diff -Nur mephisto-0.7.3/CHANGELOG technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/CHANGELOG --- mephisto-0.7.3/CHANGELOG 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/CHANGELOG 2008-03-31 02:18:56.000000000 -0400 @@ -1,5 +1,149 @@ +* SVN * + +* Experimental comment preview. [court3nay] + +* Add multi-site admin interface. [Vincent, j2m] + +* Update Wordpress converter to support Wordpress 2.3+. [Aubrey] + +* refactor so that admin/comments is more restful, allow inline comment editing in the admin. [court3nay] + +* convert to cookie sessions. + +* Fix some failing test issues and git => svn sync errors. [Aubrey, octopod] + +* Fix issue where duplicate permalinks are allowed. + +* Fix admin/users issue where site admins could disable mephisto admins. + +* Fix nil.accept_comments? bug in CommentForm block. + +* allow the various link_to filters to accept multiple args to specify more html attributes. [rob-twf] + + # use this order: :text, :title, :id, :class, :rel + link_to_article article, "click here", "this article", "article-1", "articles", "whatever-rel-means" + +* encode search/tag urls properly. [rob-twf] + +* update article forms to explain new tag syntax (comma and space delimited tags) [xavier, rick] + +* start converting tests to rspec. + +* tweak mephisto_init to support the new ActionController::Dispatcher class. [Rob Anderton] + +* Don't generate an article event for unversioned changes. [Marcus Brito] + +* Switch to will_paginate plugin. [Mislav] + +* unit test fixes for those not using mysql or psql. [Mislav] + +* add comment moderation links to the overview. [court3nay] + +* convert tests to use test/spec instead of simply bdd. [Chris McGrath] + +* move xmlrpc stuff to plugin. rails doesn't include AWS anymore. May need some simple autodetection so the plugin just prints a warning if AWS isn't found. + +* turn off session for mephisto controller. sorry, caused way too many problems. + +* fix url_for calls with symbolized controllers/actions. + +* Fix controllers so include_into works with them. + +* Change plugin class/module to Mephisto::Plugin and Mephisto::Plugins. Sorry for the breakage (still technically experimental!). + +* Fix admin overview date timezone. [Ben Wyrosdick] + +* Extract template rendering code to separate handler class, add support for alternate template handlers. [Pascal Belloncle] + +* Add {{ article.next }} and {{ article | next: section }} for paginating articles [Pascal Belloncle] + +* [converters] initial movable type support [sd] + +* [converters] use no filter for wordpress articles + +* Small bug fixes + - show correct asset thumbnail url + - assert with correct named asset resource route + - add missing fixtures for About Section Feed Test + - update asset labeling tests to reflect current behavior + +* RESTRICT hyphens as a possible separator for permalink styles. [Chris Wanstrath] + +* Initial article/asset assignment support. Perfect for podcasting. + +* Raise MissingThemesError if Site#theme is nil + +* RIP: Site#search_layout + +* Add link_to_search_result filter that uses either a paged or blog permalink, depending on the search section. + +* Allow search page to take ?s parameter to specify section path. + + * nil (default) - all sections + * '' (empty string) - home section + * 'foo/bar' - given section + +* Initial Plugin Whammy Jammy [Nick Faiz, Rick Olson] + +* link_to_section adds class='selected' for the current section [Tammo Freese] + +* Process article permalinks with Iconv. + +* Support rel-tag microformat by default in liquid filters + +* Make ImageScience the default image processor for assets. + If you wish to configure this, set ASSET_IMAGE_PROCESSOR to one of 3 values in environment.rb + + ASSET_IMAGE_PROCESSOR = :image_science || :rmagick || :none + +* paged section feeds will show the paged url for articles instead of the long permalink. + +* Replace a couple @article.full_permalink instances with @site.permalink_for(@article) [defunkt] + +# Allow Resource#non_image_extnames to be overridden by plugins [myles_b] + +* filter password fields in logs [chrissturm] + +* add *.ico to list of approved extensions for theme resources [myles_b] + +* Link comments to the currently logged in user, requires latest edge/1.2 rails [Josh Susser] + +* Convert typo filters and permalinks to mephisto [Josh Susser] + +* replace acts_as_attachment with attachment_fu plugin + +* add tags to atom feed [evilchelu] + +* flexible theme names in routes [evilchelu] + +* update liquid plugin + +* use default test.host domain where possible [courtenay] + +* fix test ensuring that comments, not articles are sanitized for script tags [courtenay] + +* fix articles form for latest rails 1.2 changes to date helpers [courtenay] + +* fix test that breaks in multi-site mode [courtenay] + +* Allow Modules to use #include_into to dynamically mixin to loaded classes (plugin stuff) + +* Allow custom routes. + + Mephisto::Routing.connect_with map do + map.foo ... + end + +* fix that only published articles are available as section pages. + +Add sorting for liquid for statements. + + {% for page in section.pages limit: 3 sort_by: title %} + * 0.7.3 * +* Fix duplicate tag bug. + * add Mephisto.root javascript variable in case a mephisto site sets the relative_url_root * don't sanitize custom anchor text for liquid filters [Jonathan Leighton] @@ -52,7 +196,9 @@ * Remove any notion of a template hierarchy, and the page template itself. Paged sections now default to the 'single' template. * Added {{ mode }} so you can check what 'view' you're in. - + + {% unless mode == 'single' %} Read more {% endunless %} + * Ensure templates are sorted by name [Brian Chapados] * Fix bug that was caching redirected routes. @@ -290,4 +436,4 @@ {% endif %} {% endfor %} -* Fix issue where Articles don't allow comments with comment_age = 0 [Rick] \ No newline at end of file +* Fix issue where Articles don't allow comments with comment_age = 0 [Rick] diff -Nur mephisto-0.7.3/LICENSE technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/LICENSE --- mephisto-0.7.3/LICENSE 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/LICENSE 2008-03-31 02:18:56.000000000 -0400 @@ -1,4 +1,4 @@ -Copyright (c) 2005 Rick Olson +Copyright (c) 2005-2008 Rick Olson Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the @@ -17,4 +17,4 @@ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff -Nur mephisto-0.7.3/README technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/README --- mephisto-0.7.3/README 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/README 2008-03-31 02:18:56.000000000 -0400 @@ -5,7 +5,7 @@ = Timezones You MUST export the environment variable TZ=UTC, or else the article dates -and times will be fubar. +and times will be invalid. This would not be needed if rails used UTC for everything, but unfortunately it doesn't... eg: action_view/helpers/date_helper.rb uses @@ -19,4 +19,4 @@ = License Mephisto is distributed under the same license as Ruby on Rails. See -http://www.opensource.org/licenses/mit-license.php \ No newline at end of file +http://www.opensource.org/licenses/mit-license.php diff -Nur mephisto-0.7.3/app/apis/meta_weblog_api.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/apis/meta_weblog_api.rb --- mephisto-0.7.3/app/apis/meta_weblog_api.rb 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/apis/meta_weblog_api.rb 1969-12-31 19:00:00.000000000 -0500 @@ -1,31 +0,0 @@ -class MetaWeblogApi < ActionWebService::API::Base - inflect_names false - - api_method :getCategories, - :expects => [ {:blogid => :string}, {:username => :string}, {:password => :string} ], - :returns => [[:string]] - - api_method :getPost, - :expects => [ {:postid => :string}, {:username => :string}, {:password => :string} ], - :returns => [MetaWeblogStructs::Article] - - api_method :getRecentPosts, - :expects => [ {:blogid => :string}, {:username => :string}, {:password => :string}, {:numberOfPosts => :int} ], - :returns => [[MetaWeblogStructs::Article]] - - api_method :deletePost, - :expects => [ {:appkey => :string}, {:postid => :string}, {:username => :string}, {:password => :string}, {:publish => :int} ], - :returns => [:bool] - - api_method :editPost, - :expects => [ {:postid => :string}, {:username => :string}, {:password => :string}, {:struct => MetaWeblogStructs::Article}, {:publish => :int} ], - :returns => [:bool] - - api_method :newPost, - :expects => [ {:blogid => :string}, {:username => :string}, {:password => :string}, {:struct => MetaWeblogStructs::Article}, {:publish => :int} ], - :returns => [:string] - - api_method :newMediaObject, - :expects => [ {:blogid => :string}, {:username => :string}, {:password => :string}, {:data => MetaWeblogStructs::MediaObject} ], - :returns => [MetaWeblogStructs::Url] -end \ No newline at end of file diff -Nur mephisto-0.7.3/app/apis/meta_weblog_service.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/apis/meta_weblog_service.rb --- mephisto-0.7.3/app/apis/meta_weblog_service.rb 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/apis/meta_weblog_service.rb 1969-12-31 19:00:00.000000000 -0500 @@ -1,91 +0,0 @@ -class MetaWeblogService < XmlRpcService - web_service_api MetaWeblogApi - before_invocation :authenticate - - def getCategories(blogid, username, password) - site.sections.find(:all, :order => 'id ASC').collect &:name - end - - def getPost(postid, username, password) - article = @user.articles.find(postid) - article_dto_from(article) - end - - def getRecentPosts(blogid, username, password, numberOfPosts) - @user.articles.find(:all, :order => "created_at DESC", :limit => numberOfPosts).collect{ |c| article_dto_from(c) } - end - - def newPost(blogid, username, password, struct, publish) - article = @user.articles.build :site => site - post_it(article, username, password, struct, publish) - end - - def editPost(postid, username, password, struct, publish) - article = @user.articles.find(postid) - post_it(article, username, password, struct, publish) - true - end - - def deletePost(appkey, postid, username, password, publish) - article = @user.articles.find(postid) - article.destroy - true - end - - def newMediaObject(blogid, username, password, data) - asset = site.assets.create!( - :filename => data['name'], - :content_type => (data['type'] || guess_content_type_from(data['name'])), - :attachment_data => data['bits'] - ) - MetaWeblogStructs::Url.new("url" => asset.public_filename) - end - - def article_dto_from(article) - MetaWeblogStructs::Article.new( - :description => article.body, - :title => article.title, - :postid => article.id.to_s, - :url => article_url(article).to_s, - :link => article_url(article).to_s, - :permaLink => article.permalink.to_s, - :categories => article.sections.collect { |c| c.name }, - :mt_text_more => article.body.to_s, - :mt_excerpt => article.excerpt.to_s, - :mt_keywords => article.tag, - # :mt_allow_comments => article.allow_comments? ? 1 : 0, - # :mt_allow_pings => article.allow_pings? ? 1 : 0, - # :mt_convert_breaks => (article.text_filter.name.to_s rescue ''), - # :mt_tb_ping_urls => article.pings.collect { |p| p.url }, - :dateCreated => (article.published_at rescue "") - ) - end - - protected - def article_url(article) - article.published? && article.full_permalink - end - - def post_it(article, user, password, struct, publish) - # make sure publish is true if it's 1 if not leave it the way it is. - publish = publish == 1 || publish - # if no categories are supplied do not attempt to set any. - article.section_ids = Section.find(:all, :conditions => ['name IN (?)', struct['categories']]).collect(&:id) if struct['categories'] - article.attributes = {:updater => @user, :body => struct['description'].to_s, :title => struct['title'].to_s, :excerpt => struct['mt_excerpt'].to_s} - # Keywords/Tags support - Tagging.set_on article, struct['mt_keywords'] if struct['mt_keywords'] # set/modify keywords _only_ if they are supplied. mt_keywords _overwrite_ not alter the ``tags'' - - utc_date = Time.utc(struct['dateCreated'].year, struct['dateCreated'].month, struct['dateCreated'].day, struct['dateCreated'].hour, struct['dateCreated'].sec, struct['dateCreated'].min) rescue article.published_at || Time.now.utc - article.published_at = publish == true ? utc_date : nil - article.save! - article.id - end - - def guess_content_type_from(name) - if name =~ /(png|gif|jpe?g)/i - "image/#{$1 == 'jpg' ? 'jpeg' : $1}" - else - 'application/octet-stream' - end - end -end diff -Nur mephisto-0.7.3/app/apis/meta_weblog_structs/article.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/apis/meta_weblog_structs/article.rb --- mephisto-0.7.3/app/apis/meta_weblog_structs/article.rb 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/apis/meta_weblog_structs/article.rb 1969-12-31 19:00:00.000000000 -0500 @@ -1,19 +0,0 @@ -module MetaWeblogStructs - class Article < ActionWebService::Struct - member :description, :string - member :title, :string - member :postid, :string - member :url, :string - member :link, :string - member :permaLink, :string - member :categories, [:string] - member :mt_text_more, :string - member :mt_excerpt, :string - member :mt_keywords, :string - member :mt_allow_comments, :int - member :mt_allow_pings, :int - member :mt_convert_breaks, :string - member :mt_tb_ping_urls, [:string] - member :dateCreated, :time - end -end \ No newline at end of file diff -Nur mephisto-0.7.3/app/apis/meta_weblog_structs/media_object.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/apis/meta_weblog_structs/media_object.rb --- mephisto-0.7.3/app/apis/meta_weblog_structs/media_object.rb 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/apis/meta_weblog_structs/media_object.rb 1969-12-31 19:00:00.000000000 -0500 @@ -1,7 +0,0 @@ -module MetaWeblogStructs - class MediaObject < ActionWebService::Struct - member :bits, :string - member :name, :string - member :type, :string - end -end \ No newline at end of file diff -Nur mephisto-0.7.3/app/apis/meta_weblog_structs/url.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/apis/meta_weblog_structs/url.rb --- mephisto-0.7.3/app/apis/meta_weblog_structs/url.rb 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/apis/meta_weblog_structs/url.rb 1969-12-31 19:00:00.000000000 -0500 @@ -1,5 +0,0 @@ -module MetaWeblogStructs - class Url < ActionWebService::Struct - member :url, :string - end -end \ No newline at end of file diff -Nur mephisto-0.7.3/app/apis/movable_type_api.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/apis/movable_type_api.rb --- mephisto-0.7.3/app/apis/movable_type_api.rb 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/apis/movable_type_api.rb 1969-12-31 19:00:00.000000000 -0500 @@ -1,88 +0,0 @@ -class MovableTypeApi < ActionWebService::API::Base - inflect_names false - - # Movable Type Programatic interface - # see: - # supportedTextFilters has already been there! - # - Moritz Angermann - # - # mt.getRecentPostTitles - # Description: Returns a bandwidth-friendly list of the most recent posts in the system. - # Parameters: String blogid, String username, String password, int numberOfPosts - # Return value: on success, array of structs containing ISO.8601 dateCreated, String userid, String postid, String title; on failure, fault - # Notes: dateCreated is in the timezone of the weblog blogid - # Reference: - - #api_method :getRecentPostTitles, - # :expects => [ {:blogid => :string}, {:username => :string}, {:password => :string}, {:numberOfPosts => :int} ], - # :returns => [[MovableTypeStructs::Post]] - - # mt.getCategoryList - # Description: Returns a list of all categories defined in the weblog. - # Parameters: String blogid, String username, String password - # Return value: on success, an array of structs containing String categoryId and String categoryName; on failure, fault. - # Reference: - api_method :getCategoryList, - :expects => [ {:blogid => :string}, {:username => :string}, {:password => :string} ], - :returns => [[MovableTypeStructs::Category]] - - # mt.getPostCategories - # Description: Returns a list of all categories to which the post is assigned. - # Parameters: String postid, String username, String password - # Return value: on success, an array of structs containing String categoryName, String categoryId, and boolean isPrimary; on failure, fault. - # Notes: isPrimary denotes whether a category is the post's primary category. - # Reference: - api_method :getPostCategories, - :expects => [ {:postid => :string}, {:username => :string}, {:password => :string} ], - :returns => [[MovableTypeStructs::Category]] - - # mt.setPostCategories - # Description: Sets the categories for a post. - # Parameters: String postid, String username, String password, array categories - # Return value: on success, boolean true value; on failure, fault - # Notes: the array categories is an array of structs containing String categoryId and boolean isPrimary. Using isPrimary to set the primary category is optional--in the absence of this flag, the first struct in the array will be assigned the primary category for the post. - # Reference: - api_method :setPostCategories, - :expects => [ {:postid => :string}, {:username => :string}, {:password => :string}, {:categories => [MovableTypeStructs::PostCategory]} ], - :returns => [:bool] - - # mt.supportedMethods - # Description: Retrieve information about the XML-RPC methods supported by the server. - # Parameters: none - # Return value: an array of method names supported by the server. - # Reference: - - api_method :supportedMethods, - :expects => [], - :returns => [[:string]] - - # mt.supportedTextFilters - # Description: Retrieve information about the text formatting plugins supported by the server. - # Parameters: none - # Return value: an array of structs containing String key and String label. key is the unique string identifying a text formatting plugin, and label is the readable description to be displayed to a user. key is the value that should be passed in the mt_convert_breaks parameter to newPost and editPost. - # Reference: - - api_method :supportedTextFilters, - :expects => [], - :returns => [[MovableTypeStructs::TextFilter]] - - # mt.getTrackbackPings - # Description: Retrieve the list of TrackBack pings posted to a particular entry. This could be used to programmatically retrieve the list of pings for a particular entry, then iterate through each of those pings doing the same, until one has built up a graph of the web of entries referencing one another on a particular topic. - # Parameters: String postid - # Return value: an array of structs containing String pingTitle (the title of the entry sent in the ping), String pingURL (the URL of the entry), and String pingIP (the IP address of the host that sent the ping). - # Reference: - - # api_method :getTrackbackPings, - # :expects => [ {:postid => :string} ], - # :returns => [[MovableTypeStructs::Trackback]] - - # mt.publishPost - # Description: Publish (rebuild) all of the static files related to an entry from your weblog. Equivalent to saving an entry in the system (but without the ping). - # Parameters: String postid, String username, String password - # Returns value: on success, boolean true value; on failure, fault - # Reference: - - #api_method :publishPost, - # :expects => [ {:postid => :string}, {:username => :string}, {:password => :string} ], - # :returns => [:bool] -end diff -Nur mephisto-0.7.3/app/apis/movable_type_service.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/apis/movable_type_service.rb --- mephisto-0.7.3/app/apis/movable_type_service.rb 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/apis/movable_type_service.rb 1969-12-31 19:00:00.000000000 -0500 @@ -1,44 +0,0 @@ -class MovableTypeService < XmlRpcService - web_service_api MovableTypeApi - before_invocation :authenticate, :except => [:supportedMethods, :supportedTextFilters] - - #def getRecentPostTitles(blogid, username, password, numberOfPosts) - # # FIXME not implemented - #end - - def getCategoryList(blogid, username, password) - site.sections.find(:all, :order => 'id ASC').collect { |c| MovableTypeStructs::Category.new(:categoryId => c.id, :categoryName => c.name) } - end - - def getPostCategories(postid, username, password) - article = @user.articles.find(postid) - article.sections.collect { |c| MovableTypeStructs::Category.new(:categoryId => c.id, :categoryName => c.name) } - end - - def setPostCategories(postid, username, password, categories) - article = @user.articles.find(postid) - article.section_ids= categories.collect { |c| c.categoryId } - article.save! - true - end - - def supportedMethods - MetaWeblogService.public_instance_methods(false).collect { |m| "metaWeblog.{#m}" } \ - + MovableTypeService.public_instance_methods(false).collect { |m| "mt.{#m}" } - end - - def supportedTextFilters - FilteredColumn.filters.collect { |(key, filter)| MovableTypeStructs::TextFilter.new(:key => key, :label => filter.filter_name) } - end - - # def getTrackbackPings, - # ... - # end - - #def publishPost(postid, username, password) - # article = @user.articles.find(postid) - # #article. hmmm now what? - # true - #end - -end diff -Nur mephisto-0.7.3/app/apis/movable_type_structs/category.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/apis/movable_type_structs/category.rb --- mephisto-0.7.3/app/apis/movable_type_structs/category.rb 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/apis/movable_type_structs/category.rb 1969-12-31 19:00:00.000000000 -0500 @@ -1,12 +0,0 @@ -module MovableTypeStructs - class Category < ActionWebService::Struct - member :categoryId, :string - member :categoryName, :string - end -end -module MovableTypeStructs - class Category < ActionWebService::Struct - member :categoryId, :string - member :categoryName, :string - end -end diff -Nur mephisto-0.7.3/app/apis/movable_type_structs/post.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/apis/movable_type_structs/post.rb --- mephisto-0.7.3/app/apis/movable_type_structs/post.rb 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/apis/movable_type_structs/post.rb 1969-12-31 19:00:00.000000000 -0500 @@ -1,16 +0,0 @@ -module MovableTypeStructs - class Post < ActionWebService::Struct - member :dateCreated, :time #ISO.8601 - member :userid, :string - member :postid, :string - member :title, :string - end -end -module MovableTypeStructs - class Post < ActionWebService::Struct - member :dateCreated, :time #ISO.8601 - member :userid, :string - member :postid, :string - member :title, :string - end -end diff -Nur mephisto-0.7.3/app/apis/movable_type_structs/post_category.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/apis/movable_type_structs/post_category.rb --- mephisto-0.7.3/app/apis/movable_type_structs/post_category.rb 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/apis/movable_type_structs/post_category.rb 1969-12-31 19:00:00.000000000 -0500 @@ -1,14 +0,0 @@ -module MovableTypeStructs - class PostCategory < ActionWebService::Struct - member :categoryId, :string - member :categoryName, :string - member :isPrimary, :bool - end -end -module MovableTypeStructs - class PostCategory < ActionWebService::Struct - member :categoryId, :string - member :categoryName, :string - member :isPrimary, :bool - end -end diff -Nur mephisto-0.7.3/app/apis/movable_type_structs/text_filter.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/apis/movable_type_structs/text_filter.rb --- mephisto-0.7.3/app/apis/movable_type_structs/text_filter.rb 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/apis/movable_type_structs/text_filter.rb 1969-12-31 19:00:00.000000000 -0500 @@ -1,6 +0,0 @@ -module MovableTypeStructs - class TextFilter < ActionWebService::Struct - member :key, :string - member :label, :string - end -end \ No newline at end of file diff -Nur mephisto-0.7.3/app/apis/movable_type_structs/trackback.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/apis/movable_type_structs/trackback.rb --- mephisto-0.7.3/app/apis/movable_type_structs/trackback.rb 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/apis/movable_type_structs/trackback.rb 1969-12-31 19:00:00.000000000 -0500 @@ -1,7 +0,0 @@ -module MovableTypeStructs - class Trackback < ActionWebService::Struct - member :pingTitle, :string - member :pingURL, :string - member :pingIP, :string - end -end \ No newline at end of file diff -Nur mephisto-0.7.3/app/apis/xml_rpc_service.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/apis/xml_rpc_service.rb --- mephisto-0.7.3/app/apis/xml_rpc_service.rb 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/apis/xml_rpc_service.rb 1969-12-31 19:00:00.000000000 -0500 @@ -1,30 +0,0 @@ -class XmlRpcService < ActionWebService::Base - attr_accessor :controller - delegate :site, :to => :controller - - def initialize(controller) - @controller = controller - end - - protected - def server_url - controller.url_for(:only_path => false, :controller => "/") - end - - def pub_date(time) - time.strftime "%a, %e %b %Y %H:%M:%S %Z" - end - - def authenticate(name, args) - method = self.class.web_service_api.api_methods[name] - - # Coping with backwards incompatibility change in AWS releases post 0.6.2 - begin - h = method.expects_to_hash(args) - raise "Invalid login" unless @user = User.authenticate_for(controller.site, h[:username], h[:password]) - rescue NoMethodError - username, password = method[:expects].index(:username=>String), method[:expects].index(:password=>String) - raise "Invalid login" unless @user = User.authenticate_for(controller.site, args[username], args[password]) - end - end -end \ No newline at end of file diff -Nur mephisto-0.7.3/app/cachers/article_observer.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/cachers/article_observer.rb --- mephisto-0.7.3/app/cachers/article_observer.rb 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/cachers/article_observer.rb 2008-03-31 02:18:56.000000000 -0400 @@ -1,10 +1,12 @@ class ArticleObserver < ActiveRecord::Observer def before_save(record) - @event = Event.new - @event.mode = case - when record.is_a?(Comment) then 'comment' - when record.new_record? then 'publish' - else 'edit' + if (record.is_a?(Article) && record.save_version?) || record.is_a?(Comment) + @event = Event.new + @event.mode = case + when record.is_a?(Comment) then 'comment' + when record.new_record? then 'publish' + else 'edit' + end end end @@ -15,4 +17,4 @@ end alias after_destroy after_save -end \ No newline at end of file +end diff -Nur mephisto-0.7.3/app/cachers/comment_observer.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/cachers/comment_observer.rb --- mephisto-0.7.3/app/cachers/comment_observer.rb 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/cachers/comment_observer.rb 2008-03-31 02:18:56.000000000 -0400 @@ -1,8 +1,15 @@ class CommentObserver < ArticleObserver - cattr_accessor :disabled + def self.disabled? + Thread.current[:comment_observer_disabled] + end + + def disabled=(value) + Thread.current[:comment_observer_disabled] = value + end + def after_save(record) @event.update_attributes :title => record.article.title, :body => record.body, :site => record.article.site, - :article => record.article, :author => record.author, :comment => record if record.approved? && !disabled + :article => record.article, :author => record.author, :comment => record if record.approved? && !self.class.disabled? end def after_destroy(record) diff -Nur mephisto-0.7.3/app/controllers/admin/articles_controller.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/controllers/admin/articles_controller.rb --- mephisto-0.7.3/app/controllers/admin/articles_controller.rb 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/controllers/admin/articles_controller.rb 2008-03-31 02:18:56.000000000 -0400 @@ -3,21 +3,18 @@ with_options :only => [:create, :update, :destroy, :upload] do |c| c.before_filter :set_default_section_ids c.cache_sweeper :article_sweeper, :assigned_section_sweeper - cache_sweeper :comment_sweeper, :only => [:approve, :unapprove, :destroy_comment] end before_filter :convert_times_to_utc, :only => [:create, :update, :upload] before_filter :check_for_new_draft, :only => [:create, :update, :upload] - before_filter :find_site_article, :only => [:edit, :update, :comments, :approve, :unapprove, :destroy] + before_filter :find_site_article, :only => [:edit, :update, :comments, :approve, :unapprove, :destroy, :attach, :detach] before_filter :login_required, :except => :upload before_filter :load_sections, :only => [:new, :edit] def index - @article_pages = Paginator.new self, site.articles.count(:all, article_options), 30, params[:page] - @articles = site.articles.find(:all, article_options(:order => 'contents.published_at DESC', :select => 'contents.*', - :limit => @article_pages.items_per_page, - :offset => @article_pages.current.offset)) + @articles = site.articles.paginate(article_options(:order => 'contents.published_at DESC', :select => 'contents.*', + :page => params[:page], :per_page => params[:per_page])) @comments = @site.unapproved_comments.count :all, :group => :article, :order => '1 desc' @sections = site.sections.find(:all) @@ -29,7 +26,7 @@ Mephisto::Liquid::CommentForm.article = @article @article = @article.to_liquid(:mode => :single) - render :text => site.render_liquid_for(site.sections.home, :single, 'articles' => [@article], 'article' => @article, 'comments' => @comments, 'site' => site.to_liquid) + render :text => site.call_render(site.sections.home, :single, 'articles' => [@article], 'article' => @article, 'comments' => @comments, 'site' => site.to_liquid) end def new @@ -65,38 +62,14 @@ def destroy @article.destroy + flash[:notice] = "The article: #{@article.title.inspect} was deleted." render :update do |page| page.redirect_to :action => 'index' end end def comments - @comments = - case params[:filter] - when 'approved' then :comments - when 'unapproved' then :unapproved_comments - else :all_comments - end - @comments = @article.send @comments - @articles = @site.unapproved_comments.count :all, :group => :article, :order => '1 desc' - end - - # xhr baby - # needs some restful lovin' - def approve - @comment = @article.unapproved_comments.approve(params[:comment]) - @comment.mark_as_ham(site, request) - end - - def unapprove - @comment = @article.comments.unapprove(params[:comment]) - @comment.mark_as_spam(site, request) - render :action => 'approve' - end - - def destroy_comment - @comments = site.all_comments.find :all, :conditions => ['id in (?)', [params[:comment]].flatten] rescue [] - Comment.transaction { @comments.each(&:destroy) } if @comments.any? + redirect_to article_comments_path(@article) end def upload @@ -117,9 +90,28 @@ end end + def attach + @asset = site.assets.find(params[:version]) + @article.assets.add @asset + end + + def detach + @asset = site.assets.find(params[:version]) + @article.assets.remove @asset + end + + def label + AssignedAsset.update_all ['label = ?', params[:label]], ['article_id = ? and asset_id = ?', params[:id], params[:version]] + end + protected def load_sections - @assets = site.assets.find(:all, :order => 'created_at desc', :limit => 6) + @assets = site.assets.find(:all, :limit => 15) + @bucket_assets = [] + session[:bucket].each do |id, values| + (@bucket_assets ||= []) << site.assets.find(id) + end unless session[:bucket].blank? + @sections = site.sections.find(:all) home = @sections.find &:home? @sections.delete home diff -Nur mephisto-0.7.3/app/controllers/admin/assets_controller.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/controllers/admin/assets_controller.rb --- mephisto-0.7.3/app/controllers/admin/assets_controller.rb 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/controllers/admin/assets_controller.rb 2008-03-31 02:18:56.000000000 -0400 @@ -29,8 +29,14 @@ end Asset.transaction { @assets.each &:save! } flash[:notice] = @assets.size == 1 ? "'#{CGI.escapeHTML @assets.first.title}' was uploaded." : "#{@assets.size} assets were uploaded." - @assets.size.zero? ? render(:action => 'new') : redirect_to(assets_path) - rescue ActiveRecord::RecordInvalid + if @assets.size.zero? + @asset = Asset.new + render :action => 'new' + else + redirect_to assets_path + end + rescue ActiveRecord::RecordInvalid => e + @asset = e.record render :action => 'new' end @@ -45,7 +51,7 @@ def latest @assets = site.assets.find(:all, :order => 'created_at desc', :limit => 6) render :update do |page| - page['latest-assets'].replace_html :partial => 'widget', :collection => @assets + page['latest-assets'].replace_html :partial => 'widget', :collection => @assets, :locals => { :prefix => 'latest' } end end @@ -53,7 +59,7 @@ search_assets 6 render :update do |page| page['spinner'].hide - return page['search-assets'].replace_html(:partial => 'widget', :collection => @assets) if @assets.any? + return page['search-assets'].replace_html(:partial => 'widget', :collection => @assets, :locals => { :prefix => 'search' }) if @assets.any? page['search-assets'].replace_html %(Couldn't find any matching assets.) end end @@ -67,11 +73,11 @@ # rjs def add_bucket - if (session[:bucket] ||= {}).key?(@asset.public_filename) + if (session[:bucket] ||= {}).key?(@asset.id) render :nothing => true and return end args = asset_image_args_for(@asset, :tiny, :title => "#{@asset.title} \n #{@asset.tags.join(', ')}") - session[:bucket][@asset.public_filename] = args + session[:bucket][@asset.id] = args end def clear_bucket @@ -85,14 +91,15 @@ def search_assets(limit) @types = params[:filter].blank? ? [] : params[:filter].keys - @asset_pages = Paginator.new self, count_by_conditions, limit, params[:page] + options = search_options.merge(:per_page => limit, :page => params[:page], :total_entries => count_by_conditions) + @assets = @types.any? ? - site.assets.find_all_by_content_types(@types, :all, search_options) : - site.assets.find(:all, search_options) + site.assets.paginate_by_content_types(@types, :all, options) : + site.assets.paginate(options) end def search_options - search_conditions.merge(:order => 'created_at desc', :limit => @asset_pages.items_per_page, :offset => @asset_pages.current.offset) + search_conditions.merge(:order => 'created_at desc') end def search_conditions diff -Nur mephisto-0.7.3/app/controllers/admin/cached_pages_controller.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/controllers/admin/cached_pages_controller.rb --- mephisto-0.7.3/app/controllers/admin/cached_pages_controller.rb 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/controllers/admin/cached_pages_controller.rb 2008-03-31 02:18:56.000000000 -0400 @@ -3,10 +3,9 @@ def index CachedPage.with_current_scope do - @cached_page_pages = Paginator.new self, site.cached_pages.count, 30, params[:page] - offset = (((params[:page] || 1).to_i - 1) * @cached_page_pages.items_per_page) - @cached_pages = site.cached_pages.find(:all, :order => 'updated_at', :limit => @cached_page_pages.items_per_page, :offset => offset, - :conditions => (params[:query] && ['url LIKE ?', ["#{params[:query]}%"]])) + @cached_pages = site.cached_pages.paginate(:order => 'updated_at', + :conditions => (params[:query] && ['url LIKE ?', ["#{params[:query]}%"]]), + :page => params[:page]) end end alias_method :query, :index @@ -25,4 +24,4 @@ protected alias authorized? admin? -end \ No newline at end of file +end diff -Nur mephisto-0.7.3/app/controllers/admin/comments_controller.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/controllers/admin/comments_controller.rb --- mephisto-0.7.3/app/controllers/admin/comments_controller.rb 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/controllers/admin/comments_controller.rb 2008-03-31 02:18:56.000000000 -0400 @@ -1,6 +1,75 @@ class Admin::CommentsController < Admin::BaseController + + member_actions.push(*%w(index unapproved create edit update approve unapprove destroy close )) + +private + + before_filter :find_site_article, :except => [ :close, :index, :destroy ] + before_filter :find_optional_site_article, :only => [:index, :destroy] + def find_site_article + @article = site.articles.find params[:article_id] + end + + def find_optional_site_article + @article = site.articles.find params[:article_id] unless params[:article_id].blank? + end + + cache_sweeper :comment_sweeper, :only => [:approve, :unapprove, :destroy, :create] + +public + def index - @comments = site.unapproved_comments.find(:all, :include => :article) + @comment = Comment.new + @articles = site.unapproved_comments.count :all, :group => :article, :order => '1 desc' + params[:filter] = 'unapproved' if @article.nil? + @comments = + (@article || @site).send case params[:filter] + when 'approved' then :comments + when 'unapproved' then :unapproved_comments + else :all_comments + end + end + + def unapproved + site.unapproved_comments.find(:all, :include => :article) + end + + def create + @comment = @article.comments.build(params[:comment].merge( + :user_id => session[:user], + :author_ip => request.remote_ip, + :user_agent => request.env['HTTP_USER_AGENT'], + :referrer => request.env['HTTP_REFERER']) + ) + @comment.approved = true + @comment.save + end + + def edit + @comment = @article.all_comments.find params[:id] + end + + def update + @comment = @article.all_comments.find params[:id] + @comment.update_attributes(params[:comment]) + end + + # xhr baby + # needs some restful lovin' + def approve + @comment = @article.unapproved_comments.approve(params[:comment] || params[:id]) + @comment.mark_as_ham(site, request) + end + + def unapprove + @comment = @article.comments.unapprove(params[:comment] || params[:id]) + @comment.mark_as_spam(site, request) + render :action => 'approve' + end + + def destroy + @comments = site.all_comments.find :all, :conditions => ['id in (?)', [ (params[:comment] || params[:id])].flatten] # rescue [] + Comment.transaction { @comments.each(&:destroy) } if @comments.any? end # ajax action, called from _page_nav diff -Nur mephisto-0.7.3/app/controllers/admin/overview_controller.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/controllers/admin/overview_controller.rb --- mephisto-0.7.3/app/controllers/admin/overview_controller.rb 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/controllers/admin/overview_controller.rb 2008-03-31 02:18:56.000000000 -0400 @@ -9,10 +9,10 @@ def index @users = site.users(:order => 'updated_at desc') @events, @todays_events, @yesterdays_events = [], [], [] - today, yesterday = Time.now.utc.to_date, 1.day.ago.utc.to_date + today, yesterday = utc_to_local(Time.now.utc).to_date, utc_to_local(1.day.ago.utc).to_date @articles = @site.unapproved_comments.count :all, :group => :article, :order => '1 desc' @site.events.find(:all, :order => 'events.created_at DESC', :include => [:article, :user], :limit => 50).each do |event| - event_date = event.created_at.to_date + event_date = utc_to_local(event.created_at).to_date if event_date >= today @todays_events elsif event_date == yesterday diff -Nur mephisto-0.7.3/app/controllers/admin/plugins_controller.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/controllers/admin/plugins_controller.rb --- mephisto-0.7.3/app/controllers/admin/plugins_controller.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/controllers/admin/plugins_controller.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,24 @@ +class Admin::PluginsController < Admin::BaseController + before_filter :find_plugin, :except => :index + + def index + @plugins = Mephisto.plugins + end + + def update + @plugin.options = params[:options] + @plugin.save! + + redirect_to :action => "show", :id => params[:id] + end + + def destroy + @plugin.destroy + redirect_to :action => "show", :id => params[:id] + end + + protected + def find_plugin + @plugin = Mephisto.plugins[params[:id]] + end +end \ No newline at end of file diff -Nur mephisto-0.7.3/app/controllers/admin/settings_controller.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/controllers/admin/settings_controller.rb --- mephisto-0.7.3/app/controllers/admin/settings_controller.rb 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/controllers/admin/settings_controller.rb 2008-03-31 02:18:56.000000000 -0400 @@ -1,6 +1,6 @@ class Admin::SettingsController < Admin::BaseController before_filter :find_and_sort_templates - clear_empty_templates_for :site, :search_layout, :tag_layout, :only => :update + clear_empty_templates_for :site, :tag_layout, :only => :update def update if site.update_attributes params[:site] diff -Nur mephisto-0.7.3/app/controllers/admin/sites_controller.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/controllers/admin/sites_controller.rb --- mephisto-0.7.3/app/controllers/admin/sites_controller.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/controllers/admin/sites_controller.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,62 @@ +class Admin::SitesController < Admin::BaseController + + before_filter :admin_required + member_actions.push *%W(index show new destroy create) + + def index + @sites = Site.search_by_host_or_title params[:search_string] do + Site.paginate(:page => params[:page], :per_page => params[:per_page], :order => 'id') + end + end + + def show + @site = Site.find(params[:id]) + end + + def new + @site = Site.new + end + + def create + @site = Site.new(params[:site]) + if @site.save + flash[:notice] = "Site #{@site.host} was successfully created." + redirect_to :action => 'index' + else + flash[:error] = "Failed to create site." + render :action => "new" + end + end + + def update + @site = Site.find(params[:id]) + if @site.update_attributes(params[:site]) + flash[:notice] = "Site #{@site.host} was successfully updated." + redirect_to :action => 'show', :id => @site + else + render :action => 'show' + end + end + + def destroy + @site = Site.find(params[:id]) + if @site.destroy + flash[:notice] = "Site removed." + redirect_to :action => 'index' + else + flash[:error] = "Failed to remove site #{@site.host}. Check file permissions." + render :action => 'show' + end + end + + private + def admin_required + current_user.admin? ? true : not_allowed + end + + def not_allowed + flash[:error] = "Only global administrators can manage sites." + redirect_to :controller => "/account", :action => :login + end + +end diff -Nur mephisto-0.7.3/app/controllers/admin/templates_controller.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/controllers/admin/templates_controller.rb --- mephisto-0.7.3/app/controllers/admin/templates_controller.rb 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/controllers/admin/templates_controller.rb 2008-03-31 02:18:56.000000000 -0400 @@ -28,7 +28,7 @@ if !@tmpl.file? page.flash.errors "File does not exist" page.visual_effect :fade, params[:context], :duration => 0.3 - elsif @theme.templates.custom.include?(@tmpl.basename.to_s) + elsif @theme.templates.custom(@theme.extension).include?(@tmpl.basename.to_s) @tmpl.unlink page.visual_effect :fade, params[:context], :duration => 0.3 else diff -Nur mephisto-0.7.3/app/controllers/admin/users_controller.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/controllers/admin/users_controller.rb --- mephisto-0.7.3/app/controllers/admin/users_controller.rb 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/controllers/admin/users_controller.rb 2008-03-31 02:18:56.000000000 -0400 @@ -34,19 +34,20 @@ end def destroy - @user.deleted_at = Time.now.utc - @user.save! + if @user == current_user then return @error = "Cannot delete yourself." end + if @user.admin? then return @error = "Cannot delete a Mephisto administrator." end + @allowed = @user.update_attribute :deleted_at, Time.now.utc end def enable - @user.deleted_at = nil - @user.save! + @allowed = @user.update_attribute :deleted_at, nil end def admin + if @user == current_user then return @error = "Cannot toggle admin permissions for yourself." end + if @user.admin? then return @error = "Cannot toggle admin permissions for a Mephisto administrator." end @membership = Membership.find_or_initialize_by_site_id_and_user_id(site.id, @user.id) - @membership.admin = !@membership.admin? - @membership.save! + @allowed = @membership.update_attribute :admin, !@membership.admin? end protected diff -Nur mephisto-0.7.3/app/controllers/application/errors.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/controllers/application/errors.rb --- mephisto-0.7.3/app/controllers/application/errors.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/controllers/application/errors.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,37 @@ +# Custom handlers for exceptions are defined here. +class ApplicationController + + protected + + # Handle public-facing errors by rendering the "error" liquid template + def show_404 + show_error 'Page Not Found', :not_found + end + + def show_error(message = 'An error occurred.', status = :internal_server_error) + render_liquid_template_for(:error, 'message' => message, :status => status) + end + + # Handle admin-application errors + # TODO: after rails 2.0.2, convert these to rescue_from [array] rather than 3 lines. + rescue_from ActiveRecord::RecordNotFound, :with => :render_admin_not_found + rescue_from ActionController::UnknownController, :with => :render_admin_not_found + rescue_from ActionController::UnknownAction, :with => :render_admin_not_found + + def render_admin_not_found + # TODO: render this from the site's custom admin 404 file, if it's a multi-site install. + render :file => File.join(RAILS_ROOT, 'public/404.html'), :status => :not_found + end + + def render_admin_error + # TODO: render this from the site's custom 500 file, if it's a multi-site install + render :file => File.join(RAILS_ROOT, 'public/500.html'), :status => :internal_server_error + end + + def rescue_action_in_public(exception) + logger.debug "#{exception.class.name}: #{exception.to_s}" + exception.backtrace.each { |t| logger.debug " > #{t}" } + render_admin_error + end + +end \ No newline at end of file diff -Nur mephisto-0.7.3/app/controllers/application.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/controllers/application.rb --- mephisto-0.7.3/app/controllers/application.rb 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/controllers/application.rb 2008-03-31 02:18:56.000000000 -0400 @@ -1,20 +1,36 @@ class ApplicationController < ActionController::Base + require_dependency 'application/errors' + include Mephisto::CachingMethods - cattr_accessor :site_count before_filter :set_cache_root helper_method :site attr_reader :site + + auto_include! + + def self.inherited(klass) + super + klass.auto_include! + end + + filter_parameter_logging "password" protected helper_method :admin? + helper_method :global_admin? def admin? logged_in? && (current_user.admin? || current_user.site_admin?) end + def global_admin? + logged_in? && current_user.admin? + end + # so not the best place for this... def asset_image_args_for(asset, thumbnail = :tiny, options = {}) - options = options.reverse_merge(:title => "#{asset.title} \n #{asset.tags.join(', ')}") + thumb_size = Array.new(2).fill(Asset.attachment_options[:thumbnails][thumbnail].to_i).join('x') + options = options.reverse_merge(:title => "#{asset.title} \n #{asset.tags.join(', ')}", :size => thumb_size) if asset.movie? ['/images/mephisto/icons/video.png', options] elsif asset.audio? @@ -24,7 +40,7 @@ elsif asset.other? ['/images/mephisto/icons/doc.png', options] elsif asset.thumbnails_count.zero? - [asset.public_filename, options.update(:size => Array.new(2).fill(Asset.attachment_options[:thumbnails][thumbnail].to_i).join('x'))] + [asset.public_filename, options] else [asset.public_filename(thumbnail), options] end @@ -44,22 +60,14 @@ # use collect so it doesn't modify @articles assigns['articles'] = assigns['articles'].collect &:to_liquid end - status = (assigns.delete(:status) || '200 OK') + status = (assigns.delete(:status) || :ok) @liquid_assigns = assigns - render :text => site.render_liquid_for(@section, template_type, assigns, self), :status => status - end - - def show_error(message = 'An error occurred.', status = '500 Error') - render_liquid_template_for(:error, 'message' => message, :status => status) - end - - def show_404 - show_error 'Page Not Found', '404 NotFound' + render :text => site.call_render(@section, template_type, assigns, self), :status => status end def set_cache_root host = request.domain(request.subdomains.size + (request.subdomains.first == 'www' ? 0 : 1)) - @site ||= Site.find_by_host(host) || Site.find(:first, :order => 'id') + @site ||= Site.find_by_host(host) || Site.find(:first, :order => 'id') || raise(ActiveRecord::RecordNotFound, "You need to create your first site!") self.class.page_cache_directory = site.page_cache_directory.to_s end @@ -69,15 +77,5 @@ yield ENV['TZ'] = old_tz end - - def rescue_action_in_public(exception) - logger.debug "#{exception.class.name}: #{exception.to_s}" - exception.backtrace.each { |t| logger.debug " > #{t}" } - case exception - when ActiveRecord::RecordNotFound, ::ActionController::UnknownController, ::ActionController::UnknownAction - render :file => File.join(RAILS_ROOT, 'public/404.html'), :status => '404 Not Found' - else - render :file => File.join(RAILS_ROOT, 'public/500.html'), :status => '500 Error' - end - end + end diff -Nur mephisto-0.7.3/app/controllers/backend_controller.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/controllers/backend_controller.rb --- mephisto-0.7.3/app/controllers/backend_controller.rb 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/controllers/backend_controller.rb 1969-12-31 19:00:00.000000000 -0500 @@ -1,13 +0,0 @@ -require 'meta_weblog_api' -require 'movable_type_api' -class BackendController < ApplicationController - session :off - - web_service_dispatching_mode :layered - web_service(:metaWeblog) { MetaWeblogService.new(self) } - web_service(:mt) { MovableTypeService.new(self) } - - alias xmlrpc api - - cache_sweeper :article_sweeper, :assigned_section_sweeper, :comment_sweeper -end diff -Nur mephisto-0.7.3/app/controllers/feed_controller.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/controllers/feed_controller.rb --- mephisto-0.7.3/app/controllers/feed_controller.rb 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/controllers/feed_controller.rb 2008-03-31 02:18:56.000000000 -0400 @@ -36,7 +36,6 @@ def comment_feed_for_site @comments = site.comments.find(:all, :limit => 15, :include => :article) - cached_references << @section self.cached_references += @comments self.cached_references += @comments.collect(&:article_referenced_cache_key) end diff -Nur mephisto-0.7.3/app/controllers/mephisto_controller.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/controllers/mephisto_controller.rb --- mephisto-0.7.3/app/controllers/mephisto_controller.rb 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/controllers/mephisto_controller.rb 2008-03-31 02:18:56.000000000 -0400 @@ -18,7 +18,7 @@ # @dispatch_path.first has the headers if @dispatch_path.first.is_a?(Hash) response.headers['Status'] = interpret_status @section - redirect_to @dispatch_path.first[:location] + redirect_to @dispatch_path.first[:location], :status=>301 else head @section end @@ -31,21 +31,23 @@ end def dispatch_page - @article = @dispatch_path.empty? ? @section.articles.find_by_position : @section.articles.find_by_permalink(@dispatch_path.first) + Article.with_published do + @article = @dispatch_path.empty? ? @section.articles.find_by_position : @section.articles.find_by_permalink(@dispatch_path.first) + end show_404 and return unless @article Mephisto::Liquid::CommentForm.article = @article render_liquid_template_for(:page, 'section' => @section.to_liquid(true), - 'article' => @article.to_liquid(:mode => :single)) + 'article' => @article.to_liquid(:mode => :single, :page => @dispatch_path.empty?)) end def dispatch_comments + @skip_caching = true show_404 and return unless find_article if !request.post? || params[:comment].blank? - @skip_caching = true redirect_to site.permalink_for(@article) and return end - @comment = @article.comments.build(params[:comment].merge(:author_ip => request.remote_ip, :user_agent => request.user_agent, :referrer => request.referer)) + @comment = @article.comments.build(params[:comment].merge(:user_id => session[:user], :author_ip => request.remote_ip, :user_agent => request.user_agent, :referrer => request.referer)) @comment.check_approval site, request if @comment.valid? @comment.save! redirect_to dispatch_path(:path => (site.permalink_for(@article)[1..-1].split('/') << 'comments' << @comment.id.to_s), :anchor => @comment.dom_id) @@ -53,9 +55,12 @@ show_article_with 'errors' => @comment.errors.full_messages, 'submitted' => params[:comment] rescue Article::CommentNotAllowed show_article_with 'errors' => ["Commenting has been disabled on this article"] + rescue Comment::Previewing + show_article_with 'errors' => ["Previewing your comment"], 'submitted' => params[:comment] end def dispatch_comment + @skip_caching = true show_article_with 'message' => 'Thanks for the comment!' end @@ -73,20 +78,25 @@ end def dispatch_search + @section = params[:s].nil? ? nil : site.sections.detect { |s| s.path == params[:s] } + joins = nil conditions = ['(published_at IS NOT NULL AND published_at <= :now) AND (title LIKE :q OR excerpt LIKE :q OR body LIKE :q)', { :now => Time.now.utc, :q => "%#{params[:q]}%" }] - search_count = site.articles.count(:all, :conditions => conditions) - @article_pages = Paginator.new self, search_count, site.articles_per_page, params[:page] - @articles = site.articles.find(:all, :conditions => conditions, :order => 'published_at DESC', - :include => [:user, :sections], - :limit => @article_pages.items_per_page, - :offset => @article_pages.current.offset) + if @section + conditions.first << ' AND (assigned_sections.section_id = :section)' + conditions.last[:section] = @section.id + end + + @articles = site.articles.paginate(:conditions => conditions, :order => 'published_at DESC', + :include => [:user, :sections], + :per_page => site.articles_per_page, :page => params[:page]) render_liquid_template_for(:search, 'articles' => @articles, - 'previous_page' => paged_search_url_for(@article_pages.current.previous), - 'next_page' => paged_search_url_for(@article_pages.current.next), - 'search_string' => params[:q], - 'search_count' => search_count) + 'previous_page' => paged_search_url_for(@articles.previous_page), + 'next_page' => paged_search_url_for(@articles.next_page), + 'search_string' => CGI::escapeHTML(params[:q]), + 'search_count' => @articles.total_entries, + 'section' => @section) @skip_caching = true end @@ -124,7 +134,7 @@ show_404 and return unless @article || find_article Mephisto::Liquid::CommentForm.article = @article @article = @article.to_liquid(:mode => :single) - render_liquid_template_for(:single, assigns.merge('articles' => [@article], 'article' => @article)) + render_liquid_template_for(:single, assigns.update('articles' => [@article], 'article' => @article)) end alias dispatch_single show_article_with end diff -Nur mephisto-0.7.3/app/drops/article_drop.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/drops/article_drop.rb --- mephisto-0.7.3/app/drops/article_drop.rb 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/drops/article_drop.rb 2008-03-31 02:18:56.000000000 -0400 @@ -6,12 +6,12 @@ def initialize(source, options = {}) super source - @options = options + @options = options @liquid.update \ - 'body' => @source.body_html, - 'excerpt' => (@source.excerpt_html.nil? || @source.excerpt_html.empty? ? nil : @source.excerpt_html), - 'accept_comments' => @source.accept_comments?, - 'is_page_home' => (options[:page] == true) + 'body' => @source.body_html, + 'excerpt' => (@source.excerpt_html.blank? ? nil : @source.excerpt_html), + 'accept_comments' => @source.accept_comments?, + 'is_page_home' => (options[:page] == true) end def author @@ -19,12 +19,11 @@ end def comments - @comments ||= liquify(*@source.comments.reject(&:new_record?)) + @comments ||= liquify(*@source.comments) # .reject(&:new_record?) <-- show new comments as they're built as a preview end def sections - @sections ||= @source.sections.inject([]) { |all, s| s.home? ? all : all << s.to_liquid } # your days are numbered, home section! - @sections ||= liquify(*@source.sections) { |s| s.home? ? nil : s.to_liquid } + @sections ||= liquify(*@source.sections.reject(&:home?)) end def tags @@ -44,7 +43,7 @@ end def url - @url ||= absolute_url(@site.permalink_for(@source)) + @url ||= absolute_url(@site.permalink_for(@source)[1..-1]) end def comments_feed_url @@ -54,6 +53,10 @@ def changes_feed_url @changes_feed_url ||= url + '/changes.xml' end + + def assets + @assets ||= liquify(*@source.assets) + end protected def body_for_mode(mode) diff -Nur mephisto-0.7.3/app/drops/comment_drop.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/drops/comment_drop.rb --- mephisto-0.7.3/app/drops/comment_drop.rb 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/drops/comment_drop.rb 2008-03-31 02:18:56.000000000 -0400 @@ -19,7 +19,22 @@ @url ||= absolute_url(@source.site.permalink_for(@source)) end + def new_record + @source.new_record? + end + def author_link - @source.author_url.blank? ? "#{CGI::escapeHTML(@source.author)}" : %Q{#{CGI::escapeHTML @source.author}} + @source.author_url.blank? ? "#{@source.author}" : %Q{#{@source.author}} + end + + def presentation_class + @presentation_class ||= case @source.user_id + when @source.article.user_id + "by-author" + when nil + "by-guest" + else + "by-user" + end end end \ No newline at end of file diff -Nur mephisto-0.7.3/app/filters/core_filters.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/filters/core_filters.rb --- mephisto-0.7.3/app/filters/core_filters.rb 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/filters/core_filters.rb 2008-03-31 02:18:56.000000000 -0400 @@ -56,6 +56,10 @@ def assign_to_global(value, name) @context.scopes.last[name] = value ; nil end + + def contains(source, text) + !source[text].nil? + end protected def liquify(*records, &block) diff -Nur mephisto-0.7.3/app/filters/drop_filters.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/filters/drop_filters.rb --- mephisto-0.7.3/app/filters/drop_filters.rb 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/filters/drop_filters.rb 2008-03-31 02:18:56.000000000 -0400 @@ -13,8 +13,12 @@ @context['site'].find_descendant_sections(path) end - def linked_section_list(article, seperator = ', ') - article.sections.collect {|s| link_to_section s }.join(seperator) + def linked_section_list(article, separator = ', ') + article.sections.collect {|s| link_to_section s }.join(separator) + end + + def linked_tag_list(article, separator = ', ') + article.tags.collect {|t| link_to_tag t }.join(separator) end def latest_articles(site_or_section, limit = nil) @@ -28,6 +32,22 @@ def latest_comments(site, limit = nil) site.latest_comments(limit || site['articles_per_page']) end + + def find_asset(article, label) + article.assets.detect { |a| a.source.label == label } + end + + def next_article(article, section=nil) + if nxt = article.source.next(section ? section.source : nil) + nxt.to_liquid.tap { |n| n.context = @context if n } + end + end + + def previous_article(article, section=nil) + if prev = article.source.previous(section ? section.source : nil) + prev.to_liquid.tap { |p| p.context = @context if p } + end + end def monthly_articles(section, date = nil) date = parse_date(date) @@ -38,11 +58,17 @@ liquify(*@context['site'].source.articles.find(:all, :include => :tags, :conditions => ['tags.name in (?)', Tag.parse(tags)], :order => 'contents.created_at desc')) end - def assets_by_type(type) - liquify(*@context['site'].source.assets.find_all_by_content_types([type.to_sym], :all, :order => 'created_at desc')) + def tagged_articles_in_section(tags, section) + liquify(*section.source.articles.find(:all, :include => :tags, :conditions => ['tags.name in (?)', Tag.parse(tags)], :order => 'contents.published_at desc')) + end + + def assets_by_type(type, drop = nil) + drop ||= @context['site'] + liquify(*drop.source.assets.find_all_by_content_types([type.to_sym], :all, :order => 'created_at desc')) end - def tagged_assets(tags) - liquify(*@context['site'].source.assets.find(:all, :include => :tags, :conditions => ['tags.name in (?)', Tag.parse(tags)], :order => 'assets.created_at desc')) + def tagged_assets(tags, drop = nil) + drop ||= @context['site'] + liquify(*drop.source.assets.find(:all, :include => :tags, :conditions => ['tags.name in (?)', Tag.parse(tags)], :order => 'assets.created_at desc')) end end \ No newline at end of file diff -Nur mephisto-0.7.3/app/filters/url_filters.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/filters/url_filters.rb --- mephisto-0.7.3/app/filters/url_filters.rb 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/filters/url_filters.rb 2008-03-31 02:18:56.000000000 -0400 @@ -4,26 +4,43 @@ include ActionView::Helpers::TagHelper include ActionView::Helpers::AssetTagHelper - def link_to_article(article, text = nil) - content_tag :a, text || h(article['title']), :href => article['url'] + def link_to_article(article, *args) + options = link_args_to_options(args) + text = options.delete(:text) || h(article['title']) + content_tag :a, text, { :href => article['url'], :title => text }.merge(options) end - def link_to_page(page, section = nil, text = nil) - content_tag :a, text || h(page['title']), page_anchor_options(page, section) + def link_to_page(page, section = nil, *args) + options = link_args_to_options(args) + text = options.delete(:text) || h(page['title']) + content_tag :a, text, page_anchor_options(page, section, { :title => text }.merge(options)) end - def link_to_comments(article, text = nil) - content_tag :a, text || pluralize(article['comments_count'], 'comment'), :href => article['url'] + def link_to_comments(article, *args) + options = link_args_to_options(args) + text = options.delete(:text) || pluralize(article['comments_count'], 'comment') + content_tag :a, text, { :href => article['url'] + '#comments', :title => text }.merge(options) end - def link_to_section(section, text = nil) - content_tag :a, text || h(section['name']), :href => section['url'], :title => section['title'] + def link_to_section(section, *args) + options = link_args_to_options(args) + text = options.delete(:text) || h(section['name']) + content_tag :a, text, section_anchor_options(section, { :title => text }.merge(options)) end def img_tag(img, options = {}) tag 'img', {:src => asset_url(img), :alt => img.split('.').first }.merge(options) end + # Special link that checks for current section. If it exists and it's a paged section, use link_to_page instead. + def link_to_search_result(article, *args) + if current_page_section && current_page_section[:is_paged] + link_to_page(article, current_page_section, *args) + else + link_to_article(article, *args) + end + end + def stylesheet_url(css) absolute_url :stylesheets, css end @@ -54,12 +71,16 @@ image_tag url, :class => 'gravatar', :size => "#{size}x#{size}", :alt => comment['author'] end - def link_to_tag(tag) - content_tag :a, h(tag), :href => tag_url(tag) + def link_to_tag(tag, *args) + options = link_args_to_options(args) + text = options.delete(:text) || h(tag) + content_tag :a, text, { :href => tag_url(tag), :rel => 'tag', :title => text }.merge(options) end - def link_to_month(section, date = nil, format = 'my') - content_tag :a, format_date(date, format), :href => monthly_url(section, date) + def link_to_month(section, date = nil, format = 'my', *args) + options = link_args_to_options(args) + text = options.delete(:text) || h(format_date(date, format)) + content_tag :a, text, { :href => monthly_url(section, date), :title => text }.merge(options) end def monthly_url(section, date = nil) @@ -109,11 +130,33 @@ atom_feed '/feed/' + section.source.to_feed_url.join('/'), (title.blank? ? "Articles for #{section['name']}" : title) end + def next(article, section = nil) + article.next(section) + end + + def previous(article, section = nil) + article.previous(section) + end + private # marks a page as class=selected - def page_anchor_options(page, section = nil) - options = {:href => page_url(page, section)} - current_page_article == page ? options.update(:class => 'selected') : options + def page_anchor_options(page, section = nil, options = {}) + options.update(:href => page_url(page, section)) + options[:class].nil? ? options.update(:class => 'selected') : options[:class] += ' selected' if current_page_article == page + options + end + + # marks a section as class=selected + def section_anchor_options(section, options = {}) + options.update(:href => section['url']) + options[:class].nil? ? options.update(:class => 'selected') : options[:class] += ' selected' if current_page_section && (current_page_section.url == section.url) + options + end + + def link_args_to_options(args) + options = {} + [:text, :title, :id, :class, :rel].zip(args) {|key, value| options[key] = h(value) unless value.blank?} + options end def current_page_section @@ -123,4 +166,4 @@ def current_page_article @current_page_article ||= @context['article'] end -end \ No newline at end of file +end diff -Nur mephisto-0.7.3/app/helpers/admin/cached_pages_helper.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/helpers/admin/cached_pages_helper.rb --- mephisto-0.7.3/app/helpers/admin/cached_pages_helper.rb 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/helpers/admin/cached_pages_helper.rb 2008-03-31 02:18:56.000000000 -0400 @@ -1,14 +1,4 @@ module Admin::CachedPagesHelper - def pagination_remote_links(paginator, options={}, html_options={}) - name = options[:name] || ActionController::Pagination::DEFAULT_OPTIONS[:name] - params = (options[:params] || ActionController::Pagination::DEFAULT_OPTIONS[:params]).clone - - pagination_links_each(paginator, options) do |n| - params[name] = n - link_to n.to_s, :page => n - end - end - def display_cached_page_date(page) if Date.today == page.updated_at.to_date if page.updated_at > Time.now - 4.hours @@ -20,4 +10,4 @@ page.updated_at.strftime("%b %d, %Y") end end -end \ No newline at end of file +end diff -Nur mephisto-0.7.3/app/helpers/admin/plugins_helper.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/helpers/admin/plugins_helper.rb --- mephisto-0.7.3/app/helpers/admin/plugins_helper.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/helpers/admin/plugins_helper.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,4 @@ +module Admin + module PluginsHelper + end +end \ No newline at end of file diff -Nur mephisto-0.7.3/app/helpers/application_helper.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/helpers/application_helper.rb --- mephisto-0.7.3/app/helpers/application_helper.rb 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/helpers/application_helper.rb 2008-03-31 02:18:56.000000000 -0400 @@ -2,7 +2,7 @@ module ApplicationHelper def author_link_for(comment) - return comment.author if comment.author_url.blank? + return h(comment.author) if comment.author_url.blank? link_to h(comment.author), "#{'http://' unless comment.author_url =~ /^https?:\/\//}#{comment.author_url}" end @@ -52,16 +52,6 @@ end end - def pagination_remote_links(paginator, options={}, html_options={}) - name = options[:name] || ActionController::Pagination::DEFAULT_OPTIONS[:name] - params = (options[:params] || ActionController::Pagination::DEFAULT_OPTIONS[:params]).clone - - pagination_links_each(paginator, options) do |n| - params[name] = n - link_to_function n.to_s, "window.spotlight.search('#{n}')" - end - end - def comment_expiration_options [['Are not allowed', -1], ['Never expire', 0], diff -Nur mephisto-0.7.3/app/helpers/feed_helper.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/helpers/feed_helper.rb --- mephisto-0.7.3/app/helpers/feed_helper.rb 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/helpers/feed_helper.rb 2008-03-31 02:18:56.000000000 -0400 @@ -1,2 +1,12 @@ -module FeedHelper +module FeedHelper + # show paged url for an article if the section is a paged section + def section_url_for(article) + if @section && @section.show_paged_articles? + @section_articles ||= {} + @section_articles[@section.id] ||= (@section.articles.find(:first) || :false) + ([nil] << (@section_articles[@section.id].permalink == article.permalink ? @section.to_url : @section.to_page_url(article))).join("/") + else + site.permalink_for(article) + end + end end diff -Nur mephisto-0.7.3/app/models/article.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/models/article.rb --- mephisto-0.7.3/app/models/article.rb 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/models/article.rb 2008-03-31 02:18:56.000000000 -0400 @@ -1,12 +1,13 @@ class Article < Content class CommentNotAllowed < StandardError; end - + validates_presence_of :title, :user_id, :site_id before_validation { |record| record.set_default_filter! } after_validation :convert_to_utc - before_create :create_permalink + has_permalink :title after_save :save_assigned_sections + after_update :reset_comment_attributes acts_as_versioned :if_changed => [:title, :body, :excerpt], :limit => 5 do def self.included(base) @@ -33,7 +34,7 @@ has_many :events, :order => 'created_at desc', :dependent => :delete_all with_options :order => 'created_at', :class_name => 'Comment' do |comment| - comment.has_many :comments, :conditions => ['contents.approved = ?', true], :dependent => :delete_all do + comment.has_many :comments, :conditions => ['contents.approved = ?', true] do def unapprove(id) returning find(id) do |comment| comment.approved = false @@ -49,14 +50,33 @@ end end end - comment.has_many :all_comments + comment.has_many :all_comments, :dependent => :delete_all + end + + has_many :assigned_assets, :order => 'position', :dependent => :destroy + has_many :assets, :through => :assigned_assets, :conditions => ['assigned_assets.active = ?', true], :select => 'assets.*, assigned_assets.label' do + def add(asset, label = nil) + returning AssignedAsset.find_or_create_by_article_id_and_asset_id(proxy_owner.id, asset.id) do |aa| + aa.label = label + aa.active = true + aa.save! + end + end + + def remove(asset) + AssignedAsset.update_all ['active = ?', false], ['article_id = ? AND asset_id = ?', proxy_owner.id, asset.id] + end end class << self + def with_published(&block) + with_scope({:find => { :conditions => ['contents.published_at <= ? AND contents.published_at IS NOT NULL', Time.now.utc] } }, &block) + end + def find_by_date(options = {}) - find(:all, { :order => 'contents.published_at desc', - :conditions => ['contents.published_at <= ? AND contents.published_at IS NOT NULL', Time.now.utc] } \ - .merge(options)) + with_published do + find :all, {:order => 'contents.published_at desc'}.update(options) + end end def find_all_in_month(year, month, options = {}) @@ -70,7 +90,7 @@ end def permalink_for(str) - str.gsub(/\W+/, ' ').strip.downcase.gsub(/\ +/, '-') + PermalinkFu.escape(str) end end @@ -134,11 +154,52 @@ set_default_filter_from user end - protected - def create_permalink - self.permalink = self.class.permalink_for(title.to_s) if permalink.blank? + def add_xml(builder) + add_podcast_xml(builder) + end + + def next(section=nil) + return nil if section && !sections.include?(section) + section = sections[0] if (section.nil?) + self.class.with_published do + if section + if section.paged? + index = section.articles.index(self) + (index <= section.articles.length-1) ? section.articles[index+1] : nil + # article = section.articles.detect {|article| article.id == id } + else + site.articles.find :first, :conditions => ['published_at > ? and assigned_sections.section_id = ?', published_at, section.id], + :joins => 'inner join assigned_sections on contents.id = assigned_sections.article_id', + :order => 'published_at' + end + else + site.articles.find :first, :conditions => ['published_at > ?', published_at], :order => 'published_at' + end end + end + + def previous(section=nil) + return nil if section && !sections.include?(section) + section = sections[0] if (section.nil?) + self.class.with_published do + if section + if section.paged? + index = section.articles.index(self) + (index > 0) ? section.articles[index-1] : nil + # article = section.articles.detect {|article| article.id == id } + else + site.articles.find :first, :conditions => ['published_at < ? and assigned_sections.section_id = ?', published_at, section.id], + :joins => 'inner join assigned_sections on contents.id = assigned_sections.article_id', + :order => 'published_at desc' + end + else + site.articles.find :first, :conditions => ['published_at < ?', published_at], :order => 'published_at desc' + end + end + end + + protected def convert_to_utc self.published_at = published_at.utc if published_at end @@ -156,4 +217,14 @@ @new_sections = nil end + + def reset_comment_attributes + Content.update_all ['title = ?, published_at = ?, permalink = ?', title, published_at, permalink], ['article_id = ?', id] + end + + def add_podcast_xml(builder) + if asset = assets.find(:first, :conditions => ['label = ?', 'podcast'], :select => 'assets.*') + builder.link :rel => :enclosure, :type => asset.content_type, :length => asset.size, :href => asset.public_filename + end + end end \ No newline at end of file diff -Nur mephisto-0.7.3/app/models/asset.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/models/asset.rb --- mephisto-0.7.3/app/models/asset.rb 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/models/asset.rb 2008-03-31 02:18:56.000000000 -0400 @@ -6,10 +6,10 @@ # use #send due to a ruby 1.8.2 issue @@movie_condition = send(:sanitize_sql, ['content_type LIKE ? OR content_type IN (?)', 'video%', extra_content_types[:movie]]).freeze @@audio_condition = send(:sanitize_sql, ['content_type LIKE ? OR content_type IN (?)', 'audio%', extra_content_types[:audio]]).freeze - @@image_condition = send(:sanitize_sql, ['content_type IN (?)', Technoweenie::ActsAsAttachment.content_types]).freeze + @@image_condition = send(:sanitize_sql, ['content_type IN (?)', Technoweenie::AttachmentFu.content_types]).freeze @@other_condition = send(:sanitize_sql, [ 'content_type NOT LIKE ? AND content_type NOT LIKE ? AND content_type NOT IN (?)', - 'audio%', 'video%', (extra_content_types[:movie] + extra_content_types[:audio] + Technoweenie::ActsAsAttachment.content_types)]).freeze + 'audio%', 'video%', (extra_content_types[:movie] + extra_content_types[:audio] + Technoweenie::AttachmentFu.content_types)]).freeze cattr_reader *%w(movie audio image other).collect! { |t| "#{t}_condition".to_sym } class << self @@ -45,7 +45,9 @@ include Mephisto::TaggableMethods belongs_to :site - acts_as_attachment :storage => :file_system, :thumbnails => { :thumb => '120>', :tiny => '50>' }, :max_size => 30.megabytes + has_many :assigned_assets, :order => 'position', :dependent => :destroy + has_attachment :storage => :file_system, :thumbnails => { :thumb => '120>', :tiny => '50>' }, :max_size => 30.megabytes, + :processor => (Object.const_defined?(:ASSET_IMAGE_PROCESSOR) ? ASSET_IMAGE_PROCESSOR : nil) before_validation_on_create :set_site_from_parent validates_presence_of :site_id validates_as_attachment @@ -69,6 +71,7 @@ end after_attachment_saved do |record| + File.chmod 0644, record.full_filename Asset.update_all ['thumbnails_count = ?', record.thumbnails.count], ['id = ?', record.id] unless record.parent_id end @@ -82,7 +85,7 @@ protected def rename_unique_filename - if (@old_filename || new_record?) && errors.empty? && site_id && filename + if ((@old_filename && !@old_filename.eql?(full_filename)) || new_record?) && errors.empty? && site_id && filename i = 1 pieces = filename.split('.') ext = pieces.size == 1 ? nil : pieces.pop diff -Nur mephisto-0.7.3/app/models/assigned_asset.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/models/assigned_asset.rb --- mephisto-0.7.3/app/models/assigned_asset.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/models/assigned_asset.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,14 @@ +class AssignedAsset < ActiveRecord::Base + belongs_to :article, :counter_cache => 'assets_count' + belongs_to :asset + acts_as_list :scope => :article_id + validates_presence_of :article_id, :asset_id + validate_on_create :check_for_dupe_article_and_asset + + protected + def check_for_dupe_article_and_asset + unless self.class.count(:all, :conditions => ['article_id = ? and asset_id = ?', article_id, asset_id]).zero? + errors.add_to_base("Cannot have a duplicate assignment for this article and asset") + end + end +end diff -Nur mephisto-0.7.3/app/models/assigned_section.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/models/assigned_section.rb --- mephisto-0.7.3/app/models/assigned_section.rb 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/models/assigned_section.rb 2008-03-31 02:18:56.000000000 -0400 @@ -1,14 +1,14 @@ class AssignedSection < ActiveRecord::Base belongs_to :article belongs_to :section, :counter_cache => 'articles_count' - acts_as_list :scope => 'section_id = #{section_id}' + acts_as_list :scope => :section_id validates_presence_of :article_id, :section_id validate_on_create :check_for_dupe_article_and_section protected def check_for_dupe_article_and_section unless self.class.count(:all, :conditions => ['article_id = ? and section_id = ?', article_id, section_id]).zero? - errors.add_to_base("Cannot have a duplicate categorization for this article and section") + errors.add_to_base("Cannot have a duplicate assignment for this article and section") end end end diff -Nur mephisto-0.7.3/app/models/comment.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/models/comment.rb --- mephisto-0.7.3/app/models/comment.rb 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/models/comment.rb 2008-03-31 02:18:56.000000000 -0400 @@ -7,12 +7,23 @@ before_validation :clean_up_author_url after_validation_on_create :snag_article_attributes before_create :check_comment_expiration + before_create :sanitize_attributes before_save :update_counter_cache before_destroy :decrement_counter_cache belongs_to :article has_one :event, :dependent => :destroy - attr_protected :approved + before_create :check_if_previewing + attr_accessible :article, :article_id, :user_id, :user, :excerpt, :body, :author, :author_url, :author_email, :author_ip, :updater_id, :updater, :comment_age, :user_agent, :referrer, :preview + attr_accessor :preview + class Previewing < StandardError; end + + # If the view sends the "preview" accessor, we raise this + # error so the controller can simply rescue + def check_if_previewing + raise Comment::Previewing if preview + end + def self.find_all_by_section(section, options = {}) find :all, options.update(:conditions => ['contents.approved = ? and assigned_sections.section_id = ?', true, section.id], :select => 'contents.*', :joins => 'INNER JOIN assigned_sections ON assigned_sections.article_id = contents.article_id', @@ -67,12 +78,19 @@ end protected + def sanitize_attributes + [:author, :author_url, :author_email, :author_ip, :user_agent, :referrer].each do |a| + self.send("#{a}=", CGI::escapeHTML(self.send(a).to_s)) + end + end + def snag_article_attributes - self.attributes = { :site => article.site, :filter => article.site.filter, :title => article.title, :published_at => article.published_at, :permalink => article.permalink } + self.filter ||= article.site.filter + [:site, :title, :published_at, :permalink].each { |a| self.send("#{a}=", article.send(a)) } end def check_comment_expiration - raise Article::CommentNotAllowed unless article.accept_comments? + raise Article::CommentNotAllowed, "#{article.status} does not allow comments" unless article.accept_comments? end def update_counter_cache diff -Nur mephisto-0.7.3/app/models/resources.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/models/resources.rb --- mephisto-0.7.3/app/models/resources.rb 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/models/resources.rb 2008-03-31 02:18:56.000000000 -0400 @@ -1,7 +1,8 @@ class Resources < Attachments - NON_IMAGE_EXTNAMES = %w(.js .css) + @@non_image_extnames = %w(.js .css) + cattr_reader :non_image_extnames def image?(path) - !NON_IMAGE_EXTNAMES.include?(path.extname) + !non_image_extnames.include?(path.extname) end def content_type(path) @@ -12,6 +13,7 @@ when '.jpg', '.jpeg' then 'image/jpeg' when '.gif' then 'image/gif' when '.swf' then 'application/x-shockwave-flash' + when '.ico' then 'image/x-icon' end end diff -Nur mephisto-0.7.3/app/models/site.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/models/site.rb --- mephisto-0.7.3/app/models/site.rb 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/models/site.rb 2008-03-31 02:18:56.000000000 -0400 @@ -1,10 +1,32 @@ +require 'uri' + class Site < ActiveRecord::Base - @@theme_path = Pathname.new(RAILS_ROOT) + 'themes' - cattr_reader :theme_path + @@default_assigns = {} + @@theme_path = Pathname.new(RAILS_ROOT) + 'themes' + cattr_reader :theme_path, :default_assigns cattr_accessor :multi_sites_enabled, :cache_sweeper_tracing + + # @@template_handlers = HashWithIndifferentAccess.new if @@template_handlers.nil? + @@template_handlers = {} + + # Register a class that knows how to handle template files with the given + # extension. This can be used to implement new template types. + # The constructor for the class must take a Site instance + # as a parameter, and the class must implement a #render method that + # has the following signature + # def render(section, layout, template, assigns ={}, controller = nil) + # and return the rendered template as a string. + def self.register_template_handler(extension, klass) + @@template_handlers[extension] = klass + end + register_template_handler(".liquid", Mephisto::Liquid::LiquidTemplate) + + def self.extensions + @@template_handlers.keys + end - has_many :sections, :order => "position" do + has_many :sections, :order => "position", :dependent => :destroy do def home find_by_path '' end @@ -19,7 +41,7 @@ end end - has_many :articles do + has_many :articles, :dependent => :destroy do def find_by_permalink(options) conditions = returning ["(contents.published_at IS NOT NULL AND contents.published_at <= ?)", Time.now.utc] do |cond| @@ -41,13 +63,13 @@ end end - has_many :comments, :order => 'comments.created_at desc' + has_many :comments, :order => 'comments.created_at desc', :dependent => :delete_all - has_many :events + has_many :events, :dependent => :destroy - has_many :cached_pages + has_many :cached_pages, :dependent => :destroy - has_many :assets, :order => 'created_at desc', :conditions => 'parent_id is null' + has_many :assets, :order => 'created_at desc', :conditions => 'parent_id is null', :dependent => :destroy has_many :memberships, :dependent => :destroy has_many :members, :through => :memberships, :source => :user @@ -60,13 +82,23 @@ validates_format_of :host, :with => Format::DOMAIN validates_uniqueness_of :host validate :check_permalink_style - after_create { |s| s.sections.create(:name => 'Home') } + + after_create :setup_site_theme_directories + after_create { |site| site.sections.create(:name => 'Home') } + before_destroy :flush_cache_and_remove_site_directories with_options :order => 'contents.created_at DESC', :class_name => 'Comment' do |comment| comment.has_many :comments, :conditions => ['contents.approved = ?', true] comment.has_many :unapproved_comments, :conditions => ['contents.approved = ? or contents.approved is null', false] comment.has_many :all_comments end + + def self.search_by_host_or_title(search_string) + conditions = search_string.blank? ? nil : ["host LIKE ? OR title LIKE ?"] + ["%#{search_string}%"] * 2 + with_scope( :find => { :conditions => conditions } ) do + yield + end + end def users(options = {}) User.find_all_by_site self, options @@ -123,7 +155,7 @@ end def theme - @theme ||= themes[current_theme_path] || themes.first + @theme ||= themes[current_theme_path] || themes.first || raise(MissingThemesError.new(self)) end def change_theme_to(new_theme_path) @@ -150,23 +182,26 @@ end def search_url(query, page = nil) - "/#{search_path}?q=#{CGI::escapeHTML(query)}#{%(&page=#{CGI::escapeHTML(page.to_s)}) unless page.blank?}" + "/#{search_path}?q=#{CGI::escapeHTML(query)}#{%(&page=#{CGI::escapeHTML(page.to_s)}) unless page.blank?}" end def tag_url(*tags) - ['', tag_path, *tags] * '/' + ['', tag_path, *tags.collect { |t| URI::escape(t.to_s) }] * '/' end def accept_comments? comment_age.to_i > -1 end - def render_liquid_for(section, template_type, assigns = {}, controller = nil) + def call_render(section, template_type, assigns = {}, controller = nil) assigns.update('site' => to_liquid(section), 'mode' => template_type) - parse_inner_template(set_content_template(section, template_type), assigns, controller) - parse_template(set_layout_template(section, template_type), assigns, controller) + assigns.update(default_assigns) unless default_assigns.empty? + template = set_content_template(section, template_type) + layout = set_layout_template(section, template_type) + handler = @@template_handlers[theme.extension] || @@template_handlers[".liquid"] + handler.new(self).render(section, layout, template, assigns, controller) end - + def to_liquid(current_section = nil) SiteDrop.new self, current_section end @@ -194,6 +229,13 @@ end end +#need non protected method for ErbTemplate - psq + def find_preferred_template(template_type, custom_template) + preferred = templates.find_preferred(template_type, custom_template) + return preferred if preferred && preferred.file? + raise MissingTemplateError.new(template_type, templates.collect_templates(template_type, custom_template).collect(&:basename)) + end + protected def cached_log_message_for(log_message, pages) pages.inject([log_message, "Expiring #{pages.size} page(s)"]) { |msg, p| msg << " - #{p.url}" }.join("\n") @@ -259,33 +301,38 @@ else case template_type when :tag then tag_layout - when :search then search_layout + when :search then sections.detect(&:home?).layout end end find_preferred_template(:layout, layout_template) end - def find_preferred_template(template_type, custom_template) - preferred = templates.find_preferred(template_type, custom_template) - return preferred if preferred && preferred.file? - raise MissingTemplateError.new(template_type, templates.collect_templates(template_type, custom_template).collect(&:basename)) - end + private - def parse_template(template, assigns, controller) - # give the include tag access to files in the site's fragments directory - Liquid::Template.file_system = Liquid::LocalFileSystem.new(File.join(theme.path, 'templates')) - tmpl = Liquid::Template.parse(template.read.to_s) - returning tmpl.render(assigns, :registers => {:controller => controller}) do |result| - yield tmpl, result if block_given? + def setup_site_theme_directories + begin + theme_path = "#{RAILS_ROOT}/themes/site-#{self.id}/simpla" + FileUtils.mkdir_p("#{RAILS_ROOT}/themes/site-#{self.id}") + FileUtils.cp_r("#{RAILS_ROOT}/themes/default", theme_path) + Dir[File.join(theme_path, '**/.svn')].each do |dir| + FileUtils.rm_rf dir + end + rescue + logger.error "ERROR: removing directories for site #{self.host}, check file permissions." + errors.add_to_base "Unable to create theme directories." + false end end - - def parse_inner_template(template, assigns, controller) - parse_template(template, assigns, controller) do |tmpl, result| - # Liquid::Template takes a copy of the assigns. - # merge any new values in to the assigns and pass them to the layout - tmpl.assigns.each { |k, v| assigns[k] = v } if tmpl.respond_to?(:assigns) - assigns['content_for_layout'] = result + + def flush_cache_and_remove_site_directories + begin + CachedPage.expire_pages self, self.cached_pages + FileUtils.rm_rf("#{RAILS_ROOT}/themes/site-#{self.id}") + FileUtils.rm_rf("#{RAILS_ROOT}/public/cache/#{self.host}") + rescue + logger.error "ERROR: removing directories for site #{self.host}, check file permissions." + false end end + end diff -Nur mephisto-0.7.3/app/models/tag.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/models/tag.rb --- mephisto-0.7.3/app/models/tag.rb 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/models/tag.rb 2008-03-31 02:18:56.000000000 -0400 @@ -1,5 +1,4 @@ class Tag < ActiveRecord::Base - @@tag_parse_regex = /((?: |)['"]{0,1})['"]?\s*(.*?)\s*(?:[,'"]|$)(?:\1(?: |$))/ has_many :taggings class << self @@ -7,23 +6,19 @@ find_by_name(tag.to_s) end - # parses a comma separated list of tags into tag names - # handles all kinds of different tags. (comma seperated, space seperated (in quotation marks)) - # should handle most the common keyword formats. - # - # e.g.: b'log, emacs fun, rails, ruby => "b'log", "emacs fun", "rails", "ruby" - # "b'log" "emacs fun" "rails" "ruby" => "b'log", "emacs fun", "rails", "ruby" - # 'b\'log' 'emacs fun' 'rails' 'ruby' => "b'log", "emacs fun", "rails", "ruby" + # parses a list of tags into tag names # # Tag.parse('a, b, c') # # => ['a', 'b', 'c'] + # + # Tag.parse("a b c") + # # => ['a', 'b', 'c'] + # + # Tag.parse(%(a "b c")) + # # => ['a', 'b c'] def parse(list) return list if list.is_a?(Array) - returning list.scan(@@tag_parse_regex) do |tags| - tags.collect! { |t| t.last.strip!; t.last } - tags.uniq! - tags.delete_if &:blank? - end + list.include?(',') ? parse_with_commas(list) : parse_with_spaces(list) end # Parses comma separated tag list and returns tags for them. @@ -44,6 +39,38 @@ found_tags + (tag_names - found_tags.collect(&:name)).collect { |s| create!(:name => s) } end end + + private + def parse_with_commas(list) + cleanup_tags(list.split(',')) + end + + def parse_with_spaces(list) + tags = [] + + # first, pull out the quoted tags + list.gsub!(/\"(.*?)\"\s*/ ) { tags << $1; "" } + + # then, get whatever's left + tags.concat list.split(/\s/) + + cleanup_tags(tags) + end + + def cleanup_tags(tags) + tags.tap do |t| + t.collect! do |tag| + unless tag.blank? + tag.downcase! + tag.gsub!(/:/, '') + tag.strip! + tag + end + end + t.compact! + t.uniq! + end + end end def ==(comparison_object) diff -Nur mephisto-0.7.3/app/models/templates.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/models/templates.rb --- mephisto-0.7.3/app/models/templates.rb 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/models/templates.rb 2008-03-31 02:18:56.000000000 -0400 @@ -1,15 +1,18 @@ class Templates < Attachments - @@template_types = [:section, :single, :archive, :search, :error, :tag, :layout].collect! { |f| "#{f}.liquid" } + @@template_types = ["section", "single", "archive", "search", "error", "tag", "layout"] @@template_types.sort! - cattr_reader :template_types + def template_types(extension = ".liquid") + @@template_types.collect { |f| "#{f}"+extension } + end + def [](template_name) - template_name = File.basename(template_name.to_s).sub /\.liquid$/, '' - theme.path + "#{template_name =~ /layout$/ ? 'layouts' : 'templates'}/#{template_name}.liquid" + template_name = File.basename(template_name.to_s).sub /#{theme.extension}$/, '' + theme.path + "#{template_name =~ /layout$/ ? 'layouts' : 'templates'}/#{template_name}#{theme.extension}" end def collect_templates(template_type, *custom_templates) - custom_templates.push(template_type).collect! { |t| self[t] } + custom_templates.push(template_type.to_s+theme.extension).collect! { |t| self[t] } end # adds the custom_template to the top of the hierarchy if given @@ -17,7 +20,7 @@ collect_templates(template_type, custom_template).detect(&:file?) end - def custom - @custom ||= collect { |p| p.basename.to_s } - template_types + def custom(extension = ".liquid") + @custom ||= (collect { |p| p.basename.to_s } - template_types(extension)).sort end end \ No newline at end of file diff -Nur mephisto-0.7.3/app/models/theme.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/models/theme.rb --- mephisto-0.7.3/app/models/theme.rb 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/models/theme.rb 2008-03-31 02:18:56.000000000 -0400 @@ -1,9 +1,9 @@ class Theme @@root_theme_files = %w(about.yml preview.png) @@theme_directories = %w(templates layouts javascripts stylesheets images) - @@allowed_extensions = %w(.js .css .liquid .png .gif .jpg .swf) + @@allowed_extensions = %w(.js .css .png .gif .jpg .swf .ico) | Site.extensions cattr_reader :root_theme_files, :theme_directories, :allowed_extensions - attr_reader :path, :base_path + attr_reader :path, :base_path, :extension def self.import(zip_file, options = {}) dest = options[:to].is_a?(Pathname) ? options[:to] : Pathname.new(options[:to] || '.') @@ -47,6 +47,8 @@ @base_path = base @path = Pathname.new(@base_path) end + layout = (@path + "layouts").children(false).select {|v| v.to_s =~ /^layout/}[0] if (@path + "layouts").directory? + @extension = layout.extname if layout end def current? @@ -98,7 +100,7 @@ Pathname.glob(File.join(base_path, '*/*')).each do |path| next unless path.file? @attachments << path - (path.extname == '.liquid' ? @templates : @resources) << path + ((path.extname == @extension) ? @templates : @resources) << path end @attachments end diff -Nur mephisto-0.7.3/app/models/user.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/models/user.rb --- mephisto-0.7.3/app/models/user.rb 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/models/user.rb 2008-03-31 02:18:56.000000000 -0400 @@ -6,7 +6,10 @@ # Virtual attribute for the unencrypted password attr_accessor :password - + + #Only these can be modified through bulk-setters like update_attributes, new, create + attr_accessible :login, :email, :password, :password_confirmation, :filter + validates_presence_of :login, :email validates_format_of :email, :with => Format::EMAIL validates_presence_of :password, :if => :password_required? diff -Nur mephisto-0.7.3/app/models/user_mailer.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/models/user_mailer.rb --- mephisto-0.7.3/app/models/user_mailer.rb 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/models/user_mailer.rb 2008-03-31 02:18:56.000000000 -0400 @@ -6,7 +6,7 @@ def forgot_password(user) setup_email(user) @subject += 'Request to change your password' - @body[:url] = url_for :controller => :account, :action => :activate, :id => user.token + @body[:url] = url_for :controller => 'account', :action => 'activate', :id => user.token end protected diff -Nur mephisto-0.7.3/app/views/account/login.rhtml technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/views/account/login.rhtml --- mephisto-0.7.3/app/views/account/login.rhtml 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/views/account/login.rhtml 2008-03-31 02:18:56.000000000 -0400 @@ -1,5 +1,5 @@
-<% form_tag({:controller=>:account, :action=>:login}, { :id => 'login_form' }) do -%> +<% form_tag({:controller=>'account', :action=>'login'}, { :id => 'login_form' }) do -%>
<%= label_tag 'login', 'Login' %>
<%= text_field_tag 'login', params[:login], :class => 'big' %>
diff -Nur mephisto-0.7.3/app/views/admin/articles/_article.rhtml technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/views/admin/articles/_article.rhtml --- mephisto-0.7.3/app/views/admin/articles/_article.rhtml 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/views/admin/articles/_article.rhtml 2008-03-31 02:18:56.000000000 -0400 @@ -5,9 +5,9 @@ <% if article.comments.size == 0 %> none <% else %> - <%= link_to article.comments.size.to_s.rjust(2, '0'), { :action => 'comments', :id => article } %> + <%= link_to article.comments.size.to_s.rjust(2, '0'), article_comments_path(article) %> <% end %> <%= published_at_for article %> - <%= article.published? ? link_to(image_tag('/images/mephisto/icons/24-zoom-in.png', :style => 'vertical-align: middle'), article.full_permalink) : ' ' %> + <%= article.published? ? link_to(image_tag('/images/mephisto/icons/24-zoom-in.png', :style => 'vertical-align: middle'), @site.permalink_for(article)) : ' ' %> diff -Nur mephisto-0.7.3/app/views/admin/articles/_form.rhtml technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/views/admin/articles/_form.rhtml --- mephisto-0.7.3/app/views/admin/articles/_form.rhtml 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/views/admin/articles/_form.rhtml 2008-03-31 02:18:56.000000000 -0400 @@ -5,11 +5,11 @@
<%= form.text_field :title, :class => 'big' %>
-
<%= form.label_for :excerpt %> (<%= link_to_function 'Cancel', %(['x-lbl', 'x-body'].each(Element.toggle)) %>)
+
<%= form.label_for :excerpt %> (<%= link_to_function 'Hide', %(['x-lbl', 'x-body'].each(Element.toggle)) %>)
<%= form.text_area :excerpt, :rows => '8', :class => 'fat' %>
(<%= link_to_function 'Add an excerpt', %(['x-lbl', 'x-body'].each(Element.toggle)) %>)
<%= form.text_area :body, :class => 'fat', :rows => 25 %>
-
Enter one or more tags separated by a comma.
+
Enter one or more tags separated by a comma or a space (for example, "Web Dev" Tutorials or Web Dev, Tutorials).
<%= form.text_field :tag %>
@@ -22,7 +22,7 @@ diff -Nur mephisto-0.7.3/app/views/admin/articles/_page_nav.rhtml technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/views/admin/articles/_page_nav.rhtml --- mephisto-0.7.3/app/views/admin/articles/_page_nav.rhtml 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/views/admin/articles/_page_nav.rhtml 2008-03-31 02:18:56.000000000 -0400 @@ -2,13 +2,15 @@ <% content_for :action_nav do %> -<% end unless @article.new_record? && @article.comments.empty? -%> \ No newline at end of file +<% end unless @article && @article.new_record? && @article.comments.size == 0 -%> \ No newline at end of file diff -Nur mephisto-0.7.3/app/views/admin/articles/_shared_options.rhtml technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/views/admin/articles/_shared_options.rhtml --- mephisto-0.7.3/app/views/admin/articles/_shared_options.rhtml 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/views/admin/articles/_shared_options.rhtml 2008-03-31 02:18:56.000000000 -0400 @@ -14,6 +14,7 @@
  • Latest
  • +
  • Attached
  • Upload
  • Bucket
  • @@ -21,8 +22,13 @@
    -
      - <%= render :partial => "admin/assets/widget", :collection => @assets %> +
        + <%= render :partial => "admin/assets/widget", :collection => @assets, :locals => { :prefix => 'latest' } %> +
      +
    +
    diff -Nur mephisto-0.7.3/app/views/admin/articles/approve.rjs technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/views/admin/articles/approve.rjs --- mephisto-0.7.3/app/views/admin/articles/approve.rjs 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/views/admin/articles/approve.rjs 1969-12-31 19:00:00.000000000 -0500 @@ -1 +0,0 @@ -page["comment-#{@comment.id}"].add_class_name 'disabled' \ No newline at end of file diff -Nur mephisto-0.7.3/app/views/admin/articles/attach.rjs technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/views/admin/articles/attach.rjs --- mephisto-0.7.3/app/views/admin/articles/attach.rjs 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/views/admin/articles/attach.rjs 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1 @@ +page.insert_html :bottom, 'attached-assets', :partial => 'admin/assets/widget', :object => @asset, :locals => { :prefix => 'attached' } \ No newline at end of file diff -Nur mephisto-0.7.3/app/views/admin/articles/comments.rhtml technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/views/admin/articles/comments.rhtml --- mephisto-0.7.3/app/views/admin/articles/comments.rhtml 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/views/admin/articles/comments.rhtml 1969-12-31 19:00:00.000000000 -0500 @@ -1,57 +0,0 @@ -<%= render :partial => "page_nav" %> - - -

    Comments on <%= link_to @article.title, { :action => 'edit', :id => @article }, :style => 'border:none' %> <%= @article.published? ? link_to(image_tag('/images/mephisto/icons/24-zoom-in.png', :style => 'vertical-align: middle'), @article.full_permalink, :style => 'border:none;') : ' ' %>

    - -
      - <% if @comments.any? %> - <% @comments.reverse.each_with_index do |comment, i| -%> -
    • 0) %>" id="comment-<%= comment.id %>"> - <% if false %> - - <% end %> - - <% unless comment.body.blank? -%> -

      "<%= strip_tags(comment.body) %>"

      - <% end -%> - - — <%= author_link_for comment %><%= %( (#{comment.author_email})) unless comment.author_email.blank? %> said <%= time_ago_in_words comment.created_at %> ago - - <% if comment.approved? -%> - <%= link_to_remote 'Unapprove', :url => { :action => 'unapprove', :id => @article, :comment => comment } %> | - <% else -%> - <%= link_to_remote 'Approve', :url => { :action => 'approve', :id => @article, :comment => comment } %> | - <% end -%> - <%= link_to_remote 'Delete', :url => { :action => 'destroy_comment', :id => @article, :comment => comment } %> - -
    • - <% end -%> - <% else %> -
    • This article has no <%= params[:filter].to_s.humanize.downcase %> comments.
    • - <% end %> -
    - - -<% content_for :sidebar do %> - <% if @articles.size > 1 -%> -
    -

    Comments awaiting your approval

    -
      - <% @articles.each do |article, count| -%> - <% if article.title != @article.title -%> -
    • <%= link_to "(#{count}) #{h(article.title)}", :controller => 'articles', :action => 'comments', :id => article.id, :filter => :unapproved %>
    • - <% end -%> - <% end -%> -
    -
    - <% end -%> -<% end %> - - - \ No newline at end of file diff -Nur mephisto-0.7.3/app/views/admin/articles/destroy_comment.rjs technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/views/admin/articles/destroy_comment.rjs --- mephisto-0.7.3/app/views/admin/articles/destroy_comment.rjs 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/views/admin/articles/destroy_comment.rjs 1969-12-31 19:00:00.000000000 -0500 @@ -1,3 +0,0 @@ -@comments.each do |comment| - page["comment-#{comment.id}"].add_class_name 'disabled' -end \ No newline at end of file diff -Nur mephisto-0.7.3/app/views/admin/articles/edit.rhtml technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/views/admin/articles/edit.rhtml --- mephisto-0.7.3/app/views/admin/articles/edit.rhtml 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/views/admin/articles/edit.rhtml 2008-03-31 02:18:56.000000000 -0400 @@ -1,23 +1,24 @@ <%= render :partial => "page_nav" %> <% fields_for :article, @version do |f| -%> -<% content_for :sidebar do %> - <%= render :partial => 'shared_options', :locals => { :form => f } %> -<% end %> + <% content_for :sidebar do %> + <%= render :partial => 'shared_options', :locals => { :form => f } %> + <% end %> <% end %> <%= error_messages_for :article %> <% content_for :form do -%> - <%= form_tag({:action => 'update', :id => @article}, {:id => 'article-form', :multipart => true}) %> + <%= form_tag({:action => 'update', :id => @article}, {:id => 'article-form', :multipart => true, :method => :put}) %> <% end -%> <% fields_for :article, @version do |f| -%> -<%= render :partial => 'form', :object => f %> -

    - <%= submit_tag 'Apply Changes' %> - <%= submit_tag 'Save without Revision' %> - <%= link_to "cancel", :controller => "articles" %>

    + <%= render :partial => 'form', :object => f %> +

    + <%= submit_tag 'Apply Changes' %> + <%= submit_tag 'Save without Revision' %> + <%= link_to "cancel", :controller => "articles" %> +

    <% end -%> diff -Nur mephisto-0.7.3/app/views/admin/articles/index.rhtml technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/views/admin/articles/index.rhtml --- mephisto-0.7.3/app/views/admin/articles/index.rhtml 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/views/admin/articles/index.rhtml 2008-03-31 02:18:56.000000000 -0400 @@ -36,7 +36,12 @@
<% end %> -<% if @articles.any? %> +<% if @articles.size > 0 -%> + +<% content_tag :p, :class => 'total' do %> + Total: <%= content_tag :strong, @articles.total_entries %> articles. +<% end %> + @@ -54,13 +59,10 @@
- - <% else %> @@ -79,7 +81,7 @@

Comments awaiting your approval

    <% @comments.each do |article, count| -%> -
  • <%= link_to "(#{count}) #{h(article.title)}", :controller => 'articles', :action => 'comments', :id => article.id, :filter => :unapproved %>
  • +
  • <%= link_to "(#{count}) #{h(article.title)}", article_comments_path(article), :filter => :unapproved %>
  • <% end -%>
diff -Nur mephisto-0.7.3/app/views/admin/articles/label.rjs technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/views/admin/articles/label.rjs --- mephisto-0.7.3/app/views/admin/articles/label.rjs 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/views/admin/articles/label.rjs 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1 @@ +page["label-attached-widget-#{params[:version]}"].replace_html "Save" \ No newline at end of file diff -Nur mephisto-0.7.3/app/views/admin/assets/_assets.rhtml technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/views/admin/assets/_assets.rhtml --- mephisto-0.7.3/app/views/admin/assets/_assets.rhtml 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/views/admin/assets/_assets.rhtml 2008-03-31 02:18:56.000000000 -0400 @@ -27,8 +27,6 @@
You have no files of this type or have yet to upload any files. <%= link_to 'Upload one now »', :action => 'new' %>
<% end %> -<% if @asset_pages.page_count > 1 %> - -<% end %> \ No newline at end of file +<% if @assets.page_count > 1 %> + <%= will_paginate @assets, :id => 'pagination' %> +<% end %> diff -Nur mephisto-0.7.3/app/views/admin/assets/_widget.rhtml technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/views/admin/assets/_widget.rhtml --- mephisto-0.7.3/app/views/admin/assets/_widget.rhtml 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/views/admin/assets/_widget.rhtml 2008-03-31 02:18:56.000000000 -0400 @@ -1,3 +1,18 @@ -
  • +
  • " class="widget<%= ' selected-widget' if @article && @article.assets.include?(widget) %>"> +<% if prefix == 'attached' -%> +
    + <%= link_to asset_image_for(widget), widget.public_filename %> + + <%= text_field_tag :version, (widget.respond_to?(:label) ? widget.label : nil), :id => widget.dom_id("#{prefix}-widget-version"), :class => 'txt' %> + ">Save + +
    +<% else -%> <%= link_to asset_image_for(widget), widget.public_filename %> -
  • \ No newline at end of file +<% end -%> + <%= image_tag('mephisto/icons/8-em-cross.png', :size => '16x16', :id => widget.dom_id("detach-#{prefix}-widget"), + :style => 'display:none', :class => 'detach-widget') %> + <%= image_tag('mephisto/icons/8-em-plus.png', :size => '16x16', :id => widget.dom_id("attach-#{prefix}-widget"), + :style => 'display:none', :class => 'attach-widget') %> + +<% if widget_counter.remainder(4).zero? && widget_counter > 0 %>
    <% end %> diff -Nur mephisto-0.7.3/app/views/admin/assets/edit.rhtml technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/views/admin/assets/edit.rhtml --- mephisto-0.7.3/app/views/admin/assets/edit.rhtml 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/views/admin/assets/edit.rhtml 2008-03-31 02:18:56.000000000 -0400 @@ -6,7 +6,7 @@ <%= error_messages_for :asset %>
    -
    Enter one or more tags separated by a comma.
    +
    Enter one or more tags separated by a comma or a space (for example, "Web Dev" Tutorials or Web Dev, Tutorials).
    <%= f.text_field :tag %>
    <%= f.file_field :uploaded_data %>
    diff -Nur mephisto-0.7.3/app/views/admin/assets/index.rhtml technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/views/admin/assets/index.rhtml --- mephisto-0.7.3/app/views/admin/assets/index.rhtml 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/views/admin/assets/index.rhtml 2008-03-31 02:18:56.000000000 -0400 @@ -43,7 +43,7 @@
      <% session[:bucket].each do |filename, values| -%>
    • - <%= link_to(image_tag(*values), filename, :target => '_blank') %> + <%= image_tag(*values) %>
    • <% end unless session[:bucket].blank? %>
    @@ -55,4 +55,4 @@ <%= number_to_human_size site.assets.sum(:size) %>.

    -<% end %> \ No newline at end of file +<% end %> diff -Nur mephisto-0.7.3/app/views/admin/cached_pages/pages.rhtml technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/views/admin/cached_pages/pages.rhtml --- mephisto-0.7.3/app/views/admin/cached_pages/pages.rhtml 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/views/admin/cached_pages/pages.rhtml 2008-03-31 02:18:56.000000000 -0400 @@ -1,34 +1,23 @@ -<% if @cached_pages.size > 0 -%> - -
    -<% if @cached_page_pages.page_count > 1 %> -Pages: <%= pagination_remote_links @cached_page_pages, :params => { :action => :index } %> -<% end %> -
    -

    Cached Pages


    - - - - - - - - - +<% unless @cached_pages.empty? -%> + <%= will_paginate @cached_pages, :class => 'pages' if @cached_pages.page_count > 1 %> + +

    Cached Pages


    +
     URLDateActions
    + + + + + + + + - - <%= render :partial => 'page', :collection => @cached_pages %> - -
     URLDateActions
    - + + <%= render :partial => 'page', :collection => @cached_pages %> + + + + <%= will_paginate @cached_pages, :id => 'pagination' if @cached_pages.page_count > 1 %> <% else -%>
    There currently aren't any pages being cached by Mephisto.
    -<% end -%> - - - - \ No newline at end of file +<% end -%> \ No newline at end of file diff -Nur mephisto-0.7.3/app/views/admin/comments/_comment.rhtml technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/views/admin/comments/_comment.rhtml --- mephisto-0.7.3/app/views/admin/comments/_comment.rhtml 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/views/admin/comments/_comment.rhtml 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,16 @@ + +
  • " id="comment-<%= comment.id %>"> +

    <%= link_to comment.article.title, :controller => 'articles', :action => 'edit', :id => comment.article %>

    +

    "<%= truncate strip_tags(comment.body), 255 %>"

    + + — <%= author_link_for comment %><%= %( (#{comment.author_email})) unless comment.author_email.blank? %> + + <%= link_to_remote 'Edit', :url => edit_article_comment_path(@article, comment), :method => :get %> | + <% if comment.approved? -%> + <%= link_to_remote 'Unapprove', :url => unapprove_article_comment_path(comment.article, comment) %> | + <% else -%> + <%= link_to_remote 'Approve', :url => approve_article_comment_path(comment.article, comment) %> | + <% end -%> + <%= link_to_remote 'Delete', :url => article_comment_path(comment.article, comment), :method => :delete %> + +
  • diff -Nur mephisto-0.7.3/app/views/admin/comments/_edit_comment.rhtml technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/views/admin/comments/_edit_comment.rhtml --- mephisto-0.7.3/app/views/admin/comments/_edit_comment.rhtml 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/views/admin/comments/_edit_comment.rhtml 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,9 @@ +
  • + <%= error_messages_for :comment %> + <% remote_form_for :comment, :url => article_comment_path(@article, comment), :html => { :method => :put, :onsubmit => "$('comment-#{comment.id}-spinner').show()" } do |form| %> + <%= render :partial => 'form', :object => form %> + <%= submit_tag "Update" %> + + <%= link_to_function "Cancel", "$('comment-#{comment.id}').show(); $('edit-comment-#{comment.id}').remove()" %> + <% end # form %> +
  • \ No newline at end of file diff -Nur mephisto-0.7.3/app/views/admin/comments/_form.rhtml technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/views/admin/comments/_form.rhtml --- mephisto-0.7.3/app/views/admin/comments/_form.rhtml 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/views/admin/comments/_form.rhtml 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,16 @@ +

    + + <%= form.text_field :author %> +

    +

    + + <%= form.text_field :author_email %> +

    +

    + + <%= form.text_field :author_url %> +

    +

    + <%= form.text_area :body, { :rows => '10' } %> +

    + diff -Nur mephisto-0.7.3/app/views/admin/comments/_new_comment.rhtml technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/views/admin/comments/_new_comment.rhtml --- mephisto-0.7.3/app/views/admin/comments/_new_comment.rhtml 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/views/admin/comments/_new_comment.rhtml 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,5 @@ + <%= error_messages_for :comment %> + <% remote_form_for :comment, :url => article_comments_path(@article) do |form| %> + <%= render :partial => 'form', :object => form %> + <%= submit_tag "Create" %> or <%= link_to_function "hide", "$('new-comment-form').toggle()" %> + <% end # form %> diff -Nur mephisto-0.7.3/app/views/admin/comments/approve.rjs technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/views/admin/comments/approve.rjs --- mephisto-0.7.3/app/views/admin/comments/approve.rjs 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/views/admin/comments/approve.rjs 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1 @@ +page["comment-#{@comment.id}"].add_class_name 'disabled' \ No newline at end of file diff -Nur mephisto-0.7.3/app/views/admin/comments/create.rjs technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/views/admin/comments/create.rjs --- mephisto-0.7.3/app/views/admin/comments/create.rjs 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/views/admin/comments/create.rjs 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,6 @@ + if @comment.new_record? + page.replace_html 'new-comment-form', :partial => 'new_comment' + else + page['new-comment-form'].reset + page.insert_html :top, 'comment-list', :partial => 'comment', :object => @comment + end diff -Nur mephisto-0.7.3/app/views/admin/comments/destroy.rjs technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/views/admin/comments/destroy.rjs --- mephisto-0.7.3/app/views/admin/comments/destroy.rjs 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/views/admin/comments/destroy.rjs 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,3 @@ +@comments.each do |comment| + page["comment-#{comment.id}"].add_class_name 'disabled' +end \ No newline at end of file diff -Nur mephisto-0.7.3/app/views/admin/comments/edit.rjs technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/views/admin/comments/edit.rjs --- mephisto-0.7.3/app/views/admin/comments/edit.rjs 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/views/admin/comments/edit.rjs 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,2 @@ + page.insert_html :after, "comment-#{@comment.id}", :partial => 'edit_comment', :locals => { :comment => @comment } + page.hide "comment-#{@comment.id}" diff -Nur mephisto-0.7.3/app/views/admin/comments/index.rhtml technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/views/admin/comments/index.rhtml --- mephisto-0.7.3/app/views/admin/comments/index.rhtml 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/views/admin/comments/index.rhtml 2008-03-31 02:18:56.000000000 -0400 @@ -1,33 +1,65 @@ -<% content_for :action_nav do %> - - - -<% end %> +<%= render :partial => "admin/articles/page_nav" %> + +

    +<% if @article -%> +Comments on <%= link_to @article.title, edit_article_path(@article), :style => 'border:none' %> <%= @article.published? ? link_to(image_tag('/images/mephisto/icons/24-zoom-in.png', :style => 'vertical-align: middle'), @site.permalink_for(@article), :style => 'border:none;') : ' ' %> +<% else -%> +Comments for all articles +<% end -%> +

    -

    <%= pluralize(@comments.size, 'Unapproved Comment') %>

    +<% if @article -%> + <%= link_to_function "New comment", "$('new-comment-form').toggle()" %> + +<% end -%> -
      - <% @comments.reverse.each_with_index do |comment, i| -%> -
    • 0) %>" id="comment-<%= comment.id %>"> -

      <%= link_to comment.article.title, :controller => 'articles', :action => :edit, :id => comment.article %>

      -

      "<%= truncate strip_tags(comment.body), 255 %>"

      +
        + <% if @comments.any? %> + <% @comments.reverse.each do |comment| -%> +
      • " id="comment-<%= comment.id %>"> + + <% unless comment.body.blank? -%> +

        "<%= strip_tags(comment.body) %>"

        + <% end -%> - — <%= author_link_for comment %><%= %( (#{comment.author_email})) unless comment.author_email.blank? %> - + — <%= author_link_for comment %><%= %( (#{comment.author_email})) unless comment.author_email.blank? %> said <%= time_ago_in_words comment.created_at %> ago + + <%= link_to_remote 'Edit', :url => edit_article_comment_path(comment.article, comment), :method => :get %> | <% if comment.approved? -%> - <%= link_to_remote 'Unapprove', :url => { :action => 'unapprove', :controller => 'articles', :id => comment.article, :comment => comment } %> | + <%= link_to_remote 'Unapprove', :url => unapprove_article_comment_path(comment.article, comment) %> | <% else -%> - <%= link_to_remote 'Approve', :url => { :action => 'approve', :controller => 'articles', :id => comment.article, :comment => comment } %> | + <%= link_to_remote 'Approve', :url => approve_article_comment_path(comment.article, comment) %> | <% end -%> - <%= link_to_remote 'Delete', :url => { :action => 'destroy_comment', :controller => 'articles', :id => comment.article, :comment => comment } %> + <%= link_to_remote 'Delete', :url => article_comment_path(comment.article, comment), :method => :delete %>
      • <% end -%> + <% else %> +
      • This article has no <%= params[:filter].to_s.humanize.downcase %> comments.
      • + <% end %>
      + + +<% content_for :sidebar do %> + <% if @articles.size > 1 -%> +
      +

      Comments awaiting your approval

      +
        + <% @articles.each do |article, count| -%> + <% if @article.nil? || article.title != @article.title -%> +
      • <%= link_to "(#{count}) #{h(article.title)}", :controller => 'comments', :action => 'index', :article_id => article.id, :filter => :unapproved %>
      • + <% end -%> + <% end -%> +
      +
      + <% end -%> +<% end %> + + + diff -Nur mephisto-0.7.3/app/views/admin/comments/unapproved.rhtml technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/views/admin/comments/unapproved.rhtml --- mephisto-0.7.3/app/views/admin/comments/unapproved.rhtml 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/views/admin/comments/unapproved.rhtml 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,20 @@ +<% content_for :action_nav do %> + + + +<% end %> + +

      <%= pluralize(@comments.size, 'Unapproved Comment') %>

      + +
        + <% @comments.reverse.each_with_index do |comment, i| -%> + <%= render :partial => 'comment', :object => comment %> + <% end -%> +
      diff -Nur mephisto-0.7.3/app/views/admin/comments/update.rjs technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/views/admin/comments/update.rjs --- mephisto-0.7.3/app/views/admin/comments/update.rjs 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/views/admin/comments/update.rjs 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,3 @@ + + page.replace "comment-#{@comment.id}", :partial => 'comment', :object => @comment + page.remove "edit-comment-#{@comment.id}" \ No newline at end of file diff -Nur mephisto-0.7.3/app/views/admin/design/_sidebar.rhtml technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/views/admin/design/_sidebar.rhtml --- mephisto-0.7.3/app/views/admin/design/_sidebar.rhtml 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/views/admin/design/_sidebar.rhtml 2008-03-31 02:18:56.000000000 -0400 @@ -3,10 +3,10 @@

      Modify a template by selecting it from the list below. Add a new layout by creating a Liquid template with an *_layout suffix (e.g custom_layout).

        - <% @theme.templates.template_types.each do |template| -%> + <% @theme.templates.template_types(@theme.extension).each do |template| -%>
      • <%= link_to template, url_for_theme(:controller => 'templates', :action => 'edit', :filename => template) %>
      • <% end -%> - <% @theme.templates.custom.each_with_index do |template, i| -%> + <% @theme.templates.custom(@theme.extension).each_with_index do |template, i| -%>
      • <%= delete_link :templates, template, "templates-#{i}" %> <%= link_to template, url_for_theme(:controller => 'templates', :action => 'edit', :filename => template) %> diff -Nur mephisto-0.7.3/app/views/admin/overview/_comment_event.rhtml technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/views/admin/overview/_comment_event.rhtml --- mephisto-0.7.3/app/views/admin/overview/_comment_event.rhtml 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/views/admin/overview/_comment_event.rhtml 2008-03-31 02:18:56.000000000 -0400 @@ -1,14 +1,22 @@ <% with_options :controller => 'articles', :id => event.article_id do |article| -%>
      • "> - <%= link_to event.article.title, :controller => 'articles', :action => 'comments', :id => event.article_id, :anchor => "comment-#{event.comment_id}" %> received a comment. +
        + <%= link_to event.article.title, :controller => 'articles', :action => 'comments', :id => event.article_id, :anchor => "comment-#{event.comment_id}" %> received a comment. - <%= event_time_for event, later %> - <% unless event.body.blank? -%> -

        "<%= truncate strip_tags(event.body), 100 %>"

        - <% end -%> - - — <%=h event.author %> - - + <%= event_time_for event, later %> + <% unless event.body.blank? -%> +

        "<%= truncate strip_tags(event.body), 100 %>"

        + <% end -%> + — <%=h event.author %> + + <% if event.comment -%> + <% if event.comment.approved? -%> + <%= link_to_remote 'Unapprove', :url => unapprove_article_comment_path(event.article_id, event.comment_id) %> | + <% else -%> + <%= link_to_remote 'Approve', :url => approve_article_comment_path(event.article_id, event.comment_id) %> | + <% end -%> + <%= link_to_remote 'Delete', :url => article_comment_path(event.article_id, event.comment_id), :method => :delete %> + <% end -%> +
      • <% end -%> diff -Nur mephisto-0.7.3/app/views/admin/overview/index.rhtml technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/views/admin/overview/index.rhtml --- mephisto-0.7.3/app/views/admin/overview/index.rhtml 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/views/admin/overview/index.rhtml 2008-03-31 02:18:56.000000000 -0400 @@ -9,7 +9,7 @@
      • <%= link_to "Upload asset", new_asset_path %>
      • <% if @articles.any? -%> -
      • <%= link_to "Moderate Comments", :controller => 'comments' %>
      • +
      • <%= link_to "Moderate Comments", moderate_path %>
      • <% end -%>
      diff -Nur mephisto-0.7.3/app/views/admin/plugins/_plugin.rhtml technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/views/admin/plugins/_plugin.rhtml --- mephisto-0.7.3/app/views/admin/plugins/_plugin.rhtml 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/views/admin/plugins/_plugin.rhtml 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,10 @@ + + + <% if plugin.configurable? -%> + <%= link_to plugin.mephisto_name, :action => 'show', :id => plugin.name %> + <% else -%> + <%=h plugin.mephisto_name %> + <% end -%> + + <%= plugin.configurable? ? link_to(image_tag('/images/mephisto/icons/8-em-check.png', :style => 'vertical-align: middle'), :action => "show", :id => plugin.name) : ' ' %> + diff -Nur mephisto-0.7.3/app/views/admin/plugins/index.rhtml technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/views/admin/plugins/index.rhtml --- mephisto-0.7.3/app/views/admin/plugins/index.rhtml 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/views/admin/plugins/index.rhtml 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,31 @@ +<% if @plugins.size > 0 -%> + + + + + + + + + + + <%= render :partial => 'plugin', :collection => @plugins -%> + +
      PluginConfigurable? 
      + +<% end %> + +<% content_for :action_nav do %> + + + +<% end -%> + +<% content_for :sidebar do %> +
      +Configurable plugins may include modifiable properties, notes, homepage, author, and version information. +
      +<% end %> \ No newline at end of file diff -Nur mephisto-0.7.3/app/views/admin/plugins/show.rhtml technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/views/admin/plugins/show.rhtml --- mephisto-0.7.3/app/views/admin/plugins/show.rhtml 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/views/admin/plugins/show.rhtml 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,54 @@ + +<% content_for :sidebar do %> +
      +

      Errata

      + <% unless @plugin.notes.blank? -%> +

      Notes:

      +

      <%= simple_format @plugin.notes %>

      +
      + <% end %> + <% unless @plugin.author.blank? -%> +

      Author: <%=h @plugin.author %>

      + <% end -%> + <% unless @plugin.homepage.blank? -%> +

      Homepage: <%= @plugin.homepage %>

      + <% end -%> + <% unless @plugin.version.blank? -%> +

      Ver.: <%= @plugin.version %>

      + <% end -%> +
      +<% end %> + +<% content_for :action_nav do %> + +<% end %> + +<% content_for :form do -%> + <%= form_tag({:action => 'update', :id => @plugin.name}, {:id => 'plugin-config-form'}) %> +<% end -%> + +<% if @plugin.default_options.any? -%> +
      +
      +
      + <% @plugin.default_options.keys.each do |key| %> +
      <%= send "#{@plugin.default_options[key]}_tag", "options[#{key}]", @plugin.send(key) %>
      + <% end %> +
      + +

      + <%= submit_tag %> +

      +
      +<% else -%> +No configuration listed (perhaps not needed). +<% end -%> diff -Nur mephisto-0.7.3/app/views/admin/settings/index.rhtml technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/views/admin/settings/index.rhtml --- mephisto-0.7.3/app/views/admin/settings/index.rhtml 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/views/admin/settings/index.rhtml 2008-03-31 02:18:56.000000000 -0400 @@ -3,6 +3,7 @@ - \ No newline at end of file + diff -Nur mephisto-0.7.3/app/views/mephisto/_article.rxml technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/views/mephisto/_article.rxml --- mephisto-0.7.3/app/views/mephisto/_article.rxml 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/app/views/mephisto/_article.rxml 2008-03-31 02:18:56.000000000 -0400 @@ -5,6 +5,12 @@ xm.id "tag:#{request.host_with_port},#{article.updated_at.to_date.to_s :db}:#{article.id}:#{article.version}" xm.published article.published_at.xmlschema if article.published_at xm.updated article.updated_at.xmlschema + article.sections.each do |section| + xm.category "term" => section.name unless section.home? + end if article.respond_to?(:sections) + article.tags.each do |tag| + xm.category "term" => tag.name + end xm.link "rel" => "alternate", "type" => "text/html", "href" => "http://#{request.host_with_port}#{site.permalink_for(article)}" xm.title strip_tags(article.title) unless article.excerpt_html.blank? diff -Nur mephisto-0.7.3/config/environment.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/config/environment.rb --- mephisto-0.7.3/config/environment.rb 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/config/environment.rb 2008-03-31 02:18:56.000000000 -0400 @@ -10,16 +10,22 @@ # Bootstrap the Rails environment, frameworks, and default configuration require File.join(File.dirname(__FILE__), 'boot') +require File.join(File.dirname(__FILE__), '../vendor/plugins/engines/boot') +require File.join(File.dirname(__FILE__), '../lib/mephisto/plugin') # requires vendor-loaded redcloth require 'RedCloth-3.0.4/lib/redcloth' unless Object.const_defined?(:RedCloth) + Rails::Initializer.run do |config| # Settings in config/environments/* take precedence those specified here # Skip frameworks you're not going to use - # config.frameworks -= [ :action_web_service ] + config.frameworks -= [ :active_resource ] config.load_paths += %W( #{RAILS_ROOT}/app/cachers #{RAILS_ROOT}/app/drops #{RAILS_ROOT}/app/filters ) + + # NFI why this is here. find and eradicate the bug. + config.load_paths += %W( #{RAILS_ROOT}/vendor/rails/actionwebservice/lib ) # Force all environments to use the same logger level # (by default production uses :info, the others :debug) @@ -27,7 +33,8 @@ # Use the database for sessions instead of the file system # (create the session table with 'rake create_sessions_table') - config.action_controller.session_store = :active_record_store + # config.action_controller.session_store = :active_record_store + config.action_controller.session = { :session_key => "_mephisto_session", :secret => "bd088a0f5b476fe5a2c02653a93ed14a95a8396829ce4e726ee77553ab6438a98d0f3e6d80fc6b120370ba047f28e09f71543ae5f842365e5070e7db51fb2cb9" } # Make Active Record use UTC-base instead of local time config.active_record.default_timezone = :utc @@ -37,43 +44,5 @@ config.active_record.schema_format = :ruby end -# Include your application configuration below -require 'mephisto_init' - -# Set this if you're running under a sub directory -# ActionController::AbstractRequest.relative_url_root = '/blog' - -# turn this on to get detailed cache sweeper logging in production mode -# Site.cache_sweeper_tracing = true - -# Enable if you want to host multiple sites on this app -# Site.multi_sites_enabled = true - -# shouldn't need to set the host, it's set automatically -UserMailer.default_url_options[:host] = 'localhost:3000' -UserMailer.mail_from = 'webmaster@localhost' - -# OPTIONAL - Redirections -# Deny a route by immediately returning a 404 -# -# Mephisto::Routing.deny 'articles/trackback/*' # return 404 -# -# Specify multiple denied routes: -# -# Mephisto::Routing.deny 'articles/trackback/*', 'monkey/foo/*' -# -# Redirect elsewhere. You can fill in variables marked by ? or * with variable names beginning with : -# -# Redirect /old/foo to /new/foo and /old/foo/bar to /new/foo/bar -# -# Mephisto::Routing.redirect 'old/*' => 'new/$1' -# -# Redirect with a more specific set of variables -# -# Mephisto::Routing.redirect 'article/?/?/?' => 'new/$2/$1/$3' - -# Multiple redirections at a time -# -# Mephisto::Routing.redirect \ -# 'old/*' => 'new/$1', -# 'article/?/?/?' => 'new/$2/$1/$3' \ No newline at end of file +# Don't update this file, make custom tweaks in config/initializers/custom.rb, +# or create your own file in config/initializers \ No newline at end of file diff -Nur mephisto-0.7.3/config/environments/development.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/config/environments/development.rb --- mephisto-0.7.3/config/environments/development.rb 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/config/environments/development.rb 2008-03-31 02:18:56.000000000 -0400 @@ -8,9 +8,6 @@ # Log error messages when you accidentally call methods on nil. config.whiny_nils = true -# Enable the breakpoint server that script/breakpointer connects to -config.breakpoint_server = true - # Show full error reports and disable caching config.action_controller.consider_all_requests_local = true config.action_controller.perform_caching = false diff -Nur mephisto-0.7.3/config/initializers/custom.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/config/initializers/custom.rb --- mephisto-0.7.3/config/initializers/custom.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/config/initializers/custom.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,40 @@ +# Set this if you're running under a sub directory +# ActionController::AbstractRequest.relative_url_root = '/blog' + +# turn this on to get detailed cache sweeper logging in production mode +# Site.cache_sweeper_tracing = true + +# Enable if you want to host multiple sites on this app +# Site.multi_sites_enabled = true + +# shouldn't need to set the host, it's set automatically +UserMailer.default_url_options[:host] = 'localhost:3000' +UserMailer.mail_from = 'webmaster@localhost' + +# defaults to ImageScience, then RMagick, then nothing +# ASSET_IMAGE_PROCESSOR = :image_science || :rmagick || :none + +# OPTIONAL - Redirections +# Deny a route by immediately returning a 404 +# +# Mephisto::Routing.deny 'articles/trackback/*' # return 404 +# +# Specify multiple denied routes: +# +# Mephisto::Routing.deny 'articles/trackback/*', 'monkey/foo/*' +# +# Redirect elsewhere. You can fill in variables marked by ? or * with variable names beginning with : +# +# Redirect /old/foo to /new/foo and /old/foo/bar to /new/foo/bar +# +# Mephisto::Routing.redirect 'old/*' => 'new/$1' +# +# Redirect with a more specific set of variables +# +# Mephisto::Routing.redirect 'article/?/?/?' => 'new/$2/$1/$3' + +# Multiple redirections at a time +# +# Mephisto::Routing.redirect \ +# 'old/*' => 'new/$1', +# 'article/?/?/?' => 'new/$2/$1/$3' \ No newline at end of file diff -Nur mephisto-0.7.3/config/initializers/mephisto_init.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/config/initializers/mephisto_init.rb --- mephisto-0.7.3/config/initializers/mephisto_init.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/config/initializers/mephisto_init.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,44 @@ +# this is for standard library loading and configuration. All the hardcore monkey patching is in the mephisto plugin. +require 'tzinfo' +require 'zip/zipfilesystem' +require 'action_controller/dispatcher' +require 'coderay' +require 'ruby_pants' +require 'xmlrpc_patch' + +ActiveRecord::Base.observers = [:article_observer, :comment_observer] + +# temporarily moved to vendor/plugins/aaa/init.rb to make sure +# it's loaded before all other plugins +# Object::RAILS_PATH = Pathname.new(File.expand_path(RAILS_ROOT)) + +require 'mephisto' + +class ActionController::Dispatcher + def self.register_liquid_tags + Mephisto.liquid_filters.each { |mod| Liquid::Template.register_filter mod } + Mephisto.liquid_tags.each { |name, klass| Liquid::Template.register_tag name, klass } + end + + def cleanup_application_with_plugins(force = false) + returning cleanup_application_without_plugins(force) do + self.class.register_liquid_tags + end + end + + alias_method_chain :cleanup_application, :plugins +end + +ActionController::Dispatcher.register_liquid_tags + +Inflector.inflections do |inflect| + #inflect.plural /^(ox)$/i, '\1en' + #inflect.singular /^(ox)en/i, '\1' + #inflect.irregular 'person', 'people' + inflect.uncountable %w( audio ) +end + +Engines::Plugin::Config.set_table_name 'mephisto_plugins' + +Dependencies.autoloaded_constants.delete "Mephisto" +Dependencies.autoloaded_constants.delete "Mephisto::Plugin" diff -Nur mephisto-0.7.3/config/initializers/metaprogramming.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/config/initializers/metaprogramming.rb --- mephisto-0.7.3/config/initializers/metaprogramming.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/config/initializers/metaprogramming.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,42 @@ +# need to make pathname safe for windows! +Pathname.class_eval do + def read(*args) + returning [] do |s| + File.open(@path, 'rb') { |f| s << f.read } + end.to_s + end +end + +Symbol.class_eval do + def to_liquid + to_s + end +end + +# http://rails.techno-weenie.net/tip/2005/12/23/make_fixtures +ActiveRecord::Base.class_eval do + # person.dom_id #-> "person-5" + # new_person.dom_id #-> "person-new" + # new_person.dom_id(:bare) #-> "new" + # person.dom_id(:person_name) #-> "person-name-5" + def dom_id(prefix=nil) + display_id = new_record? ? "new" : id + prefix ||= self.class.name.underscore + prefix != :bare ? "#{prefix.to_s.dasherize}-#{display_id}" : display_id + end + + # Write a fixture file for testing + def self.to_fixture(fixture_path = nil) + File.open(File.expand_path(fixture_path || "test/fixtures/#{table_name}.yml", RAILS_ROOT), 'w') do |out| + YAML.dump find(:all).inject({}) { |hsh, record| hsh.merge(record.id => record.attributes) }, out + end + end + + expiring_attr_reader :referenced_cache_key, '"[#{[id, self.class.name] * ":"}]"' +end + +class Object + def tap + yield self; self; + end +end \ No newline at end of file diff -Nur mephisto-0.7.3/config/initializers/templating.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/config/initializers/templating.rb --- mephisto-0.7.3/config/initializers/templating.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/config/initializers/templating.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,32 @@ +module Liquid + AllowedVariableCharacters = /[a-zA-Z_.-]/ unless Liquid.const_defined?(:AllowedVariableCharacters) +end + +Liquid::For.send :include, Mephisto::Liquid::ForWithSorting + +WhiteListHelper.tags.merge %w(table tr td) + +class MissingTemplateError < StandardError + attr_reader :template_type, :templates + def initialize(template_type, templates) + @template_type = template_type + @templates = templates + super "No template found for #{template_type}, checked #{templates.to_sentence}." + end +end + +class MissingThemesError < StandardError + attr_reader :site + def initialize(site) + @site = site + super "No themes found in '#{site.theme_path.to_s}/#{site.current_theme_path}'. This must be set correctly in the site settings." + end +end + +class ThemeError < StandardError + attr_reader :theme + def initialize(theme, message) + @theme = theme + super message + end +end \ No newline at end of file diff -Nur mephisto-0.7.3/config/initializers/time_hacks.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/config/initializers/time_hacks.rb --- mephisto-0.7.3/config/initializers/time_hacks.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/config/initializers/time_hacks.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,54 @@ +# Time.now.to_ordinalized_s :long +# => "February 28th, 2006 21:10" +module ActiveSupport::CoreExtensions::Time::Conversions + def to_ordinalized_s(format = :default) + format = ActiveSupport::CoreExtensions::Time::Conversions::DATE_FORMATS[format] + return to_default_s if format.nil? + strftime(format.gsub(/%d/, '_%d_')).gsub(/_(\d+)_/) { |s| s.to_i.ordinalize } + end +end + +ActiveSupport::CoreExtensions::Time::Conversions::DATE_FORMATS.update \ + :standard => '%B %d, %Y @ %I:%M %p', + :stub => '%B %d', + :time_only => '%I:%M %p', + :plain => '%B %d %I:%M %p', + :mdy => '%B %d, %Y', + :my => '%B %Y' + +class Time + class << self + # Used for getting multifield attributes like those generated by a + # select_datetime into a new Time object. For example if you have + # following params={:meetup=>{:"time(1i)=>..."}} just do + # following: + # + # Time.parse_from_attributes(params[:meetup], :time) + def parse_from_attributes(attrs, field, method=:gm) + attrs = attrs.keys.sort.grep(/^#{field.to_s}\(.+\)$/).map { |k| attrs[k] } + attrs.any? ? Time.send(method, *attrs) : nil + end + + def delta(year, month = nil, day = nil) + from = Time.local(year, month || 1, day || 1) + + to = + if !day.blank? + from.advance :days => 1 + elsif !month.blank? + from.advance :months => 1 + else + from.advance :years => 1 + end + return [from.midnight, to.midnight-1] + end + end + + def to_delta(delta_type = :day) + case delta_type + when :year then self.class.delta(year) + when :month then self.class.delta(year, month) + else self.class.delta(year, month, day) + end + end +end \ No newline at end of file diff -Nur mephisto-0.7.3/config/initializers/xml_simple_doctype_fix.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/config/initializers/xml_simple_doctype_fix.rb --- mephisto-0.7.3/config/initializers/xml_simple_doctype_fix.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/config/initializers/xml_simple_doctype_fix.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,2 @@ +# http://tinyurl.com/377j6s +REXML::Document.class_eval { def doctype() nil end } \ No newline at end of file diff -Nur mephisto-0.7.3/db/migrate/033_user_hostile_template_migration.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/db/migrate/033_user_hostile_template_migration.rb --- mephisto-0.7.3/db/migrate/033_user_hostile_template_migration.rb 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/db/migrate/033_user_hostile_template_migration.rb 2008-03-31 02:18:56.000000000 -0400 @@ -5,7 +5,7 @@ class DbFile < ActiveRecord::Base; end class Attachment < ActiveRecord::Base belongs_to :site - acts_as_attachment + has_attachment end class Avatar < Attachment; end class Asset < Attachment; end diff -Nur mephisto-0.7.3/db/migrate/068_moment_of_silence.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/db/migrate/068_moment_of_silence.rb --- mephisto-0.7.3/db/migrate/068_moment_of_silence.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/db/migrate/068_moment_of_silence.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,8 @@ +class MomentOfSilence < ActiveRecord::Migration + def self.up + # makes up for migration #68 in the stable branch, which is the same as #072 on trunk + end + + def self.down + end +end \ No newline at end of file diff -Nur mephisto-0.7.3/db/migrate/069_add_mephisto_plugins.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/db/migrate/069_add_mephisto_plugins.rb --- mephisto-0.7.3/db/migrate/069_add_mephisto_plugins.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/db/migrate/069_add_mephisto_plugins.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,13 @@ +class AddMephistoPlugins < ActiveRecord::Migration + def self.up + create_table :mephisto_plugins do |t| + t.column :name, :string + t.column :options, :text + t.column :type, :string + end + end + + def self.down + drop_table :mephisto_plugins + end +end \ No newline at end of file diff -Nur mephisto-0.7.3/db/migrate/070_remove_site_search_layout.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/db/migrate/070_remove_site_search_layout.rb --- mephisto-0.7.3/db/migrate/070_remove_site_search_layout.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/db/migrate/070_remove_site_search_layout.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,9 @@ +class RemoveSiteSearchLayout < ActiveRecord::Migration + def self.up + remove_column "sites", "search_layout" + end + + def self.down + add_column "sites", "search_layout", :string + end +end diff -Nur mephisto-0.7.3/db/migrate/071_create_assigned_assets.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/db/migrate/071_create_assigned_assets.rb --- mephisto-0.7.3/db/migrate/071_create_assigned_assets.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/db/migrate/071_create_assigned_assets.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,20 @@ +class CreateAssignedAssets < ActiveRecord::Migration + def self.up + create_table :assigned_assets do |t| + t.column :article_id, :integer + t.column :asset_id, :integer + t.column :position, :integer + t.column :label, :string + t.column :created_at, :datetime + t.column :active, :boolean + end + add_column "contents", "assets_count", :integer, :default => 0 + add_column "content_versions", "assets_count", :integer, :default => 0 + end + + def self.down + drop_table :assigned_assets + remove_column "contents", "assets_count" + remove_column "content_versions", "assets_count" + end +end diff -Nur mephisto-0.7.3/db/migrate/072_filter_current_comments.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/db/migrate/072_filter_current_comments.rb --- mephisto-0.7.3/db/migrate/072_filter_current_comments.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/db/migrate/072_filter_current_comments.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,14 @@ +class FilterCurrentComments < ActiveRecord::Migration + def self.up + transaction do + Comment.find(:all).each do |c| + Comment.update_all ['author = ?, author_url = ?, author_email = ?, author_ip = ?, user_agent = ?, referrer = ?', + CGI::escapeHTML(c.author), CGI::escapeHTML(c.author_url), CGI::escapeHTML(c.author_email), CGI::escapeHTML(c.author_ip), + CGI::escapeHTML(c.user_agent), CGI::escapeHTML(c.referrer)], ['id = ?', c.id] + end + end + end + + def self.down + end +end diff -Nur mephisto-0.7.3/db/migrate/073_add_some_indexing_idiot.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/db/migrate/073_add_some_indexing_idiot.rb --- mephisto-0.7.3/db/migrate/073_add_some_indexing_idiot.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/db/migrate/073_add_some_indexing_idiot.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,14 @@ +class AddSomeIndexingIdiot < ActiveRecord::Migration + def self.up + return if indexes(:assigned_sections).any? { |idx| idx.name == 'idx_a_sections_article_section' } + add_index :assigned_sections, [:article_id, :section_id], :name => :idx_a_sections_article_section + add_index :contents, :published_at, :name => :idx_articles_published + add_index :contents, [:article_id, :approved, :type], :name => :idx_comments + end + + def self.down + remove_index :assigned_sections, :name => :idx_a_sections_article_section + remove_index :contents, :name => :idx_articles_published + remove_index :contents, :name => :idx_comments + end +end diff -Nur mephisto-0.7.3/db/migrate/074_remove_orphan_comments.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/db/migrate/074_remove_orphan_comments.rb --- mephisto-0.7.3/db/migrate/074_remove_orphan_comments.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/db/migrate/074_remove_orphan_comments.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,9 @@ +class RemoveOrphanComments < ActiveRecord::Migration + def self.up + article_ids = select_values("SELECT id FROM contents WHERE type = 'Article'") + Comment.delete_all(['article_id NOT IN (?)', article_ids]) + end + + def self.down + end +end diff -Nur mephisto-0.7.3/db/migrate/075_drop_session_table.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/db/migrate/075_drop_session_table.rb --- mephisto-0.7.3/db/migrate/075_drop_session_table.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/db/migrate/075_drop_session_table.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,16 @@ +class DropSessionTable < ActiveRecord::Migration + def self.up + remove_index :sessions, :name => :sessions_session_id_index + drop_table :sessions + end + + def self.down + create_table "sessions", :force => true do |t| + t.string "session_id" + t.text "data" + t.datetime "updated_at" + end + + add_index "sessions", ["session_id"], :name => "sessions_session_id_index" + end +end diff -Nur mephisto-0.7.3/db/schema.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/db/schema.rb --- mephisto-0.7.3/db/schema.rb 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/db/schema.rb 2008-03-31 02:18:56.000000000 -0400 @@ -1,183 +1,212 @@ -# This file is autogenerated. Instead of editing this file, please use the -# migrations feature of ActiveRecord to incrementally modify your database, and +# This file is auto-generated from the current state of the database. Instead of editing this file, +# please use the migrations feature of ActiveRecord to incrementally modify your database, and # then regenerate this schema definition. +# +# Note that this schema.rb definition is the authoritative source for your database schema. If you need +# to create the application database on another system, you should be using db:schema:load, not running +# all the migrations from scratch. The latter is a flawed and unsustainable approach (the more migrations +# you'll amass, the slower it'll run and the greater likelihood for issues). +# +# It's strongly recommended to check this file into your version control system. -ActiveRecord::Schema.define(:version => 67) do +ActiveRecord::Schema.define(:version => 75) do create_table "assets", :force => true do |t| - t.column "content_type", :string - t.column "filename", :string - t.column "size", :integer - t.column "parent_id", :integer - t.column "thumbnail", :string - t.column "width", :integer - t.column "height", :integer - t.column "site_id", :integer - t.column "created_at", :datetime - t.column "title", :string - t.column "thumbnails_count", :integer, :default => 0 - t.column "user_id", :integer + t.string "content_type" + t.string "filename" + t.integer "size" + t.integer "parent_id" + t.string "thumbnail" + t.integer "width" + t.integer "height" + t.integer "site_id" + t.datetime "created_at" + t.string "title" + t.integer "thumbnails_count", :default => 0 + t.integer "user_id" + end + + create_table "assigned_assets", :force => true do |t| + t.integer "article_id" + t.integer "asset_id" + t.integer "position" + t.string "label" + t.datetime "created_at" + t.boolean "active" end create_table "assigned_sections", :force => true do |t| - t.column "article_id", :integer - t.column "section_id", :integer - t.column "position", :integer, :default => 1 + t.integer "article_id" + t.integer "section_id" + t.integer "position", :default => 1 end + add_index "assigned_sections", ["article_id", "section_id"], :name => "idx_a_sections_article_section" + create_table "cached_pages", :force => true do |t| - t.column "url", :string - t.column "references", :text - t.column "updated_at", :datetime - t.column "site_id", :integer - t.column "cleared_at", :datetime + t.string "url" + t.text "references" + t.datetime "updated_at" + t.integer "site_id" + t.datetime "cleared_at" end create_table "content_versions", :force => true do |t| - t.column "content_id", :integer - t.column "version", :integer - t.column "article_id", :integer - t.column "user_id", :integer - t.column "title", :string - t.column "permalink", :string - t.column "excerpt", :text - t.column "body", :text - t.column "excerpt_html", :text - t.column "body_html", :text - t.column "created_at", :datetime - t.column "updated_at", :datetime - t.column "published_at", :datetime - t.column "author", :string, :limit => 100 - t.column "author_url", :string - t.column "author_email", :string - t.column "author_ip", :string, :limit => 100 - t.column "comments_count", :integer, :default => 0 - t.column "updater_id", :integer - t.column "versioned_type", :string, :limit => 20 - t.column "site_id", :integer - t.column "approved", :boolean, :default => false - t.column "comment_age", :integer, :default => 0 - t.column "filter", :string - t.column "user_agent", :string - t.column "referrer", :string + t.integer "content_id" + t.integer "version" + t.integer "article_id" + t.integer "user_id" + t.string "title" + t.string "permalink" + t.text "excerpt" + t.text "body" + t.text "excerpt_html" + t.text "body_html" + t.datetime "created_at" + t.datetime "updated_at" + t.datetime "published_at" + t.string "author", :limit => 100 + t.string "author_url" + t.string "author_email" + t.string "author_ip", :limit => 100 + t.integer "comments_count", :default => 0 + t.integer "updater_id" + t.string "versioned_type", :limit => 20 + t.integer "site_id" + t.boolean "approved", :default => false + t.integer "comment_age", :default => 0 + t.string "filter" + t.string "user_agent" + t.string "referrer" + t.integer "assets_count", :default => 0 end create_table "contents", :force => true do |t| - t.column "article_id", :integer - t.column "user_id", :integer - t.column "title", :string - t.column "permalink", :string - t.column "excerpt", :text - t.column "body", :text - t.column "excerpt_html", :text - t.column "body_html", :text - t.column "created_at", :datetime - t.column "updated_at", :datetime - t.column "published_at", :datetime - t.column "type", :string, :limit => 20 - t.column "author", :string, :limit => 100 - t.column "author_url", :string - t.column "author_email", :string - t.column "author_ip", :string, :limit => 100 - t.column "comments_count", :integer, :default => 0 - t.column "updater_id", :integer - t.column "version", :integer - t.column "site_id", :integer - t.column "approved", :boolean, :default => false - t.column "comment_age", :integer, :default => 0 - t.column "filter", :string - t.column "user_agent", :string - t.column "referrer", :string + t.integer "article_id" + t.integer "user_id" + t.string "title" + t.string "permalink" + t.text "excerpt" + t.text "body" + t.text "excerpt_html" + t.text "body_html" + t.datetime "created_at" + t.datetime "updated_at" + t.datetime "published_at" + t.string "type", :limit => 20 + t.string "author", :limit => 100 + t.string "author_url" + t.string "author_email" + t.string "author_ip", :limit => 100 + t.integer "comments_count", :default => 0 + t.integer "updater_id" + t.integer "version" + t.integer "site_id" + t.boolean "approved", :default => false + t.integer "comment_age", :default => 0 + t.string "filter" + t.string "user_agent" + t.string "referrer" + t.integer "assets_count", :default => 0 end + add_index "contents", ["published_at"], :name => "idx_articles_published" + add_index "contents", ["article_id", "approved", "type"], :name => "idx_comments" + create_table "events", :force => true do |t| - t.column "mode", :string - t.column "user_id", :integer - t.column "article_id", :integer - t.column "title", :text - t.column "body", :text - t.column "created_at", :datetime - t.column "author", :string, :limit => 100 - t.column "comment_id", :integer - t.column "site_id", :integer + t.string "mode" + t.integer "user_id" + t.integer "article_id" + t.text "title" + t.text "body" + t.datetime "created_at" + t.string "author", :limit => 100 + t.integer "comment_id" + t.integer "site_id" + end + + create_table "feedbacks", :force => true do |t| + t.integer "site_id" + t.string "name" + t.string "email" + t.text "body" + t.string "key" + t.datetime "created_at" end create_table "memberships", :force => true do |t| - t.column "site_id", :integer - t.column "user_id", :integer - t.column "created_at", :datetime - t.column "admin", :boolean, :default => false + t.integer "site_id" + t.integer "user_id" + t.datetime "created_at" + t.boolean "admin", :default => false end - create_table "sections", :force => true do |t| - t.column "name", :string - t.column "show_paged_articles", :boolean, :default => false - t.column "articles_per_page", :integer, :default => 15 - t.column "layout", :string - t.column "template", :string - t.column "site_id", :integer - t.column "path", :string - t.column "articles_count", :integer, :default => 0 - t.column "archive_path", :string - t.column "archive_template", :string - t.column "position", :integer, :default => 1 - end - - create_table "sessions", :force => true do |t| - t.column "session_id", :string - t.column "data", :text - t.column "updated_at", :datetime + create_table "mephisto_plugins", :force => true do |t| + t.string "name" + t.text "options" + t.string "type" end - add_index "sessions", ["session_id"], :name => "sessions_session_id_index" + create_table "sections", :force => true do |t| + t.string "name" + t.boolean "show_paged_articles", :default => false + t.integer "articles_per_page", :default => 15 + t.string "layout" + t.string "template" + t.integer "site_id" + t.string "path" + t.integer "articles_count", :default => 0 + t.string "archive_path" + t.string "archive_template" + t.integer "position", :default => 1 + end create_table "sites", :force => true do |t| - t.column "title", :string - t.column "subtitle", :string - t.column "email", :string - t.column "ping_urls", :text - t.column "articles_per_page", :integer, :default => 15 - t.column "host", :string - t.column "akismet_key", :string, :limit => 100 - t.column "akismet_url", :string - t.column "approve_comments", :boolean - t.column "comment_age", :integer - t.column "timezone", :string - t.column "filter", :string - t.column "permalink_style", :string - t.column "search_path", :string - t.column "tag_path", :string - t.column "search_layout", :string - t.column "tag_layout", :string - t.column "current_theme_path", :string + t.string "title" + t.string "subtitle" + t.string "email" + t.text "ping_urls" + t.integer "articles_per_page", :default => 15 + t.string "host" + t.boolean "approve_comments" + t.integer "comment_age" + t.string "timezone" + t.string "filter" + t.string "permalink_style" + t.string "search_path" + t.string "tag_path" + t.string "tag_layout" + t.string "current_theme_path" + t.string "akismet_key", :limit => 100 + t.string "akismet_url" end add_index "sites", ["host"], :name => "index_sites_on_host" create_table "taggings", :force => true do |t| - t.column "tag_id", :integer - t.column "taggable_id", :integer - t.column "taggable_type", :string + t.integer "tag_id" + t.integer "taggable_id" + t.string "taggable_type" end create_table "tags", :force => true do |t| - t.column "name", :string + t.string "name" end create_table "users", :force => true do |t| - t.column "login", :string, :limit => 40 - t.column "email", :string, :limit => 100 - t.column "crypted_password", :string, :limit => 40 - t.column "salt", :string, :limit => 40 - t.column "activation_code", :string, :limit => 40 - t.column "activated_at", :datetime - t.column "created_at", :datetime - t.column "updated_at", :datetime - t.column "deleted_at", :datetime - t.column "token", :string - t.column "token_expires_at", :datetime - t.column "filter", :string - t.column "admin", :boolean, :default => false + t.string "login", :limit => 40 + t.string "email", :limit => 100 + t.string "crypted_password", :limit => 40 + t.string "salt", :limit => 40 + t.string "activation_code", :limit => 40 + t.datetime "activated_at" + t.datetime "created_at" + t.datetime "updated_at" + t.datetime "deleted_at" + t.string "token" + t.datetime "token_expires_at" + t.string "filter" + t.boolean "admin", :default => false end end diff -Nur mephisto-0.7.3/lib/authenticated_system.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/lib/authenticated_system.rb --- mephisto-0.7.3/lib/authenticated_system.rb 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/lib/authenticated_system.rb 2008-03-31 02:18:56.000000000 -0400 @@ -51,7 +51,7 @@ # move to the last store_location call or to the passed default one def redirect_back_or_default(default) - location_stored? ? redirect_to_url(session[:return_to]) : redirect_to(default) + redirect_to(location_stored? ? session[:return_to] : default) session[:return_to] = nil end diff -Nur mephisto-0.7.3/lib/format.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/lib/format.rb --- mephisto-0.7.3/lib/format.rb 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/lib/format.rb 2008-03-31 02:18:56.000000000 -0400 @@ -1,5 +1,6 @@ module Format - DOMAIN = /^([a-z0-9]([-a-z0-9]*[a-z0-9])?\.)+((a[cdefgilmnoqrstuwxz]|aero|arpa)|(b[abdefghijmnorstvwyz]|biz)|(c[acdfghiklmnorsuvxyz]|cat|com|coop)|d[ejkmoz]|(e[ceghrstu]|edu)|f[ijkmor]|(g[abdefghilmnpqrstuwy]|gov)|h[kmnrtu]|(i[delmnoqrst]|info|int)|(j[emop]|jobs)|k[eghimnprwyz]|l[abcikrstuvy]|(m[acdghklmnopqrstuvwxyz]|mil|mobi|museum)|(n[acefgilopruz]|name|net)|(om|org)|(p[aefghklmnrstwy]|pro)|qa|r[eouw]|s[abcdeghijklmnortvyz]|(t[cdfghjklmnoprtvwz]|travel)|u[agkmsyz]|v[aceginu]|w[fs]|y[etu]|z[amw])$/ unless const_defined?(:DOMAIN) + # yes this is valid ruby, even if textmate's highlighter can't grok it + DOMAIN = /^([a-z0-9]([-a-z0-9]*[a-z0-9])?\.)+((a[cdefgilmnoqrstuwxz]|aero|arpa)|(b[abdefghijmnorstvwyz]|biz)|(c[acdfghiklmnorsuvxyz]|cat|com|coop)|d[ejkmoz]|(e[ceghrstu]|edu)|f[ijkmor]|(g[abdefghilmnpqrstuwy]|gov)|(h[kmnrtu]#{RAILS_ENV=='test'?'|host':''})|(i[delmnoqrst]|info|int)|(j[emop]|jobs)|k[eghimnprwyz]|l[abcikrstuvy]|(m[acdghklmnopqrstuvwxyz]|mil|mobi|museum)|(n[acefgilopruz]|name|net)|(om|org)|(p[aefghklmnrstwy]|pro)|qa|r[eouw]|s[abcdeghijklmnortvyz]|(t[cdfghjklmnoprtvwz]|travel)|u[agkmsyz]|v[aceginu]|w[fs]|y[etu]|z[amw])$/ unless const_defined?(:DOMAIN) STRING = /^[a-z0-9-]+$/ EMAIL = /(\A(\s*)\Z)|(\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z)/i end \ No newline at end of file diff -Nur mephisto-0.7.3/lib/mephisto/directory_plugin.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/lib/mephisto/directory_plugin.rb --- mephisto-0.7.3/lib/mephisto/directory_plugin.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/lib/mephisto/directory_plugin.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,26 @@ +# Object model of a plugin in plugins/vendor. May or may not have an internal Mephisto::Plugins::Plugin (an AR). +module Mephisto + class DirectoryPlugin + @@filter = /^mephisto_(\w+)$/ + attr_accessor :plugin, :path + + def self.scan + Dir.new("#{RAILS_ROOT}/vendor/plugins/").collect do |entry| + # don't list "invisible" plugins nor directories/files hidden on the filesystem + entry =~ @@filter ? new($1) : nil + end.compact + end + + def initialize(path) + @path = path + end + + def klass + @klass ||= Mephisto::Plugin[@path] rescue :false + end + + def configurable? + klass != :false + end + end +end \ No newline at end of file diff -Nur mephisto-0.7.3/lib/mephisto/dispatcher.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/lib/mephisto/dispatcher.rb --- mephisto-0.7.3/lib/mephisto/dispatcher.rb 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/lib/mephisto/dispatcher.rb 2008-03-31 02:18:56.000000000 -0400 @@ -112,8 +112,8 @@ old_published = article.published_at article.published_at ||= Time.now.utc article.article_id ||= article.id - permalink_style.split('/').inject [''] do |s, piece| - s << ((name = variable_format?(piece)) && PERMALINK_OPTIONS.keys.include?(name.to_sym) ? variable_value_for(article, name) : piece) + '/' + permalink_style.split('/').collect! do |piece| + (name = variable_format?(piece)) && PERMALINK_OPTIONS.keys.include?(name.to_sym) ? variable_value_for(article, name) : piece end.join('/') ensure article.published_at = old_published diff -Nur mephisto-0.7.3/lib/mephisto/liquid/comment_form.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/lib/mephisto/liquid/comment_form.rb --- mephisto-0.7.3/lib/mephisto/liquid/comment_form.rb 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/lib/mephisto/liquid/comment_form.rb 2008-03-31 02:18:56.000000000 -0400 @@ -1,10 +1,18 @@ module Mephisto module Liquid class CommentForm < ::Liquid::Block - cattr_accessor :article + def self.article + Thread.current[:comment_form_article] + end + + def self.article=(value) + Thread.current[:comment_form_article] = value + end + # Provides the required input, error, and form fields + # TODO: make this more accessible to users (let them mess it up, rather than forcing a structure on them) def render(context) - return '' unless article.accept_comments? + return '' unless self.class.article.accept_comments? result = [] context.stack do if context['message'].blank? diff -Nur mephisto-0.7.3/lib/mephisto/liquid/for_with_sorting.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/lib/mephisto/liquid/for_with_sorting.rb --- mephisto-0.7.3/lib/mephisto/liquid/for_with_sorting.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/lib/mephisto/liquid/for_with_sorting.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,26 @@ +module Mephisto + module Liquid + module ForWithSorting + def self.included(base) + base.alias_method_chain :render, :sorting + end + + def render_with_sorting(context) + context.registers[:for] ||= Hash.new(0) + + collection = context[@collection_name] + collection = collection.to_a if collection.is_a?(Range) + + return '' if collection.nil? or collection.empty? + + if @attributes['sort_by'] + sorted_name = "sorted_#{@collection_name.tr '.', '_'}" + context[sorted_name] = collection.sort_by { |i| i[@attributes['sort_by']] } + @collection_name = sorted_name + end + + render_without_sorting(context) + end + end + end +end \ No newline at end of file diff -Nur mephisto-0.7.3/lib/mephisto/liquid/liquid_template.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/lib/mephisto/liquid/liquid_template.rb --- mephisto-0.7.3/lib/mephisto/liquid/liquid_template.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/lib/mephisto/liquid/liquid_template.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,33 @@ +module Mephisto + module Liquid + class LiquidTemplate + + def initialize(site) + @site = site + end + + def render(section, layout, template, assigns ={}, controller = nil) + parse_inner_template(template, assigns, controller) + parse_template(layout, assigns, controller) + end + + def parse_template(template, assigns, controller) + # give the include tag access to files in the site's fragments directory + ::Liquid::Template.file_system = ::Liquid::LocalFileSystem.new(File.join(@site.theme.path, 'templates')) + tmpl = ::Liquid::Template.parse(template.read.to_s) + returning tmpl.render(assigns, :registers => {:controller => controller}) do |result| + yield tmpl, result if block_given? + end + end + + def parse_inner_template(template, assigns, controller) + parse_template(template, assigns, controller) do |tmpl, result| + # Liquid::Template takes a copy of the assigns. + # merge any new values in to the assigns and pass them to the layout + tmpl.assigns.each { |k, v| assigns[k] = v } if tmpl.respond_to?(:assigns) + assigns['content_for_layout'] = result + end + end + end + end +end diff -Nur mephisto-0.7.3/lib/mephisto/liquid/url_methods.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/lib/mephisto/liquid/url_methods.rb --- mephisto-0.7.3/lib/mephisto/liquid/url_methods.rb 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/lib/mephisto/liquid/url_methods.rb 2008-03-31 02:18:56.000000000 -0400 @@ -12,8 +12,10 @@ def absolute_url(*path) return "#{relative_url_root}/" if path.empty? + is_absolute = path.first.to_s[/(^\/)/] path.collect! { |p| p.to_s.gsub /(^\/)|(\/$)/, '' } - path.empty? ? "#{relative_url_root}/" : path.unshift(relative_url_root).join('/') + path.unshift(is_absolute ? '' : relative_url_root) + path * '/' end end end diff -Nur mephisto-0.7.3/lib/mephisto/plugin.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/lib/mephisto/plugin.rb --- mephisto-0.7.3/lib/mephisto/plugin.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/lib/mephisto/plugin.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,58 @@ +require File.join(File.dirname(__FILE__), 'plugin_about_patch') + +# needs to be loaded before or at beginning of plugin init stage because it +# allows to use add_tab and add_admin_tab from plugin init.rb + +module Mephisto + def self.plugins + @@plugins ||= Engines::Plugin::List.new Engines.plugins.select{ |plugin| plugin.mephisto_plugin? } + end + + module Plugin + @@tabs = [] + @@admin_tabs = [] + mattr_reader :tabs, :admin_tabs + + # delegate read access to about info + %w(author homepage version notes).each do |property| + module_eval "def #{property}; about['#{property}'] end", __FILE__, __LINE__ + end + + # Keeps track of custom adminstration tabs. Each item is an array of arguments to be passed to link_to. + def add_tab(*args) + args.push(:controller => args.first.to_s.downcase) if (args.size == 1) + Mephisto::Plugin.tabs << args + end + + # Keeps track of custom adminstration tabs for ADMIN users only. Each item is an array of arguments to be passed to link_to. + def add_admin_tab(*args) + args.push(:controller => args.first.to_s.downcase) if (args.size == 1) + Mephisto::Plugin.admin_tabs << args + end + + def mephisto_plugin? + name =~ /^mephisto_(\w+)$/ + end + + def configurable? + not default_options.empty? + end + + def mephisto_name + name.sub /^mephisto_/, '' + end + alias :conf_name :mephisto_name + end +end + +Engines::Plugin.send :include, Mephisto::Plugin + +module Engines + class Plugin < Rails::Plugin + protected + # override engine default list for Mephisto plugins + def default_code_paths + %w(app/controllers app/helpers app/models app/drops components lib) + end + end +end \ No newline at end of file diff -Nur mephisto-0.7.3/lib/mephisto/plugin_about_patch.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/lib/mephisto/plugin_about_patch.rb --- mephisto-0.7.3/lib/mephisto/plugin_about_patch.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/lib/mephisto/plugin_about_patch.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,26 @@ +# separately patching Rails::Plugin assuming that this patch will be accepted: +# http://dev.rubyonrails.org/ticket/10979 + +unless Rails::Plugin.respond_to?(:directory) + Rails::Plugin.class_eval do + attr_reader :directory, :name, :about + + alias :initialize_without_about_info :initialize + def initialize(directory) + initialize_without_about_info(directory) + load_about_information + end + + private + + def load_about_information + begin + about_yml_path = File.join(@directory, "about.yml") + parsed_yml = File.exist?(about_yml_path) ? YAML.load(File.read(about_yml_path)) : {} + @about = parsed_yml || {} + rescue Exception + @about = {} + end + end + end +end \ No newline at end of file diff -Nur mephisto-0.7.3/lib/mephisto/plugins.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/lib/mephisto/plugins.rb --- mephisto-0.7.3/lib/mephisto/plugins.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/lib/mephisto/plugins.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,5 @@ +# Empty module to hold plugin models +module Mephisto + module Plugins + end +end \ No newline at end of file diff -Nur mephisto-0.7.3/lib/mephisto/routing.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/lib/mephisto/routing.rb --- mephisto-0.7.3/lib/mephisto/routing.rb 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/lib/mephisto/routing.rb 2008-03-31 02:18:56.000000000 -0400 @@ -1,5 +1,10 @@ module Mephisto class Routing + # Adds Mephisto routes. Yield a given block to allow custom routes. + # + # Mephisto::Routing.connect_with map do + # map.foo ... + # end def self.connect_with(map) map.feed 'feed/*sections', :controller => 'feed', :action => 'feed' @@ -9,22 +14,38 @@ m.js 'javascripts/:path.:ext', :dir => 'javascripts' m.images 'images/:path.:ext', :dir => 'images' end - + + map.moderate 'admin/articles/comments', :controller => 'admin/comments', :action => 'index' + map.purge 'admin/articles/comments/purge', :controller => 'admin/comments', :action => 'destroy' + + map.resources :articles, :path_prefix => 'admin', :controller => 'admin/articles' do |r| + r.resources :comments, :controller => 'admin/comments', :member => { :unapprove => :post, :approve => :post, :edit => :get, :preview => :post } + end + map.overview 'admin/overview.xml', :controller => 'admin/overview', :action => 'feed' map.admin 'admin', :controller => 'admin/overview', :action => 'index' map.resources :assets, :path_prefix => '/admin', :controller => 'admin/assets', :member => { :add_bucket => :post }, :collection => { :latest => :post, :search => :post, :upload => :post, :clear_bucket => :post } - map.connect 'xmlrpc', :controller => 'backend', :action => 'xmlrpc' + # Where oh where is my xmlrpc code? + # map.connect 'xmlrpc', :controller => 'backend', :action => 'xmlrpc' - map.connect ':controller/:action/:id/:version', :version => nil, :controller => /routing_navigator|account|(admin\/\w+)/ + map_from_plugins(map) + + map.connect ':controller/:action/:id/:version', :version => nil, :controller => /routing_navigator|account|(admin\/\w+)/, :id => /[^\/]*/ + + yield if block_given? map.dispatch '*path', :controller => 'mephisto', :action => 'dispatch' map.home '', :controller => 'mephisto', :action => 'dispatch' end - def self.redirections - @redirections ||= {} + class << self + expiring_attr_reader :redirections, '{}' + end + + def self.map_from_plugins(map) + Engines.plugins.each { |plugin| map.from_plugin(plugin.name) } end def self.deny(*paths) @@ -53,8 +74,9 @@ end protected + @@sanitize_path_regex = /^(\/)|(https?:\/\/)/ def self.sanitize_path(path) - path =~ /^(\/)|(https?:\/\/)/ ? path : "/#{path.split("://").last}" + path =~ @@sanitize_path_regex ? path : "/#{path.split("://").last}" end def self.convert_redirection_to_regex(path) diff -Nur mephisto-0.7.3/lib/mephisto/version.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/lib/mephisto/version.rb --- mephisto-0.7.3/lib/mephisto/version.rb 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/lib/mephisto/version.rb 2008-03-31 02:18:56.000000000 -0400 @@ -1,9 +1,9 @@ module Mephisto module Version MAJOR = 0 - MINOR = 7 - TINY = 3 + MINOR = 8 + TINY = 0 STRING = [MAJOR, MINOR, TINY].join('.').freeze - TITLE = "Noh-Varr".freeze + TITLE = "Drax".freeze end end \ No newline at end of file diff -Nur mephisto-0.7.3/lib/mephisto.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/lib/mephisto.rb --- mephisto-0.7.3/lib/mephisto.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/lib/mephisto.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,5 @@ +module Mephisto + @@liquid_filters = [CoreFilters, DropFilters, UrlFilters] + @@liquid_tags = {:textile => Mephisto::Liquid::Textile, :commentform => Mephisto::Liquid::CommentForm, :head => Mephisto::Liquid::Head} + mattr_reader :liquid_tags, :liquid_filters +end \ No newline at end of file diff -Nur mephisto-0.7.3/lib/mephisto_init.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/lib/mephisto_init.rb --- mephisto-0.7.3/lib/mephisto_init.rb 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/lib/mephisto_init.rb 1969-12-31 19:00:00.000000000 -0500 @@ -1,148 +0,0 @@ -require 'tzinfo' -require 'zip/zipfilesystem' -require 'dispatcher' -require 'coderay' -require 'ruby_pants' -require 'xmlrpc_patch' - -RAILS_PATH = Pathname.new(File.expand_path(RAILS_ROOT)) - -ActiveRecord::Base.observers = [:article_observer, :comment_observer] - -Inflector.inflections do |inflect| - #inflect.plural /^(ox)$/i, '\1en' - #inflect.singular /^(ox)en/i, '\1' - #inflect.irregular 'person', 'people' - inflect.uncountable %w( audio ) -end - -class << Dispatcher - def register_liquid_tags - [CoreFilters, DropFilters, UrlFilters].each { |f| Liquid::Template.register_filter f } - Liquid::Template.register_tag(:textile, Mephisto::Liquid::Textile) - Liquid::Template.register_tag(:commentform, Mephisto::Liquid::CommentForm) - Liquid::Template.register_tag(:head, Mephisto::Liquid::Head) - end - - def reset_application_with_plugins! - returning reset_application_without_plugins! do - register_liquid_tags - end - end - - alias_method_chain :reset_application!, :plugins -end - -Dispatcher.register_liquid_tags -# http://rails.techno-weenie.net/tip/2005/12/23/make_fixtures -ActiveRecord::Base.class_eval do - # person.dom_id #-> "person-5" - # new_person.dom_id #-> "person-new" - # new_person.dom_id(:bare) #-> "new" - # person.dom_id(:person_name) #-> "person-name-5" - def dom_id(prefix=nil) - display_id = new_record? ? "new" : id - prefix ||= self.class.name.underscore - prefix != :bare ? "#{prefix.to_s.dasherize}-#{display_id}" : display_id - end - - # Write a fixture file for testing - def self.to_fixture(fixture_path = nil) - File.open(File.expand_path(fixture_path || "test/fixtures/#{table_name}.yml", RAILS_ROOT), 'w') do |out| - YAML.dump find(:all).inject({}) { |hsh, record| hsh.merge(record.id => record.attributes) }, out - end - end - - def referenced_cache_key - "[#{[id, self.class.name] * ':'}]" - end -end - -ActiveSupport::CoreExtensions::Time::Conversions::DATE_FORMATS.update \ - :standard => '%B %d, %Y @ %I:%M %p', - :stub => '%B %d', # XXX what is the meaning of stub in this context? (Basically it means short) - :time_only => '%I:%M %p', - :plain => '%B %d %I:%M %p', - :mdy => '%B %d, %Y', - :my => '%B %Y' - -# Time.now.to_ordinalized_s :long -# => "February 28th, 2006 21:10" -module ActiveSupport::CoreExtensions::Time::Conversions - def to_ordinalized_s(format = :default) - format = ActiveSupport::CoreExtensions::Time::Conversions::DATE_FORMATS[format] - return to_default_s if format.nil? - strftime(format.gsub(/%d/, '_%d_')).gsub(/_(\d+)_/) { |s| s.to_i.ordinalize } - end -end - -class Time - class << self - # Used for getting multifield attributes like those generated by a - # select_datetime into a new Time object. For example if you have - # following params={:meetup=>{:"time(1i)=>..."}} just do - # following: - # - # Time.parse_from_attributes(params[:meetup], :time) - def parse_from_attributes(attrs, field, method=:gm) - attrs = attrs.keys.sort.grep(/^#{field.to_s}\(.+\)$/).map { |k| attrs[k] } - attrs.any? ? Time.send(method, *attrs) : nil - end - end - - def to_delta(delta_type = :day) - case delta_type - when :year then self.class.delta(year) - when :month then self.class.delta(year, month) - else self.class.delta(year, month, day) - end - end - - def self.delta(year, month = nil, day = nil) - from = Time.local(year, month || 1, day || 1) - - to = - if !day.blank? - from.advance :days => 1 - elsif !month.blank? - from.advance :months => 1 - else - from.advance :years => 1 - end - return [from.midnight, to.midnight-1] - end -end - -# need to make pathname safe for windows! -Pathname.class_eval do - def read(*args) - returning '' do |s| - File.open @path, 'rb' do |f| - s << f.read - end - end - end -end - -class MissingTemplateError < StandardError - attr_reader :template_type, :templates - def initialize(template_type, templates) - @template_type = template_type - @templates = templates - super "No template found for #{template_type}, checked #{templates.to_sentence}." - end -end - -class ThemeError < StandardError - attr_reader :theme - def initialize(theme, message) - @theme = theme - super message - end -end - -Symbol.class_eval do - def to_liquid - to_s - end -end \ No newline at end of file diff -Nur mephisto-0.7.3/lib/tasks/bootstrap.rake technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/lib/tasks/bootstrap.rake --- mephisto-0.7.3/lib/tasks/bootstrap.rake 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/lib/tasks/bootstrap.rake 2008-03-31 02:18:56.000000000 -0400 @@ -1,7 +1,7 @@ SITE_DIR = File.join(RAILS_ROOT, 'themes/site-' + (ENV['SITE_ID'] || '1')) namespace :db do desc "Loads a schema.rb file into the database and then loads the initial database fixtures." - task :bootstrap do + task :bootstrap do |task_args| mkdir_p File.join(RAILS_ROOT, 'log') require 'rubygems' unless Object.const_defined?(:Gem) @@ -25,11 +25,11 @@ raise end - %w(environment db:schema:load db:bootstrap:load tmp:create).each { |t| Rake::Task[t].execute } + %w(environment db:schema:load db:bootstrap:load tmp:create).each { |t| Rake::Task[t].execute task_args} if File.exists?(SITE_DIR) puts "skipping default theme creation..." else - Rake::Task["db:bootstrap:copy_default_theme"].execute + Rake::Task["db:bootstrap:copy_default_theme"].execute task_args puts "copied default theme to #{SITE_DIR}..." end diff -Nur mephisto-0.7.3/lib/tasks/common.rake technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/lib/tasks/common.rake --- mephisto-0.7.3/lib/tasks/common.rake 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/lib/tasks/common.rake 2008-03-31 02:18:56.000000000 -0400 @@ -2,6 +2,7 @@ task :deploy_edge do ENV['SHARED_PATH'] = '../../shared' unless ENV['SHARED_PATH'] ENV['RAILS_PATH'] ||= File.join(ENV['SHARED_PATH'], 'rails') + ENV['REPO_BRANCH'] ||= 'trunk' checkout_path = File.join(ENV['RAILS_PATH'], 'trunk') export_path = "#{ENV['RAILS_PATH']}/rev_#{ENV['REVISION']}" @@ -11,7 +12,7 @@ unless File.exists?(checkout_path) puts 'setting up rails trunk' get_framework_for checkout_path do |framework| - system "svn co http://dev.rubyonrails.org/svn/rails/trunk/#{framework}/lib #{checkout_path}/#{framework}/lib --quiet" + system "svn co http://dev.rubyonrails.org/svn/rails/#{ENV['REPO_BRANCH']}/#{framework}/lib #{checkout_path}/#{framework}/lib --quiet" end end diff -Nur mephisto-0.7.3/lib/tasks/switchtower.rake technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/lib/tasks/switchtower.rake --- mephisto-0.7.3/lib/tasks/switchtower.rake 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/lib/tasks/switchtower.rake 1969-12-31 19:00:00.000000000 -0500 @@ -1,33 +0,0 @@ -# ============================================================================= -# A set of rake tasks for invoking the SwitchTower automation utility. -# ============================================================================= - -desc "Push the latest revision into production using the release manager" -task :deploy do - system "switchtower -vvvv -r config/deploy -a deploy" -end - -desc "Rollback to the release before the current release in production" -task :rollback do - system "switchtower -vvvv -r config/deploy -a rollback" -end - -desc "Describe the differences between HEAD and the last production release" -task :diff_from_last_deploy do - system "switchtower -vvvv -r config/deploy -a diff_from_last_deploy" -end - -desc "Enumerate all available deployment tasks" -task :show_deploy_tasks do - system "switchtower -r config/deploy -a show_tasks" -end - -desc "Execute a specific action using the release manager" -task :remote_exec do - unless ENV['ACTION'] - raise "Please specify an action (or comma separated list of actions) via the ACTION environment variable" - end - - actions = ENV['ACTION'].split(",").map { |a| "-a #{a}" }.join(" ") - system "switchtower -vvvv -r config/deploy #{actions}" -end diff -Nur mephisto-0.7.3/public/.htaccess technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/public/.htaccess --- mephisto-0.7.3/public/.htaccess 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/public/.htaccess 1969-12-31 19:00:00.000000000 -0500 @@ -1,40 +0,0 @@ -# General Apache options -AddHandler fastcgi-script .fcgi -AddHandler cgi-script .cgi -Options +FollowSymLinks +ExecCGI - -# If you don't want Rails to look in certain directories, -# use the following rewrite rules so that Apache won't rewrite certain requests -# -# Example: -# RewriteCond %{REQUEST_URI} ^/notrails.* -# RewriteRule .* - [L] - -# Redirect all requests not available on the filesystem to Rails -# By default the cgi dispatcher is used which is very slow -# -# For better performance replace the dispatcher with the fastcgi one -# -# Example: -# RewriteRule ^(.*)$ dispatch.fcgi [QSA,L] -RewriteEngine On - -# If your Rails application is accessed via an Alias directive, -# then you MUST also set the RewriteBase in this htaccess file. -# -# Example: -# Alias /myrailsapp /path/to/myrailsapp/public -# RewriteBase /myrailsapp - -RewriteRule ^$ index.html [QSA] -RewriteRule ^([^.]+)$ $1.html [QSA] -RewriteCond %{REQUEST_FILENAME} !-f -RewriteRule ^(.*)$ dispatch.cgi [QSA,L] - -# In case Rails experiences terminal errors -# Instead of displaying this message you can supply a file here which will be rendered instead -# -# Example: -# ErrorDocument 500 /500.html - -ErrorDocument 500 "

      Application error

      Rails application failed to start properly" diff -Nur mephisto-0.7.3/public/install.html technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/public/install.html --- mephisto-0.7.3/public/install.html 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/public/install.html 2008-03-31 02:18:56.000000000 -0400 @@ -1,87 +1,87 @@ + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> - - - Installing Mephisto - - - - - - + \ No newline at end of file diff -Nur mephisto-0.7.3/public/javascripts/mephisto/application.js technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/public/javascripts/mephisto/application.js --- mephisto-0.7.3/public/javascripts/mephisto/application.js 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/public/javascripts/mephisto/application.js 2008-03-31 02:18:56.000000000 -0400 @@ -206,9 +206,9 @@ Asset = { upload: function(form) { form = $(form); - article_id = location.href.match(/\/edit\/([0-9]+)/); + article_id = location.href.match(/\/(edit|upload)\/([0-9]+)/); form.action = Mephisto.root + "/admin/articles/upload" - if(article_id) form.action += "/" + article_id[1] + if(article_id) form.action += "/" + article_id[2] form.submit(); }, @@ -295,11 +295,36 @@ getAvailableComments: function() { return $$('ul.commentlist li').reject(function(div) { return !(div.visible() && !div.hasClassName('disabled') && div.id.match(/^comment-/)); }).collect(function(div) { return div.id.match(/comment-(\d+)/)[1] }); }, - + + attachAsset: function(assetId) { + var articleId = location.href.match(/\/([0-9]+)\/(edit|upload)/)[1]; + var attached = $('attached-widget-' + assetId); + if(attached) return; + new Ajax.Request('/admin/articles/attach/' + articleId + '/' + assetId); + $$('.widget').each(function(asset) { if(assetId == asset.getAttribute('id').match(/-(\d+)$/)[1]) asset.addClassName('selected-widget'); }); + }, + + labelAsset: function(assetId) { + var articleId = location.href.match(/\/([0-9]+)\/(edit|upload)/)[1]; + var attached = $('attached-widget-' + assetId); + var label = $('attached-widget-version-' + assetId); + new Ajax.Request('/admin/articles/label/' + articleId + '/' + assetId + '?label=' + escape(label.value)); + if(attached) return; + }, + + detachAsset: function(assetId) { + var articleId = location.href.match(/\/([0-9]+)\/(edit|upload)/)[1]; + var attached = $('attached-widget-' + assetId); + if(!attached) return; + new Ajax.Request('/admin/articles/detach/' + articleId + '/' + assetId); + new Effect.DropOut(attached, {afterFinish: function() { attached.remove(); }}); + $$('.widget').each(function(asset) { if(assetId == asset.getAttribute('id').match(/-(\d+)$/)[1]) asset.removeClassName('selected-widget'); }); + }, + getRevision: function() { var rev = $F(this) - var url = Mephisto.root + '/admin/articles/edit/' + location.href.match(/\/edit\/([0-9]+)/)[1]; - if(rev != '0') url += "/" + rev; + var url = Mephisto.root + '/admin/articles/' + location.href.match(/\/([0-9]+)\/edit/)[1] + "/edit"; + if(rev != '0') url += "?version=" + rev; location.href = url; } } @@ -548,7 +573,37 @@ $('published').value = '0'; $('article-search').submit(); }, + + 'li.widget:mouseover': function() { + var attach = $('attach-' + this.getAttribute('id')); + var detach = $('detach-' + this.getAttribute('id')); + if(attach) attach.show(); + if(detach) detach.show(); + }, + + 'li.widget:mouseout': function() { + var attach = $('attach-' + this.getAttribute('id')); + var detach = $('detach-' + this.getAttribute('id')); + if(attach) attach.hide(); + if(detach) detach.hide(); + }, + '.attach-widget:click': function() { + ArticleForm.attachAsset(this.getAttribute('id').match(/-(\d+)$/)[1]); + return false; + }, + + '.label-widget:click': function() { + ArticleForm.labelAsset(this.getAttribute('id').match(/-(\d+)$/)[1]); + this.innerHTML = 'Saving...' + return false; + }, + + '.detach-widget:click': function() { + ArticleForm.detachAsset(this.getAttribute('id').match(/-(\d+)$/)[1]); + return false; + }, + 'a.theme_dialog:click': function() { var img = this.down('img'); var pieces = img.src.split('/'); diff -Nur mephisto-0.7.3/public/stylesheets/mephisto/mephisto.css technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/public/stylesheets/mephisto/mephisto.css --- mephisto-0.7.3/public/stylesheets/mephisto/mephisto.css 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/public/stylesheets/mephisto/mephisto.css 2008-03-31 02:18:56.000000000 -0400 @@ -1199,6 +1199,14 @@ text-align: center; border-top: 1px solid #ccc; padding: 10px 0; + font-weight:bold; +} + +#main p.total { + margin:-0.3em 0 1.2em 0; + padding: 0.3em 3em; + background: #eee; + text-align:center; } @@ -1305,29 +1313,75 @@ *=ASSET MANAGEMENT */ -#assets, #files, #latest-assets, #bucket-assets, #search-assets { +#assets, #files, ul.asset-list { list-style: none; margin-top: 5px; } -#assets li, #files li, #latest-assets li, #bucket-assets li, #search-assets li { +#assets li, #files li, ul.asset-list li { display: inline; + white-space: no-wrap; margin-left: 5px; margin-bottom: 5px; } -#assets li a img, +#attached-assets li { + display:block; +} + +#attached-assets li div { + position:relative; +} + +#attached-assets li div a { + display:inline; +} + +#attached-assets div input.txt { + width:125px; +} + +#attached-assets div span { + position:absolute; + top:20px; right:8px; +} + +ul.asset-list .widget { + position:relative; +} + +.widget .attach-widget { + z-index:500; + position:absolute; + top:-13px; left:-23px; +} + +.widget .detach-widget { + z-index:500; + position:absolute; + top:-36px; left:-23px; +} + +#attached-assets .widget .attach-widget { + position:absolute; + top:11px; left:-23px; +} + +#attached-assets .widget .detach-widget { + position:absolute; + top:34px; left:-23px; +} + +#assets li a img, #latest-assets li a img, #bucket-assets li a img, -#search-assets li a img { +#search-assets li a img, +ul.asset-list li a img { padding: 4px; background: #fff; } -#assets img, -#latest-assets img, -#bucket-assets img, -#search-assets img { +ul.asset-list img { max-height: 50px; max-width: 50px; padding: 3px; @@ -1335,6 +1389,10 @@ border: 1px solid #8BCACD; } +ul.asset-list .selected-widget img { + border-color:#000; +} + #assets span, #latest-assets span, #bucket-assets span, diff -Nur mephisto-0.7.3/script/spec technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/script/spec --- mephisto-0.7.3/script/spec 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/script/spec 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,4 @@ +#!/usr/bin/env ruby +$LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__) + "/../vendor/plugins/rspec/lib")) +require 'spec' +exit ::Spec::Runner::CommandLine.run(::Spec::Runner::OptionParser.parse(ARGV, STDERR, STDOUT)) diff -Nur mephisto-0.7.3/script/spec_server technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/script/spec_server --- mephisto-0.7.3/script/spec_server 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/script/spec_server 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,99 @@ +#!/usr/bin/env ruby +$LOAD_PATH.unshift File.dirname(__FILE__) + '/../../rspec/lib' # For svn +$LOAD_PATH.unshift File.dirname(__FILE__) + '/../vendor/plugins/rspec/lib' # For rspec installed as plugin +require 'rubygems' +require 'drb/drb' +require 'rbconfig' +require 'spec' +require 'optparse' + +# This is based on Florian Weber's TDDMate +module Spec + module Runner + class RailsSpecServer + def run(argv, stderr, stdout) + $stdout = stdout + $stderr = stderr + + base = ActiveRecord::Base + def base.clear_reloadable_connections! + active_connections.each do |name, conn| + if conn.requires_reloading? + conn.disconnect! + active_connections.delete(name) + end + end + end + + if ::Dispatcher.respond_to?(:cleanup_application) + ::Dispatcher.cleanup_application + elsif ::Dispatcher.respond_to?(:reset_application!) + ::Dispatcher.reset_application! + end + ::Dependencies.mechanism = :load + require_dependency('application.rb') unless Object.const_defined?(:ApplicationController) + load File.dirname(__FILE__) + '/../spec/spec_helper.rb' + + ::Spec::Runner::CommandLine.run( + ::Spec::Runner::OptionParser.parse( + argv, + $stderr, + $stdout + ) + ) + end + end + end +end +puts "Loading Rails environment" + +ENV["RAILS_ENV"] = "test" +require File.expand_path(File.dirname(__FILE__) + "/../config/environment") +require 'dispatcher' + +def restart_test_server + puts "restarting" + config = ::Config::CONFIG + ruby = File::join(config['bindir'], config['ruby_install_name']) + config['EXEEXT'] + command_line = [ruby, $0, ARGV].flatten.join(' ') + exec(command_line) +end + +def daemonize(pid_file = nil) + return yield if $DEBUG + pid = Process.fork{ + Process.setsid + Dir.chdir(RAILS_ROOT) + trap("SIGINT"){ exit! 0 } + trap("SIGTERM"){ exit! 0 } + trap("SIGHUP"){ restart_test_server } + File.open("/dev/null"){|f| + STDERR.reopen f + STDIN.reopen f + STDOUT.reopen f + } + yield + } + puts "spec_server launched. (PID: %d)" % pid + File.open(pid_file,"w"){|f| f.puts pid } if pid_file + exit! 0 +end + +options = Hash.new +opts = OptionParser.new +opts.on("-d", "--daemon"){|v| options[:daemon] = true } +opts.on("-p", "--pid PIDFILE"){|v| options[:pid] = v } +opts.parse!(ARGV) + +puts "Ready" +exec_server = lambda { + trap("USR2") { restart_test_server } if Signal.list.has_key?("USR2") + DRb.start_service("druby://localhost:8989", Spec::Runner::RailsSpecServer.new) + DRb.thread.join +} + +if options[:daemon] + daemonize(options[:pid], &exec_server) +else + exec_server.call +end diff -Nur mephisto-0.7.3/spec/controllers/plugin_routing_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/spec/controllers/plugin_routing_spec.rb --- mephisto-0.7.3/spec/controllers/plugin_routing_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/spec/controllers/plugin_routing_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,18 @@ +# cant get this working with autotest for some reason +# invoking the spec manually will work though + +# require File.join(File.dirname(__FILE__), '/../../config/boot') +# +# Rails::Configuration.send(:define_method, :plugin_paths) do +# ["#{RAILS_ROOT}/vendor/plugins", "#{RAILS_ROOT}/vendor/plugins/engines_config/test/plugins"] +# end +# +# require File.dirname(__FILE__) + '/../spec_helper' +# +# describe "Mephisto::Plugin routing" do +# controller_name 'mephisto' +# +# it "should work" do +# route_for(:controller => "somethings", :action => "index").should == "/something" +# end +# end \ No newline at end of file diff -Nur mephisto-0.7.3/spec/filters/absolute_url_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/spec/filters/absolute_url_spec.rb --- mephisto-0.7.3/spec/filters/absolute_url_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/spec/filters/absolute_url_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,57 @@ +require File.dirname(__FILE__) + '/../spec_helper' + +describe Mephisto::Liquid::UrlMethods, "#absolute_url" do + it "has root absolute url" do + absolute_url.should == '/' + end + + it "joins url pieces" do + absolute_url(:foo).should == '/foo' + absolute_url(:foo, :bar).should == '/foo/bar' + absolute_url(:foo, :bar, 'baz.html').should == '/foo/bar/baz.html' + end + + it "joins relative path" do + absolute_url('foo/bar/baz.html').should == '/foo/bar/baz.html' + end + + it "joins absolute path" do + absolute_url('/foo/bar/baz.html').should == '/foo/bar/baz.html' + end + + it "joins path ending with a slash" do + absolute_url('foo/bar/baz/').should == '/foo/bar/baz' + end +end + +describe Mephisto::Liquid::UrlMethods, "#absolute_url (with custom url root)" do + class << self + attr_accessor :relative_url_root + end + + before do + stub!(:relative_url_root).and_return("/blog") + end + + it "has root absolute url" do + absolute_url.should == '/blog/' + end + + it "joins url pieces" do + absolute_url(:foo).should == '/blog/foo' + absolute_url(:foo, :bar).should == '/blog/foo/bar' + absolute_url(:foo, :bar, 'baz.html').should == '/blog/foo/bar/baz.html' + end + + it "joins relative path" do + absolute_url('foo/bar/baz.html').should == '/blog/foo/bar/baz.html' + end + + it "joins absolute path" do + absolute_url('/foo/bar/baz.html').should == '/foo/bar/baz.html' + end + + it "joins path ending with a slash" do + absolute_url('foo/bar/baz/').should == '/blog/foo/bar/baz' + end +end \ No newline at end of file diff -Nur mephisto-0.7.3/spec/model_stubs.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/spec/model_stubs.rb --- mephisto-0.7.3/spec/model_stubs.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/spec/model_stubs.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,21 @@ +ModelStubbing.define_models do + # only put minimal, core models in here if specs require interaction + # with lots of models + + time 2007, 6, 15 + + model Site do + stub :title => "Mephisto", :host => 'test.host', :filter => 'textile_filter', :approve_comments => false, + :comment_age => 30, :timezone => "America/New_York", :articles_per_page => 15, :permalink_style => ":year/:month/:day/:permalink", + :tag_path => 'tags', :search_path => 'search', :current_theme_path => 'current' + end + + model User do + stub :login => 'quentin', :email => 'quentin@example.com', :filter => 'textile_filter', :token => 'quentintoken', :admin => true, + :salt => '7e3041ebc2fc05a40c60028e2c4901a81035d3cd', :crypted_password => '00742970dc9e6319f8019fd54864d3ea740f04b1' + end + + # model Article do + # stub :title => 'foobar' + # end +end \ No newline at end of file diff -Nur mephisto-0.7.3/spec/models/comment_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/spec/models/comment_spec.rb --- mephisto-0.7.3/spec/models/comment_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/spec/models/comment_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,53 @@ +require File.dirname(__FILE__) + '/../spec_helper' + + +describe Comment, "previewing" do + define_models do + time 2007, 6, 15 + + model Site do + stub :cupcake, :title => "Cupcake", :host => 'cupcake.com' + end + model Article do + stub :welcome, :title => "Welcome!", :body => "Hi there", :filter => "textile_filter", :site => all_stubs(:site), :created_at => current_time - 3.days, :published_at => current_time - 2.days, :comment_age => 0 + end + end + + before do + @comment = Comment.new :author => "1", :author_ip => "127.0.0.1", :body => "No answer" + @comment.article = contents(:welcome) + end + + it "should be valid" do + @comment.should be_valid + end + + it "raises Previewing error when preview accessor is set" do + @comment.preview = true + lambda{ + @comment.save! + }.should raise_error(Comment::Previewing) + end + +end + +describe Comment, "textilizing" do + define_models do + model Site do + stub :cupcake, :title => "Cupcake", :host => 'cupcake.com' + end + model Article do + stub :welcome, :title => "Welcome!", :body => "Hi there", :filter => "textile_filter", :site => all_stubs(:site), :created_at => current_time - 3.days, :published_at => current_time - 2.days, :comment_age => 0 + end + end + + # Copied from tests, in the hope that more people will PDI and convert the test::unit + # tests to RSpec. + it "processes comments with textile, if the article is textile-formatted" do + @comment = Comment.new :author => "1", :author_ip => "127.0.0.1", :body => "*test* comment" + @comment.article = contents(:welcome) + @comment.save + @comment.body_html.should == "

      test comment

      " + end + +end \ No newline at end of file diff -Nur mephisto-0.7.3/spec/models/membership_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/spec/models/membership_spec.rb --- mephisto-0.7.3/spec/models/membership_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/spec/models/membership_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,39 @@ +require File.dirname(__FILE__) + '/../spec_helper' + +describe Membership do + define_models do + model Site do + stub :cupcake, :title => "Cupcake", :host => 'cupcake.com' + end + + model User do + stub :non_admin, :login => 'arthur', :admin => false + stub :deleted, :login => "aaron", :admin => false, :deleted_at => current_time - 5.minutes + end + + model Membership do + stub :admin_on_default, :site => all_stubs(:site), :user => all_stubs(:user), :admin => true + stub :admin_on_cupcake, :site => all_stubs(:cupcake_site), :user => all_stubs(:user), :admin => true + stub :user_on_default, :site => all_stubs(:site), :user => all_stubs(:non_admin_user), :admin => false + stub :deleted_on_default, :site => all_stubs(:site), :user => all_stubs(:deleted_user), :admin => false + end + end + + it "finds user sites" do + users(:default).sites.sort_by { |s| s.title }.should == [sites(:cupcake), sites(:default)] + end + + it "finds site members" do + sites(:default).members.sort_by { |u| u.login }.should == [users(:non_admin), users(:default)] + User.find_all_by_site(sites(:default)).sort_by { |u| u.login }.should == [users(:non_admin), users(:default)] + end + + it "finds site admins" do + sites(:default).admins.should == [users(:default)] + end + + it "finds all users with deleted" do + sites(:default).users_with_deleted.sort_by { |u| u.login }.should == [users(:deleted), users(:non_admin), users(:default)] + User.find_all_by_site_with_deleted(sites(:default)).sort_by { |u| u.login }.should == [users(:deleted), users(:non_admin), users(:default)] + end +end \ No newline at end of file diff -Nur mephisto-0.7.3/spec/models/plugin_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/spec/models/plugin_spec.rb --- mephisto-0.7.3/spec/models/plugin_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/spec/models/plugin_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,41 @@ +# cant get this working with autotest for some reason +# invoking the spec manually will work though + +require File.join(File.dirname(__FILE__), '/../../config/boot') + +Rails::Configuration.send(:define_method, :plugin_paths) do + ["#{RAILS_ROOT}/vendor/plugins", "#{RAILS_ROOT}/vendor/plugins/engines_config/test/plugins"] +end + +require File.dirname(__FILE__) + '/../spec_helper' + +describe Mephisto::Plugin do + def plugin_alpha + Engines.plugins['plugin_alpha'] + end + + it "should filter plugin list and return mephisto plugins" do + Engines.plugins.size.should > Mephisto.plugins.size + end + + it "should be a mephisto plugin when its name starts with 'mephisto_'" do + Mephisto.plugins.each {|p| p.name.should =~ /^mephisto_/ } + end + + it "should be configurable when at least one option is defined" do + plugin_alpha.configurable?.should be_true + Engines.plugins['engines'].configurable?.should be_false + end + + it "should allow to add tabs" do + Mephisto::Plugin.tabs.clear + plugin_alpha.add_tab :something + Mephisto::Plugin.tabs.first.first.should == :something + end + + it "should allow to add admin tabs" do + Mephisto::Plugin.admin_tabs.clear + plugin_alpha.add_admin_tab :something + Mephisto::Plugin.admin_tabs.first.first.should == :something + end +end \ No newline at end of file diff -Nur mephisto-0.7.3/spec/models/site_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/spec/models/site_spec.rb --- mephisto-0.7.3/spec/models/site_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/spec/models/site_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,69 @@ +require File.dirname(__FILE__) + '/../spec_helper' +describe Site do + define_models do + + model Site do + stub :destroy, :host => 'destroy.com' + end + + model User do + stub :destroy, :login => 'destroy' + end + + model Membership do + stub :destroy, :site => all_stubs(:destroy_site), :user => all_stubs(:destroy_user) + end + end + + it "should delete memberships on destruction" do + sites(:destroy).memberships.should == [memberships(:destroy)] + lambda { sites(:destroy).destroy }.should change(Membership, :count).by(-1) + end + +end +require File.dirname(__FILE__) + '/../spec_helper' +describe Site do + define_models do + + model Site do + stub :destroy, :host => 'destroy.com' + end + + model User do + stub :destroy, :login => 'destroy' + end + + model Membership do + stub :destroy, :site => all_stubs(:destroy_site), :user => all_stubs(:destroy_user) + end + end + + it "should delete memberships on destruction" do + sites(:destroy).memberships.should == [memberships(:destroy)] + lambda { sites(:destroy).destroy }.should change(Membership, :count).by(-1) + end + +end +require File.dirname(__FILE__) + '/../spec_helper' +describe Site do + define_models do + + model Site do + stub :destroy, :host => 'destroy.com' + end + + model User do + stub :destroy, :login => 'destroy' + end + + model Membership do + stub :destroy, :site => all_stubs(:destroy_site), :user => all_stubs(:destroy_user) + end + end + + it "should delete memberships on destruction" do + sites(:destroy).memberships.should == [memberships(:destroy)] + lambda { sites(:destroy).destroy }.should change(Membership, :count).by(-1) + end + +end diff -Nur mephisto-0.7.3/spec/models/tag_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/spec/models/tag_spec.rb --- mephisto-0.7.3/spec/models/tag_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/spec/models/tag_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,69 @@ +require File.dirname(__FILE__) + '/../spec_helper' + +ModelStubbing.define_models :tags, :copy => false do + model Tag do + [:ruby, :rails, :mongrel, :plugin].each do |t| + stub t, :name => t.to_s + end + end +end + +describe Tag, "#parse" do + define_models :tags + + it "parses comma separated tags" do + Tag.parse('a,b,c').should == %w(a b c) + Tag.parse('a, b c').should == %w(a b\ c) + end + + it "parses simple tags" do + Tag.parse('"a" "b" "c"').should == %w(a b c) + end + + it "parses space delimited tags" do + Tag.parse('a b c').should == %w(a b c) + end + + it "parses tags with double quotes" do + Tag.parse('tagging, it"s, weirdness').should == %w(tagging it"s weirdness) + end + + it "parses tags with single quotes" do + Tag.parse('"tagging" "it\'s" "weirdness"').should == %w(tagging it's weirdness) + end + + it "parses tags with quotes and spaces" do + Tag.parse('"tagging" "it\'s weirdness"').should == %w(tagging it's\ weirdness) + end + + it "returns tag array" do + Tag.parse(%w(a b c)).should == %w(a b c) + end + + it "returns unique tags" do + ["a, b, b", %("a" "b" " b ")].each do |input| + Tag.parse(input).should == %w(a b) + end + end +end + +describe Tag do + define_models :tags + + it "finds or creates tags" do + lambda { Tag.find_or_create %w(ruby rails foo) }.should change { Tag.count }.by(1) + end + + it "creates tags from comma separated list" do + lambda { Tag.parse_to_tags 'ruby, a, b, rails, c' }.should change { Tag.count }.by(3) + end + + it "equals tags of the same name" do + tags(:ruby).should == 'ruby' + tags(:ruby).should == Tag.new(:name => "ruby") + end + + it "selects tags by name" do + Tag[:ruby].should == tags(:ruby) + end +end diff -Nur mephisto-0.7.3/spec/rcov.opts technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/spec/rcov.opts --- mephisto-0.7.3/spec/rcov.opts 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/spec/rcov.opts 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,2 @@ +--exclude "spec/*,gems/*" +--rails \ No newline at end of file diff -Nur mephisto-0.7.3/spec/spec.opts technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/spec/spec.opts --- mephisto-0.7.3/spec/spec.opts 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/spec/spec.opts 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,7 @@ +--colour +--format +progress +--loadby +mtime +--reverse +--backtrace \ No newline at end of file diff -Nur mephisto-0.7.3/spec/spec_helper.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/spec/spec_helper.rb --- mephisto-0.7.3/spec/spec_helper.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/spec/spec_helper.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,15 @@ +ENV["RAILS_ENV"] = "test" + +require File.expand_path(File.dirname(__FILE__) + "/../config/environment") +require 'spec' +require 'spec/rails' +require 'ruby-debug' +require 'model_stubbing/spec' +require File.join(File.dirname(__FILE__), 'model_stubs') + +Spec::Runner.configure do |config| + config.use_transactional_fixtures = true + config.use_instantiated_fixtures = false +end + +Debugger.start \ No newline at end of file diff -Nur mephisto-0.7.3/stories/all.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/stories/all.rb --- mephisto-0.7.3/stories/all.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/stories/all.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,4 @@ +dir = File.dirname(__FILE__) +Dir[File.expand_path("#{dir}/**/*.rb")].uniq.each do |file| + require file +end \ No newline at end of file diff -Nur mephisto-0.7.3/stories/helper.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/stories/helper.rb --- mephisto-0.7.3/stories/helper.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/stories/helper.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,3 @@ +ENV["RAILS_ENV"] = "test" +require File.expand_path(File.dirname(__FILE__) + "/../config/environment") +require 'spec/rails/story_adapter' \ No newline at end of file diff -Nur mephisto-0.7.3/test/actor.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/test/actor.rb --- mephisto-0.7.3/test/actor.rb 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/test/actor.rb 2008-03-31 02:18:56.000000000 -0400 @@ -51,23 +51,23 @@ end def revise(article, contents) - post "/admin/articles/update/#{article.id}", to_article_params(article, contents.is_a?(Hash) ? contents : {:body => contents}) - assert_redirected_to "/admin/articles/edit/#{assigns(:article).id}" + put "/admin/articles/#{article.id}", to_article_params(article, contents.is_a?(Hash) ? contents : {:body => contents}) + assert_redirected_to "/admin/articles/#{assigns(:article).id}/edit" end def remove_article(article) - post "/admin/articles/destroy/#{article.id}" + delete "/admin/articles/#{article.id}" assert_equal 200, status, "Removing article #{article.id}" end def create(params) - post '/admin/articles/create', to_article_params(params) - assert_redirected_to "/admin/articles/edit/#{assigns(:article).id}" + post '/admin/articles', to_article_params(params) + assert_redirected_to "/admin/articles/#{assigns(:article).id}/edit" end private def manage_comment(action, comment) - post "/admin/articles/#{action}/#{comment.article_id}", :comment => comment.id + post "/admin/articles/#{comment.article_id}/comments/#{comment.id}/#{action}", :comment => comment.id end def to_article_params(*args) diff -Nur mephisto-0.7.3/test/fixtures/assigned_assets.yml technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/test/fixtures/assigned_assets.yml --- mephisto-0.7.3/test/fixtures/assigned_assets.yml 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/test/fixtures/assigned_assets.yml 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,25 @@ +# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html +welcome_gif: + id: 1 + article_id: 1 + asset_id: 1 + position: 1 + label: welcome image + created_at: <%= 2.minutes.ago.to_s :db %> + active: true +welcome_mp3: + id: 2 + article_id: 1 + asset_id: 3 + position: 2 + label: podcast + created_at: <%= 1.minute.ago.to_s :db %> + active: true +welcome_png: + id: 3 + article_id: 1 + asset_id: 2 + position: 3 + label: png + created_at: <%= 90.seconds.ago.to_s :db %> + active: false diff -Nur mephisto-0.7.3/test/fixtures/assigned_sections.yml technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/test/fixtures/assigned_sections.yml --- mephisto-0.7.3/test/fixtures/assigned_sections.yml 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/test/fixtures/assigned_sections.yml 2008-03-31 02:18:56.000000000 -0400 @@ -45,4 +45,24 @@ id: 9 article_id: 11 section_id: 1 - position: 5 \ No newline at end of file + position: 5 +draft_about: + id: 10 + article_id: 11 + section_id: 2 + position: 4 +future_about: + id: 11 + article_id: 5 + section_id: 2 + position: 5 +paged_section_article_1: + id: 12 + article_id: 16 + section_id: 10 + position: 1 +paged_section_article_2: + id: 13 + article_id: 17 + section_id: 10 + position: 2 diff -Nur mephisto-0.7.3/test/fixtures/contents.yml technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/test/fixtures/contents.yml --- mephisto-0.7.3/test/fixtures/contents.yml 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/test/fixtures/contents.yml 2008-03-31 02:18:56.000000000 -0400 @@ -43,8 +43,8 @@ article_id: 1 title: Welcome to Mephisto permalink: welcome-to-mephisto - body: "rico's evil and linkage" - body_html: "

      rico’s evil and linkage

      " + body: "rico's evil script and linkage alert!" + body_html: "

      rico’s evil script and linkage

      <\nscrip\nt>alert!" created_at: <%= (3.days + 55.minutes).ago.utc.to_s(:db) %> updated_at: <%= (3.days + 55.minutes).ago.utc.to_s(:db) %> published_at: <%= 3.days.ago.utc.to_s(:db) %> @@ -199,6 +199,32 @@ permalink: at-beginning-of-next-month body: Lalala body_html: Lalala + created_at: <%= date = Time.now.utc.beginning_of_month.advance(:months => -1, :minutes => 2).to_s(:db) %> + updated_at: <%= date %> + published_at: <%= date %> + comment_age: 30 + user_id: 1 + type: Article +article_1_only_in_page_section: + id: 16 + site_id: 1 + title: Article 1 + permalink: article-1 + body: Lalala + body_html: Lalala + created_at: <%= date = Time.now.utc.beginning_of_month.advance(:months => -1, :minutes => 1).to_s(:db) %> + updated_at: <%= date %> + published_at: <%= date %> + comment_age: 30 + user_id: 1 + type: Article +article_2_only_in_page_section: + id: 17 + site_id: 1 + title: Article 2 + permalink: article-2 + body: Lalala + body_html: Lalala created_at: <%= date = Time.now.utc.beginning_of_month.advance(:months => -1).to_s(:db) %> updated_at: <%= date %> published_at: <%= date %> diff -Nur mephisto-0.7.3/test/fixtures/mephisto_plugins.yml technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/test/fixtures/mephisto_plugins.yml --- mephisto-0.7.3/test/fixtures/mephisto_plugins.yml 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/test/fixtures/mephisto_plugins.yml 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,4 @@ +whammy_jammy: + id: 1 + name: plugin_whammy_jammy + type: PluginWhammyJammy \ No newline at end of file diff -Nur mephisto-0.7.3/test/fixtures/plugins/lib/test_plugin.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/test/fixtures/plugins/lib/test_plugin.rb --- mephisto-0.7.3/test/fixtures/plugins/lib/test_plugin.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/test/fixtures/plugins/lib/test_plugin.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,12 @@ +module Mephisto + module Plugins + class TestPlugin < Mephisto::Plugin + homepage 'http://foo.com' + author 'Captain Problematic' + version 'deathstar' + + option :config, 'one' => 'test' + option :notes, 'notes' + end + end +end \ No newline at end of file diff -Nur mephisto-0.7.3/test/fixtures/sections.yml technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/test/fixtures/sections.yml --- mephisto-0.7.3/test/fixtures/sections.yml 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/test/fixtures/sections.yml 2008-03-31 02:18:56.000000000 -0400 @@ -7,6 +7,7 @@ articles_count: 3 template: home.liquid archive_path: archives + position: 1 about: id: 2 site_id: 1 @@ -16,6 +17,7 @@ articles_count: 3 template: page.liquid archive_path: archives + position: 2 cupcake_home: id: 3 site_id: 2 @@ -25,6 +27,7 @@ template: home.liquid articles_count: 1 archive_path: archives + position: 1 cupcake_about: id: 4 site_id: 2 @@ -34,6 +37,7 @@ template: page.liquid articles_count: 1 archive_path: archives + position: 2 earth: id: 5 site_id: 1 @@ -42,6 +46,7 @@ show_paged_articles: false articles_count: 0 archive_path: archives + position: 3 europe: id: 6 site_id: 1 @@ -50,6 +55,7 @@ show_paged_articles: false articles_count: 0 archive_path: archives + position: 4 africa: id: 7 site_id: 1 @@ -58,6 +64,7 @@ show_paged_articles: false articles_count: 0 archive_path: archives + position: 5 bucharest: id: 8 site_id: 1 @@ -66,6 +73,7 @@ show_paged_articles: false articles_count: 0 archive_path: archives + position: 6 links: id: 9 site_id: 1 @@ -75,3 +83,14 @@ template: page.liquid articles_count: 0 archive_path: archives + position: 7 +paged_section: + id: 10 + site_id: 1 + name: Paged Section + path: paged-section + show_paged_articles: true + template: page.liquid + articles_count: 2 + archive_path: archives + position: 8 \ No newline at end of file diff -Nur mephisto-0.7.3/test/fixtures/sites.yml technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/test/fixtures/sites.yml --- mephisto-0.7.3/test/fixtures/sites.yml 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/test/fixtures/sites.yml 2008-03-31 02:18:56.000000000 -0400 @@ -7,7 +7,7 @@ first: id: 1 title: Mephisto - host: test.com + host: test.host filter: textile_filter approve_comments: false comment_age: 30 diff -Nur mephisto-0.7.3/test/functional/admin/admin_nav_test.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/test/functional/admin/admin_nav_test.rb --- mephisto-0.7.3/test/functional/admin/admin_nav_test.rb 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/test/functional/admin/admin_nav_test.rb 2008-03-31 02:18:56.000000000 -0400 @@ -11,7 +11,7 @@ @controller = Admin::AssetsController.new @request = ActionController::TestRequest.new @response = ActionController::TestResponse.new - login_as :quentin + login_as :arthur get :new end @@ -63,3 +63,39 @@ end end end + +class Admin::GlobalAdminNavTest < Test::Unit::TestCase + fixtures :sites, :users, :memberships + + def setup + @old = Site.multi_sites_enabled + @controller = Admin::AssetsController.new + @request = ActionController::TestRequest.new + @response = ActionController::TestResponse.new + Site.multi_sites_enabled = true + login_as :quentin + get :new + end + + def teardown + Site.multi_sites_enabled = @old + end + + def test_should_show_primary_nav + assert_select "#header #nav a" do |anchors| + assert_equal %w(Overview Articles Assets), anchors[0..2].collect { |a| a.children.first.content } + end + end + + def test_should_show_secondary_nav + assert_select "#header #nav #nav-r a" do |anchors| + assert_equal %w(Sections Design Users), anchors.collect { |a| a.children.first.content } + end + end + + def test_should_show_user_nav + assert_select "#header #sec-nav a" do |anchors| + assert_equal %w(Website Settings Sites Account Logout), anchors.collect { |a| a.children.first.content } + end + end +end diff -Nur mephisto-0.7.3/test/functional/admin/articles_controller_assets_test.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/test/functional/admin/articles_controller_assets_test.rb --- mephisto-0.7.3/test/functional/admin/articles_controller_assets_test.rb 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/test/functional/admin/articles_controller_assets_test.rb 2008-03-31 02:18:56.000000000 -0400 @@ -4,10 +4,10 @@ # Re-raise errors caught by the controller. class Admin::ArticlesController; def rescue_action(e) raise e end; end -class Admin::ArticlesControllerAssetsTest < Test::Unit::TestCase - fixtures :contents, :content_versions, :sections, :assigned_sections, :users, :sites, :tags, :taggings, :memberships +context "Admin Articles Controller Assets" do + fixtures :contents, :content_versions, :sections, :assigned_sections, :users, :sites, :tags, :taggings, :memberships, :assigned_assets, :assets - def setup + setup do @controller = Admin::ArticlesController.new @request = ActionController::TestRequest.new @response = ActionController::TestResponse.new @@ -15,8 +15,8 @@ FileUtils.mkdir_p ASSET_PATH end - def test_should_upload_asset - asset_count = Object.const_defined?(:Magick) ? 3 : 1 # asset + 2 thumbnails + specify "should upload asset" do + asset_count = has_image_processor? ? 3 : 1 # asset + 2 thumbnails assert_difference Asset, :count, asset_count do post :upload, :asset => { :uploaded_data => fixture_file_upload('assets/logo.png', 'image/png') } @@ -25,8 +25,8 @@ end end - def test_should_upload_asset_and_redirect_to_article - asset_count = Object.const_defined?(:Magick) ? 3 : 1 # asset + 2 thumbnails + specify "should upload asset and redirect to article" do + asset_count = has_image_processor? ? 3 : 1 # asset + 2 thumbnails assert_difference Asset, :count, asset_count do post :upload, :id => contents(:welcome).id, @@ -37,8 +37,8 @@ end end - def test_should_upload_asset_as_member - asset_count = Object.const_defined?(:Magick) ? 3 : 1 # asset + 2 thumbnails + specify "should upload asset as member" do + asset_count = has_image_processor? ? 3 : 1 # asset + 2 thumbnails login_as :ben assert_difference Asset, :count, asset_count do @@ -48,8 +48,8 @@ end end - def test_should_upload_asset_and_redirect_to_article_as_member - asset_count = Object.const_defined?(:Magick) ? 3 : 1 # asset + 2 thumbnails + specify "should upload asset and redirect to article as member" do + asset_count = has_image_processor? ? 3 : 1 # asset + 2 thumbnails login_as :ben assert_difference Asset, :count, asset_count do @@ -61,7 +61,7 @@ end end - def test_should_not_error_on_new_article_asset_upload + specify "should not error on new article asset upload" do assert_no_difference Asset, :count do post :upload assert_response :success @@ -69,7 +69,7 @@ end end - def test_should_not_error_on_article_asset_upload + specify "should not error on article asset upload" do assert_no_difference Asset, :count do post :upload, :id => contents(:welcome).id assert_response :success @@ -78,7 +78,7 @@ end end - def test_should_not_create_article_when_uploading_asset + specify "should not create article when uploading asset" do Time.mock! Time.local(2005, 1, 1, 12, 0, 0) do assert_no_difference Article, :count do post :upload, :asset => { :uploaded_data => fixture_file_upload('assets/logo.png', 'image/png') }, @@ -94,7 +94,34 @@ end end - def teardown + # TODO: Fails due to asset test deleting asset fixtures + specify "should add asset to article" do + return if Asset.count == 1 + assert_difference AssignedAsset, :count do + post :attach, :id => contents(:welcome).id, :version => assets(:mov).id + end + assert_models_equal [assets(:gif), assets(:mp3), assets(:mov)], contents(:welcome).assets(true) + end + + # TODO: Fails due to asset test deleting asset fixtures + specify "should add inactive asset to article" do + return if Asset.count == 1 + assert_no_difference AssignedAsset, :count do + post :attach, :id => contents(:welcome).id, :version => assets(:png).id + end + assert_models_equal [assets(:gif), assets(:mp3), assets(:png)], contents(:welcome).assets(true) + end + + # TODO: Fails due to asset test deleting asset fixtures + specify "should find deactivate article assets" do + return if Asset.count == 1 + assert_no_difference AssignedAsset, :count do + post :detach, :id => contents(:welcome).id, :version => assets(:mp3).id + end + assert_models_equal [assets(:gif)], contents(:welcome).assets + end + + teardown do FileUtils.rm_rf ASSET_PATH end end diff -Nur mephisto-0.7.3/test/functional/admin/articles_controller_permissions_test.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/test/functional/admin/articles_controller_permissions_test.rb --- mephisto-0.7.3/test/functional/admin/articles_controller_permissions_test.rb 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/test/functional/admin/articles_controller_permissions_test.rb 2008-03-31 02:18:56.000000000 -0400 @@ -16,7 +16,7 @@ def test_should_show_articles get :index - assert_equal 10, assigns(:articles).length + assert_equal 12, assigns(:articles).length end def test_should_show_new_article_form diff -Nur mephisto-0.7.3/test/functional/admin/articles_controller_test.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/test/functional/admin/articles_controller_test.rb --- mephisto-0.7.3/test/functional/admin/articles_controller_test.rb 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/test/functional/admin/articles_controller_test.rb 2008-03-31 02:18:56.000000000 -0400 @@ -28,12 +28,12 @@ def test_should_show_articles get :index - assert_equal 10, assigns(:articles).length + assert_equal 12, assigns(:articles).length end def test_should_show_articles_with_empty_seartest_should_show_checked_sectionsch get :index, :q => '', :filter => 'title', :section => '0' - assert_equal 10, assigns(:articles).length + assert_equal 12, assigns(:articles).length end def test_should_search_article_titles @@ -57,7 +57,7 @@ def test_should_search_article_by_section get :index, :filter => 'section', :section => '2' assert_response :success - assert_models_equal [contents(:welcome), contents(:about), contents(:site_map)], assigns(:articles) + assert_models_equal [contents(:future), contents(:welcome), contents(:about), contents(:site_map), contents(:draft)], assigns(:articles) end def test_should_search_article_by_section_and_title @@ -125,7 +125,7 @@ def test_should_show_default_checked_sections get :new assert_response :success - assert_tag 'form', :attributes => { :action => '/admin/articles/create' } + assert_tag 'form', :attributes => { :action => '/admin/articles', :method => 'post' } assert_tag 'input', :attributes => { :id => "article_section_ids_#{sections(:home).id.to_s}" } assert_no_tag 'input', :attributes => { :id => "article_section_ids_#{sections(:about).id.to_s}", :checked => 'checked' } end @@ -162,7 +162,7 @@ def test_should_show_available_years_for_old_article contents(:welcome).update_attribute(:published_at, Time.utc(2003,1,1)) get :edit, :id => contents(:welcome).id - (2003..Time.now.utc.year).to_a.each do |year| + (2003..2007).to_a.each do |year| assert_select "select[name='article[published_at(1i)]'] option[value='#{year}']" end end @@ -182,7 +182,9 @@ def test_edit_form_should_have_correct_post_action get :edit, :id => contents(:welcome).id assert_response :success - assert_tag :tag => 'form', :attributes => { :action => "/admin/articles/update/#{contents(:welcome).id}" } + assert_tag :tag => 'form', :attributes => { :action => "/admin/articles/#{contents(:welcome).id}" } do + assert_tag :tag => 'input', :attributes => { :name => "_method", :value => "put" } + end end def test_should_update_article_with_correct_time diff -Nur mephisto-0.7.3/test/functional/admin/assets_controller_permissions_test.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/test/functional/admin/assets_controller_permissions_test.rb --- mephisto-0.7.3/test/functional/admin/assets_controller_permissions_test.rb 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/test/functional/admin/assets_controller_permissions_test.rb 2008-03-31 02:18:56.000000000 -0400 @@ -21,7 +21,7 @@ end def test_should_upload_and_create_asset_records - asset_count = Object.const_defined?(:Magick) ? 3 : 1 # asset + 2 thumbnails + asset_count = has_image_processor? ? 3 : 1 # asset + 2 thumbnails assert_difference sites(:first).assets, :count do assert_difference Asset, :count, asset_count do @@ -29,7 +29,7 @@ assert_equal users(:ben).id, assigns(:assets).first.user_id assert_equal 'logo.png', assigns(:assets).first.title assert_match /logo\.png/, flash[:notice] - assert_redirected_to asset_path + assert_redirected_to assets_path end end end @@ -74,7 +74,7 @@ assert_response :success assert_match /Flash\.notice/, @response.body assert_equal 1, session[:bucket].size - assert_kind_of Array, session[:bucket][assets(:gif).public_filename] + assert_kind_of Array, session[:bucket][assets(:gif).id] end def test_should_clear_bucket diff -Nur mephisto-0.7.3/test/functional/admin/assets_controller_test.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/test/functional/admin/assets_controller_test.rb --- mephisto-0.7.3/test/functional/admin/assets_controller_test.rb 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/test/functional/admin/assets_controller_test.rb 2008-03-31 02:18:56.000000000 -0400 @@ -21,14 +21,14 @@ end def test_should_upload_and_create_asset_records - asset_count = Object.const_defined?(:Magick) ? 3 : 1 # asset + 2 thumbnails + asset_count = has_image_processor? ? 3 : 1 # asset + 2 thumbnails assert_difference sites(:first).assets, :count do assert_difference Asset, :count, asset_count do process_upload ['logo.png'] assert_equal 'logo.png', assigns(:assets).first.title assert_match /logo\.png/, flash[:notice] - assert_redirected_to asset_path + assert_redirected_to assets_path end end end @@ -53,12 +53,12 @@ end def test_should_upload_multiple_assets_and_ignore_titles - asset_count = Object.const_defined?(:Magick) ? 6 : 2 # asset + 2 thumbnails + asset_count = has_image_processor? ? 6 : 2 # asset + 2 thumbnails assert_difference sites(:first).assets, :count, 2 do assert_difference Asset, :count, asset_count do process_upload %w(logo.png logo.png) assert_match /2 assets/, flash[:notice] - assert_redirected_to asset_path + assert_redirected_to assets_path end end end @@ -138,16 +138,16 @@ assert_response :success assert_match /Flash\.notice/, @response.body assert_equal 1, session[:bucket].size - assert_kind_of Array, session[:bucket][assets(:gif).public_filename] + assert_kind_of Array, session[:bucket][assets(:gif).id] end def test_should_not_add_duplicate_asset_to_bucket - @request.session[:bucket] = {assets(:gif).public_filename => []} + @request.session[:bucket] = {assets(:gif).id => []} xhr :post, :add_bucket, :id => assets(:gif).id assert_response :success assert_equal ' ', @response.body assert_equal 1, session[:bucket].size - assert_kind_of Array, session[:bucket][assets(:gif).public_filename] + assert_kind_of Array, session[:bucket][assets(:gif).id] end def test_should_clear_bucket diff -Nur mephisto-0.7.3/test/functional/admin/assets_controller_upload_test.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/test/functional/admin/assets_controller_upload_test.rb --- mephisto-0.7.3/test/functional/admin/assets_controller_upload_test.rb 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/test/functional/admin/assets_controller_upload_test.rb 2008-03-31 02:18:56.000000000 -0400 @@ -16,7 +16,7 @@ Fixtures.delete_existing_fixtures_for(Asset.connection, :assets) end -if Object.const_defined?(:Magick) +if has_image_processor? def test_should_sort_assets assert_difference sites(:first).assets, :count, 21 do assert_difference Asset, :count, 63 do diff -Nur mephisto-0.7.3/test/functional/admin/comments_controller_test.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/test/functional/admin/comments_controller_test.rb --- mephisto-0.7.3/test/functional/admin/comments_controller_test.rb 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/test/functional/admin/comments_controller_test.rb 2008-03-31 02:18:56.000000000 -0400 @@ -10,7 +10,7 @@ @controller = Admin::CommentsController.new @request = ActionController::TestRequest.new @response = ActionController::TestResponse.new - login_as :ben + login_as :quentin end def test_should_disable_comments_on_article @@ -18,4 +18,60 @@ assert_equal -1, contents(:welcome).reload.comment_age assert_response :success end + + def test_should_destroy_comment + comment = contents(:welcome_comment) + + xhr :delete, :destroy, :id => '3', :article_id => '1' + assert_response :success + assert_equal [comment], assigns(:comments) + assert_raise(ActiveRecord::RecordNotFound) { comment.reload } + end + + def test_should_destroy_comments + comment = contents(:welcome_comment) + + xhr :delete, :destroy, :comment => ['3'], :article_id => '1' + assert_response :success + assert_equal [comment], assigns(:comments) + assert_raise(ActiveRecord::RecordNotFound) { comment.reload } + end + + def test_should_list_comments_on_article + get :index, :article_id => '1' + assert_response :success + end + + def test_should_list_approved_comments_on_article + get :index, :article_id => '1', :filter => 'approved' + assert_response :success + end + + def test_should_list_unapproved_comments_on_article + get :index, :article_id => '1', :filter => 'unapproved' + assert_response :success + end + + def test_should_create_comment + post :create, :article_id => '1', :comment => {} + assert_response :success + end + + def test_should_edit_comment + get :edit, :article_id => '1', :id => '3' + assert_response :success + end + + def test_should_approve_comment + contents(:welcome_comment).update_attribute(:approved, false) + xhr :get, :approve, :article_id => '1', :id => '3' + assert_response :success + end + + def test_should_unapprove_comment + xhr :get, :unapprove, :article_id => '1', :id => '3' + assert_response :success + assert_template 'approve' + end + end diff -Nur mephisto-0.7.3/test/functional/admin/plugins_controller_test.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/test/functional/admin/plugins_controller_test.rb --- mephisto-0.7.3/test/functional/admin/plugins_controller_test.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/test/functional/admin/plugins_controller_test.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,66 @@ +require File.dirname(__FILE__) + '/../../test_helper' +require 'admin/plugins_controller' + +class Admin::PluginsControllerTest < Test::Unit::TestCase + fixtures :contents, :content_versions, :sections, :assigned_sections, :users, :sites, :tags, :taggings, :memberships + @@test_plugin_dir = RAILS_PATH + 'test/fixtures/plugins/lib' + @@plugin_dir = RAILS_PATH + 'vendor/plugins/mephisto_test_plugin' + @@plugin_lib_dir = @@plugin_dir + 'lib' + + def setup + @controller = Admin::PluginsController.new + @request = ActionController::TestRequest.new + @response = ActionController::TestResponse.new + login_as :quentin + + #here we create a temporary and simple plugin + FileUtils.mkdir_p(@@plugin_dir) + FileUtils.cp_r @@test_plugin_dir, @@plugin_dir + $LOAD_PATH << @@plugin_lib_dir.to_s + load @@plugin_lib_dir + 'test_plugin.rb' + end + + def teardown + $LOAD_PATH.delete @@plugin_lib_dir.to_s + FileUtils.rm_rf(@@plugin_dir) + end + + def test_should_list_plugins + get :index + assert_response :success + + test_dir_plugin = assigns(:plugins).detect { |p| p.path == 'test_plugin' } + + assert test_dir_plugin.configurable?, "Test Plugin is not configurable!" + end + + def test_should_show_plugin + assert_not_nil Mephisto::Plugins::TestPlugin.new + get :show, :id => 'test_plugin' + assert_response :success + end + + def test_should_update_plugin_options + get :update, :id => 'test_plugin', :options => { :notes => 'foo bar' } + assert_redirected_to :action => "show" + + assert_equal "foo bar", assigns(:plugin).notes + end + + def test_should_delete_plugin + test_should_update_plugin_options + get :destroy, :id => 'test_plugin' + assert_redirected_to :action => "show" + + + # weird, in the below the assigns hash holds the plugin object from delete + # not the second plugin reloaded from show. So I suppose assigns is built by + # the get. + # I'd like to work out a way to access the plugin object reloaded in the 302 show. + # + # TODO: Convert to integration test for this + # + # plugin = assigns["plugin"] + # assert_equal "test", plugin.config["one"] + end +end \ No newline at end of file diff -Nur mephisto-0.7.3/test/functional/admin/sections_controller_test.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/test/functional/admin/sections_controller_test.rb --- mephisto-0.7.3/test/functional/admin/sections_controller_test.rb 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/test/functional/admin/sections_controller_test.rb 2008-03-31 02:18:56.000000000 -0400 @@ -18,9 +18,9 @@ get :index assert_equal sites(:first), assigns(:site) assert_equal sections(:home), assigns(:home) - assert_equal 7, assigns(:sections).length, "Sections: #{assigns(:sections).collect(&:id).to_sentence}" + assert_equal 8, assigns(:sections).length, "Sections: #{assigns(:sections).collect(&:id).to_sentence}" assert_equal 4, assigns(:article_count)['1'] - assert_equal 3, assigns(:article_count)['2'] + assert_equal 5, assigns(:article_count)['2'] end def test_should_create_blog_section @@ -67,8 +67,8 @@ def test_should_reorder_articles assert_reorder_articles sections(:about), - [contents(:welcome), contents(:about), contents(:site_map)], - [contents(:about), contents(:site_map), contents(:welcome)] + [contents(:welcome), contents(:about), contents(:site_map), contents(:draft), contents(:future)], + [contents(:future), contents(:about), contents(:site_map), contents(:welcome), contents(:draft)] end def test_should_destroy_section @@ -77,8 +77,8 @@ end def test_should_reorder_sections - assert_reorder_sections [sections(:home), sections(:about), sections(:earth), sections(:europe), sections(:africa), sections(:bucharest), sections(:links)], - [sections(:home), sections(:earth), sections(:europe), sections(:africa), sections(:bucharest), sections(:links), sections(:about)] + assert_reorder_sections [sections(:home), sections(:about), sections(:earth), sections(:europe), sections(:africa), sections(:bucharest), sections(:links), sections(:paged_section)], + [sections(:home), sections(:earth), sections(:europe), sections(:africa), sections(:bucharest), sections(:links), sections(:about), sections(:paged_section)] end protected diff -Nur mephisto-0.7.3/test/functional/admin/settings_controller_test.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/test/functional/admin/settings_controller_test.rb --- mephisto-0.7.3/test/functional/admin/settings_controller_test.rb 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/test/functional/admin/settings_controller_test.rb 2008-03-31 02:18:56.000000000 -0400 @@ -27,8 +27,7 @@ def test_should_clear_layouts login_as :quentin - post :update, :site => { :title => 'foo', :search_layout => '-', :tag_layout => '-' } - assert_nil sites(:first).reload.search_layout + post :update, :site => { :title => 'foo', :tag_layout => '-' } assert_nil sites(:first).tag_layout end diff -Nur mephisto-0.7.3/test/functional/admin/sites_controller_test.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/test/functional/admin/sites_controller_test.rb --- mephisto-0.7.3/test/functional/admin/sites_controller_test.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/test/functional/admin/sites_controller_test.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,58 @@ +require File.dirname(__FILE__) + '/../../test_helper' +require 'admin/sites_controller' + +# Re-raise errors caught by the controller. +class Admin::SitesController; def rescue_action(e) raise e end; end + +class Admin::SitesControllerTest < Test::Unit::TestCase + fixtures :users, :sites + def setup + @controller = Admin::SitesController.new + @request = ActionController::TestRequest.new + @response = ActionController::TestResponse.new + end + + def test_should_allow_admin_of_sites + login_as :quentin + get :index + assert_response :success + end + + def test_should_restrict_admin_of_sites + login_as :arthur + get :index + assert_redirected_to :controller => 'account', :action => 'login' + end + + def test_should_allow_admin_to_view_site + login_as :quentin + get :show, :id => sites(:hostess).id.to_s + assert_response :success + end + + def test_should_create_site + login_as :quentin + assert_difference Site, :count do + post :create, :site => { :host => 'example.com', :email => 'foo@example.com', :title => 'example', :subtitle => 'example site' } + assert_redirected_to :action => 'index' + assert flash[:notice] + end + end + + def test_should_show_error_while_creating_site + login_as :quentin + assert_no_difference Site, :count do + post :create, :site => { :host => 'not a valid host' } + assert_response :success + end + end + + def test_should_destroy_site + login_as :quentin + assert_difference Site, :count, -1 do + post :destroy, :id => sites(:hostess).id.to_s + assert_redirected_to :action => 'index' + end + end + +end diff -Nur mephisto-0.7.3/test/functional/admin/themes_controller_test.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/test/functional/admin/themes_controller_test.rb --- mephisto-0.7.3/test/functional/admin/themes_controller_test.rb 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/test/functional/admin/themes_controller_test.rb 2008-03-31 02:18:56.000000000 -0400 @@ -4,9 +4,10 @@ # Re-raise errors caught by the controller. class Admin::ThemesController; def rescue_action(e) raise e end; end -class Admin::ThemesControllerTest < Test::Unit::TestCase +context "Admin Themes Controller" do fixtures :users, :sections, :sites, :memberships - def setup + + setup do @controller = Admin::ThemesController.new @request = ActionController::TestRequest.new @response = ActionController::TestResponse.new diff -Nur mephisto-0.7.3/test/functional/admin/users_controller_test.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/test/functional/admin/users_controller_test.rb --- mephisto-0.7.3/test/functional/admin/users_controller_test.rb 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/test/functional/admin/users_controller_test.rb 2008-03-31 02:18:56.000000000 -0400 @@ -5,7 +5,7 @@ class Admin::UsersController; def rescue_action(e) raise e end; end class Admin::UsersControllerTest < Test::Unit::TestCase - fixtures :users, :sites, :memberships + fixtures :users, :sites, :memberships, :contents def setup @controller = Admin::UsersController.new @request = ActionController::TestRequest.new @@ -40,7 +40,7 @@ login_as :quentin assert_difference User, :count do assert_difference Membership, :count do - post :create, :user => { :login => 'bob', :email => 'foo@example.com', :password => 'testy', :password_confirmation => 'testy', :admin => true } + post :create, :user => { :login => 'bob', :email => 'foo@example.com', :password => 'testy', :password_confirmation => 'testy' } assert_models_equal [sites(:first)], assigns(:user).sites assert_equal assigns(:user), User.authenticate_for(sites(:first), 'bob', 'testy') assert_redirected_to :action => 'index' @@ -114,6 +114,36 @@ assert_equal 'markdown_filter', users(:quentin).filter end + def test_should_not_permit_promoting_self_to_admin_in_update + login_as :arthur, :hostess + assert !users(:arthur).admin, "we mean to test with a non-admin user" + post :update, :id => users(:arthur).id, :user => { :admin => 'true' } + users(:arthur).reload + assert !users(:arthur).admin, "user.admin shouldn't change" + assert_response :success + end + + def test_should_not_permit_changing_own_created_at_in_update + login_as :arthur, :hostess + prev_time = users(:arthur).created_at + post :update, :id => users(:arthur).id, :user => { :created_at => prev_time - 1.year } + users(:arthur).reload + assert_equal prev_time, users(:arthur).created_at, "user.created_at shouldn't change" + assert_response :success + end + + def test_should_not_permit_changing_owned_articles_in_update + login_as :quentin + user = users(:quentin) + prev_article_ids = user.article_ids + assert prev_article_ids.size > 2, "Test needs more than 2 articles. Pick another user?" + #but now we're going to try to own only the first 2 of them... + post :update, :id => user.id, :user => { :article_ids => prev_article_ids[0..1] } + user.reload + assert_equal prev_article_ids, user.article_ids, "user.article_ids[] shouldn't change" + assert_response :success + end + def test_should_show_deleted_users login_as :quentin get :index @@ -137,11 +167,36 @@ end end - def test_should_disable_site_admin + def test_should_toggle_site_admin_as_admin login_as :quentin xhr :post, :admin, :id => users(:arthur).id assert_response :success assert !sites(:first).user(users(:arthur).id).site_admin? + assert_match /Flash\.notice/, @response.body + end + + def test_should_toggle_site_admin_as_site_admin + login_as :arthur + assert !sites(:first).user(users(:ben).id).site_admin? + xhr :post, :admin, :id => users(:ben).id + assert_response :success + assert sites(:first).user(users(:ben).id).site_admin? + assert_match /Flash\.notice/, @response.body + end + + def test_should_not_toggle_site_admin_for_admin + login_as :arthur + xhr :post, :admin, :id => users(:quentin).id + assert_response :success + assert_match /Flash\.errors/, @response.body + end + + def test_should_not_toggle_site_admin_for_self + login_as :arthur + xhr :post, :admin, :id => users(:arthur).id + assert_response :success + assert sites(:first).user(users(:arthur).id).site_admin? + assert_match /Flash\.errors/, @response.body end def test_should_enable_site_admin @@ -156,12 +211,35 @@ login_as :quentin assert_no_difference User, :count_with_deleted do assert_difference User, :count, -1 do - xhr :post, :destroy, :id => users(:quentin).id + xhr :post, :destroy, :id => users(:arthur).id assert_response :success + assert_match /Flash\.notice/, @response.body end end - assert_equal users(:quentin), User.find_with_deleted(users(:quentin).id) + assert_equal users(:arthur), User.find_with_deleted(users(:arthur).id) + end + + def test_should_not_disable_admin + login_as :arthur + assert_no_difference User, :count_with_deleted do + assert_no_difference User, :count do + xhr :post, :destroy, :id => users(:quentin).id + assert_response :success + assert_match /Flash\.errors/, @response.body + end + end + end + + def test_should_not_disable_self + login_as :arthur + assert_no_difference User, :count_with_deleted do + assert_no_difference User, :count do + xhr :post, :destroy, :id => users(:arthur).id + assert_response :success + assert_match /Flash\.errors/, @response.body + end + end end def test_should_enable_user diff -Nur mephisto-0.7.3/test/functional/application_controller_test.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/test/functional/application_controller_test.rb --- mephisto-0.7.3/test/functional/application_controller_test.rb 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/test/functional/application_controller_test.rb 2008-03-31 02:18:56.000000000 -0400 @@ -12,33 +12,40 @@ class ApplicationControllerTest < Test::Unit::TestCase fixtures :sites def setup - @sub = Site.create!(:title => 'sub', :host => 'sub.test.com') + @sub = Site.create!(:title => 'sub', :host => 'sub.test.host') @uk = Site.create!(:title => 'sub', :host => 'sub.test.co.uk') @controller = AccountController.new @request = ActionController::TestRequest.new @response = ActionController::TestResponse.new end + + def test_should_raise_404_if_no_site + Site.delete_all + host! 'test.hosts' + get :test_host + assert_response :missing + end def test_should_find_site_by_host - host! 'test.com' + host! 'test.host' get :test_host assert_equal sites(:first), @controller.site end def test_should_find_site_with_www_prefix - host! 'www.test.com' + host! 'www.test.host' get :test_host assert_equal sites(:first), @controller.site end def test_should_find_site_by_subdomain_and_host - host! 'sub.test.com' + host! 'sub.test.host' get :test_host assert_equal @sub, @controller.site end def test_should_find_site_by_subdomain_and_host_with_www_prefix - host! 'www.sub.test.com' + host! 'www.sub.test.host' get :test_host assert_equal @sub, @controller.site end diff -Nur mephisto-0.7.3/test/functional/application_helper_test.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/test/functional/application_helper_test.rb --- mephisto-0.7.3/test/functional/application_helper_test.rb 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/test/functional/application_helper_test.rb 2008-03-31 02:18:56.000000000 -0400 @@ -55,14 +55,6 @@ assert_match assets(:png).public_filename, asset_image_for(assets(:png)) end - def test_should_not_sanitize_tables - assert_equal "<table>", sanitize_feed_content('') - end - - def test_should_sanitize_tables - assert_equal "&lt;table>", sanitize_feed_content('
      ', true) - end - protected def asset_image_args_for(*args) controller.send(:asset_image_args_for, *args) diff -Nur mephisto-0.7.3/test/functional/backend_controller_test.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/test/functional/backend_controller_test.rb --- mephisto-0.7.3/test/functional/backend_controller_test.rb 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/test/functional/backend_controller_test.rb 1969-12-31 19:00:00.000000000 -0500 @@ -1,303 +0,0 @@ -require File.dirname(__FILE__) + '/../test_helper' -require 'meta_weblog_api' -require 'movable_type_api' -require 'backend_controller' - -# Re-raise errors caught by the controller. -class BackendController; def rescue_action(e) raise e end; end - -class BackendControllerTest < Test::Unit::TestCase - fixtures :users, :sections, :assigned_sections, :contents, :sites - - def setup - @controller = BackendController.new - @request = ActionController::TestRequest.new - @response = ActionController::TestResponse.new - @protocol = :xmlrpc - FileUtils.mkdir_p ASSET_PATH - end - - def teardown - FileUtils.rm_rf ASSET_PATH - end - - # Movable Type Backend Api Tests - def test_movable_type_get_category_list - # test test_movable_type_get_category_list - args = [ 1, 'quentin', 'test' ] - - result = invoke_layered :mt, :getCategoryList, *args - assert_equal 'Home', result.first['categoryName'] - end - - def test_movable_type_get_post_categories - # test test_movable_type_get_post_categories - args = [ 1, 'quentin', 'test' ] - - result = invoke_layered :mt, :getPostCategories, *args - assert_equal %w(About Home), result.collect { |c| c['categoryName'] } - end - - def test_movable_type_set_post_categories - # test test_movable_type_set_post_categories - # this needs some work!! FIXME FIXME FIXME - - c1 = MovableTypeStructs::PostCategory.new(:categoryId => 1, :categoryName => 'Home', :isPrimary => false) - c2 = MovableTypeStructs::PostCategory.new(:categoryId => 2, :categoryName => 'About', :isPrimary => false) - c3 = MovableTypeStructs::PostCategory.new(:categoryId => 9, :categoryName => 'Links', :isPrimary => false) - - args = [ 1, 'quentin', 'test', [ c1, c2, c3 ]] - - result = invoke_layered :mt, :setPostCategories, *args - assert_equal true, result - - # see if the categories have been set - args = [ 1, 'quentin', 'test' ] - - result = invoke_layered :mt, :getPostCategories, *args - assert_equal ["1","2","9"], result.collect { |c| c['categoryId'] }.sort - - # set the categories back to the default - args = [ 1, 'quentin', 'test', [c1,c2] ] - - result = invoke_layered :mt, :setPostCategories, *args - assert_equal true, result - end - - def test_movable_type_supported_methods - # test test_movable_type_supported_methods - result = invoke_layered :mt, :supportedMethods - - assert_instance_of Array, result - end - - def test_movable_type_supported_text_filters - # test test_movable_type_supported_text_filters - result = invoke_layered :mt, :supportedTextFilters - - assert_instance_of Array, result - end - - - - def test_meta_weblog_get_categories - args = [ 1, 'quentin', 'test' ] - - result = invoke_layered :metaWeblog, :getCategories, *args - assert_equal 'Home', result.first - end - - def test_meta_weblog_get_post - args = [ 1, 'quentin', 'test' ] - - result = invoke_layered :metaWeblog, :getPost, *args - assert_equal 'Welcome to Mephisto', result['title'], result.inspect - assert_equal %w(About Home), result['categories'] - end - - def test_meta_weblog_get_recent_posts - args = [ 1, 'quentin', 'test', 2 ] - - articles = invoke_layered :metaWeblog, :getRecentPosts, *args - assert_equal %w(test-draft article-in-the-future), articles.collect { |a| a['permaLink'] }, articles.inspect - end - - def test_meta_weblog_delete_post - args = [ 1, 1, 'quentin', 'test', 1 ] - - assert_difference Article, :count, -1 do - result = invoke_layered :metaWeblog, :deletePost, *args - end - end - - def test_meta_weblog_edit_post - post_time = Time.now.midnight.utc - article = contents(:welcome) - article.title = "Modified!" - article.body = "this is a *test*" - article.excerpt = "* one\n* two\n" - article.published_at = post_time - - struct = MetaWeblogService.new(@controller).article_dto_from(article) - invoke_layered :metaWeblog, :editPost, contents(:welcome).id, 'quentin', 'test', struct, true - - assert_equal post_time, struct['dateCreated'] - - assert_equal 'Modified!', article.reload.title - assert_equal "

      this is a test

      ", article.body_html, article.inspect - assert_equal "
        \n\t
      • one
      • \n\t\t
      • two
      • \n\t
      ", article.excerpt_html, article.inspect - assert_equal post_time, article.published_at - assert_equal users(:quentin), article.updater - end - - def test_meta_weblog_new_post - assert_difference Article, :count do - article = Article.new - article.title = "Posted via Test" - article.body = "body" - article.excerpt = "extend me" - article.published_at = Time.now.midnight.utc - - args = [ 1, 'quentin', 'test', MetaWeblogService.new(@controller).article_dto_from(article), 1 ] - - result = invoke_layered :metaWeblog, :newPost, *args - assert result - new_post = Article.find(result) - - assert_equal "Posted via Test", new_post.title - assert_equal article.body, new_post.body - assert_equal "

      body

      ", new_post.body_html - assert_equal "

      extend me

      ", new_post.excerpt_html - end - end - - def test_meta_weblog_new_post_tags - # test weather we can create a new post, set tags and get away with it... - tags = 'blog, emacs, fun, rails, ruby' - article = MetaWeblogStructs::Article.new(:title => 'This is a title', :description => 'This is a post', :mt_keywords => tags) - - args = [ 1, 'quentin', 'test', article, 1 ] - - result = invoke_layered :metaWeblog, :newPost, *args - # assert result - new_post = Article.find(result) - assert_equal Tag.parse_to_tags(tags).collect(&:name).sort, new_post.tags.collect(&:name).sort - end - - def test_meta_weblog_edit_post_tags - # changing tags - tags = 'blog, emacs, fun, rails, ruby' - article = MetaWeblogStructs::Article.new(:title => 'This is a title', :description => 'This is a post', :mt_keywords => tags) - args = [ 1, 'quentin', 'test', article, 1 ] - post_id = invoke_layered :metaWeblog, :newPost, *args - - new_post = Article.find(post_id) - assert_equal Tag.parse_to_tags(tags).collect(&:name).sort, new_post.tags.collect(&:name).sort - - tags = 'bar, baz, foo' - article = MetaWeblogStructs::Article.new(:title => 'This is a title', :description => 'This is a post', :mt_keywords => tags) - args = [ post_id, 'quentin', 'test', article, 1] - edit_result = invoke_layered :metaWeblog, :editPost, *args - assert_equal true, edit_result - - new_post = Article.find(post_id) - assert_equal Tag.parse_to_tags(tags).collect(&:name).sort, new_post.tags.collect(&:name).sort - end - - def test_meta_weblog_get_post_with_tags - # set tags and see if we recive them! - tags = 'blog, emacs, fun, rails, ruby' - article = MetaWeblogStructs::Article.new(:title => 'This is a title', :description => 'This is a post', :mt_keywords => tags) - - args = [ 1, 'quentin', 'test', article, 1 ] - post_id = invoke_layered :metaWeblog, :newPost, *args - - args = [ post_id, 'quentin', 'test' ] - result = invoke_layered :metaWeblog, :getPost, *args - - assert_equal tags, result['mt_keywords'] - end - - - def test_meta_weblog_new_post_min - # This is going to test weather a post is correctly submited or not without the published_at field! - # See http://www.xmlrpc.com/metaWeblogApi#theStruct or - # See http://www.sixapart.com/developers/xmlrpc/metaweblog_api/metaweblognewpost.html for more information - assert_difference Article, :count do - article = Article.new - article.title = 'This is a title' - article.body = 'This is a post' - - args = [ 1, 'quentin', 'test', MetaWeblogService.new(@controller).article_dto_from(article), 1 ] - - result = invoke_layered :metaWeblog, :newPost, *args - assert result - new_post = Article.find(result) - - assert_equal 'This is a post', new_post.body - assert_equal '

      This is a post

      ', new_post.body_html - assert_equal 'This is a title', new_post.title - assert_equal :published, new_post.status - end - end - - def test_meta_weblog_new_post_publish - # Test weather publish is set correctly on 1 and true to :published otherwise :pending - [{ :set => 1, :expect => :published }, - { :set => 0, :expect => :pending }, - { :set => true, :expect => :published}, - { :set => false, :expect => :pending }].each do |c| - assert_difference Article, :count do - article = Article.new - article.title = 'This is a title' - article.body = 'This is a post' - - args = [ 1, 'quentin', 'test', MetaWeblogService.new(@controller).article_dto_from(article), c[:set] ] - - result = invoke_layered :metaWeblog, :newPost, *args - assert result - new_post = Article.find(result) - - assert_equal 'This is a post', new_post.body - assert_equal '

      This is a post

      ', new_post.body_html - assert_equal 'This is a title', new_post.title - assert_equal c[:expect], new_post.status - end - end - end - - def test_should_upload_file_via_meta_weblog_new_media_object - now = Time.now.utc - media_object = new_media_object - - args = [ 1, 'quentin', 'test', media_object ] - result = invoke_layered :metaWeblog, :newMediaObject, *args - assert result['url'] =~ /#{media_object['name']}$/ - - assert_file_exists File.join(ASSET_PATH, now.year.to_s, now.month.to_s, now.day.to_s, media_object['name']) - end - - def test_should_guess_content_type_for_gif - media_object = new_media_object 'type' => nil, :name => 'filename.gif' - assert_nil media_object['type'] - - args = [ 1, 'quentin', 'test', media_object ] - result = invoke_layered :metaWeblog, :newMediaObject, *args - - new_asset = Asset.find :first, :order => 'created_at DESC' - assert_equal 'image/gif', new_asset.content_type - end - - def test_should_guess_content_type_for_jpg - media_object = new_media_object 'type' => nil - assert_nil media_object['type'] - - args = [ 1, 'quentin', 'test', media_object ] - result = invoke_layered :metaWeblog, :newMediaObject, *args - - new_asset = Asset.find :first, :order => 'created_at DESC' - assert_equal 'image/jpeg', new_asset.content_type - end - - def test_should_show_filters - result = invoke_layered :mt, :supportedTextFilters - filters = %w(textile_filter markdown_filter smartypants_filter) - result.each { |f| filters.include? f[:key] } - end - - def test_meta_weblog_fail_authentication - args = [ 1, 'quentin', 'using a wrong password', 2 ] - # This will be a little more useful with the upstream changes in [1093] - assert_raise(XMLRPC::FaultException) { invoke_layered :metaWeblog, :getRecentPosts, *args } - end - - protected - - def new_media_object(options = {}) - MetaWeblogStructs::MediaObject.new(options.reverse_merge!( - 'name' => Digest::SHA1.hexdigest("upload-test--#{Time.now}--") + ".jpg", - 'type' => 'image/jpeg', - 'bits' => Base64.encode64(File.open(File.expand_path(RAILS_ROOT) + '/public/images/mephisto/shadow.png', 'rb') { |f| f.read }) - )) - end -end diff -Nur mephisto-0.7.3/test/functional/feed_controller_test.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/test/functional/feed_controller_test.rb --- mephisto-0.7.3/test/functional/feed_controller_test.rb 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/test/functional/feed_controller_test.rb 2008-03-31 02:18:56.000000000 -0400 @@ -12,14 +12,6 @@ @request = ActionController::TestRequest.new @response = ActionController::TestResponse.new end - - def test_feed_assigns - get :feed, :sections => ['about'] - assert_equal sections(:about), assigns(:section) - assert_equal [contents(:welcome), contents(:about), contents(:site_map)], assigns(:articles) - assert_select 'feed>title', 'Mephisto - About' - assert_atom_entries_size 3 - end def test_feed_comes_from_site host! 'cupcake.com' @@ -35,13 +27,12 @@ assert_models_equal [sections(:cupcake_home)], [assigns(:section)] assert_models_equal [contents(:cupcake_welcome)], assigns(:articles) assert_atom_entries_size 1 - assert_tag 'link', :attributes => {:href => 'http://cupcake.com/'} + assert_select 'link[href=?]', 'http://cupcake.com/' end def test_should_return_record_not_found_for_bad_feed_urls - assert_raise ActiveRecord::RecordNotFound do - get :feed, :sections => %w(beastie boys) - end + get :feed, :sections => %w(beastie boys) + assert_equal '404', @response.code end def test_should_find_comments_by_site @@ -61,8 +52,44 @@ end end +context "About Section Feed" do + fixtures :contents, :sections, :assigned_sections, :sites, :users, :assets, :assigned_assets + def setup + @controller = FeedController.new + @request = ActionController::TestRequest.new + @response = ActionController::TestResponse.new + get :feed, :sections => ['about'] + end + + specify "should select correct records" do + assert_equal sections(:about), assigns(:section) + assert_equal [contents(:welcome), contents(:about), contents(:site_map)], assigns(:articles) + end + + specify "should show correct titles" do + assert_select 'feed>title', 'Mephisto - About' + assert_select 'feed>entry>title', 3 do |titles| + assert_equal 'Welcome to Mephisto', titles[0].children.first.content + assert_equal 'About this page', titles[1].children.first.content + assert_equal 'The Site Map', titles[2].children.first.content + end + end + + # TODO: Fails due to asset test deleting asset fixtures + specify "should show correct links" do + return if Asset.count == 1 + assert_select 'feed>link[href=?][type=?]', 'http://test.host/about', 'text/html' + assert_select 'feed>entry>link[href]', 4 do |hrefs| + assert_equal "http://test.host/about", hrefs[0]['href'] + assert_match /asset\.mp3$/, hrefs[1]['href'] + assert_equal "http://test.host/about/about-this-page", hrefs[2]['href'] + assert_equal "http://test.host/about/the-site-map", hrefs[3]['href'] + end + end +end + context "Home Section Feed" do - fixtures :contents, :sections, :assigned_sections, :sites + fixtures :contents, :sections, :assigned_sections, :sites, :assets, :assigned_assets def setup @controller = FeedController.new @request = ActionController::TestRequest.new @@ -72,16 +99,30 @@ end specify "should show titles" do - assert_xpath '/feed/entry[title="Welcome to Mephisto"]' - assert_xpath '/feed/entry[title="Another Welcome to Mephisto"]' + assert_select 'feed>title', 'Mephisto - Home' + assert_select 'feed>entry>title', 2 do |elements| + assert_equal 'Welcome to Mephisto', elements[0].children.first.content + assert_equal 'Another Welcome to Mephisto', elements[1].children.first.content + end end - specify "show absolute urls" do - assert_select 'feed entry link' do - assert_select '[href=?]', /^http\:\/\/test\.host\/\d{4}\/.*$/ + # TODO: Fails due to asset test deleting asset fixtures + specify "should show correct links" do + return if Asset.count == 1 + assert_select 'feed>link[href=?][type=?]', 'http://test.host/', 'text/html' + assert_select 'feed>entry>link[href]', 3 do |hrefs| + assert_match /\/welcome-to-mephisto$/, hrefs[0]['href'] + assert_match /asset\.mp3$/, hrefs[1]['href'] + assert_match /\/another-welcome-to-mephisto$/, hrefs[2]['href'] end end + # TODO: Fails due to asset test deleting asset fixtures + specify "should show podcast" do + return if Asset.count == 1 + assert_select 'feed>entry>link[rel=?][length=?][type=?]', 'enclosure', '252366', 'audio/mpeg' + end + specify "show absolute urls with custom relative url root" do begin old_root = ActionController::AbstractRequest.relative_url_root @@ -103,7 +144,7 @@ specify "should sanitize content" do text = @contents.first.get_text.to_s.strip evil = "linkage

      " - good = "<script>hi</script>linkage

      " + good = %(linkage

      ) assert !text.ends_with(CGI::escapeHTML(evil)), "'#{text.inspect}' was not sanitized" assert text.ends_with(CGI::escapeHTML(good)), "'#{text.inspect}' was not sanitized" end diff -Nur mephisto-0.7.3/test/functional/mephisto_controller_redirections_test.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/test/functional/mephisto_controller_redirections_test.rb --- mephisto-0.7.3/test/functional/mephisto_controller_redirections_test.rb 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/test/functional/mephisto_controller_redirections_test.rb 2008-03-31 02:18:56.000000000 -0400 @@ -11,7 +11,6 @@ @controller = MephistoController.new @request = ActionController::TestRequest.new @response = ActionController::TestResponse.new - host! 'test.com' end specify "should handle denied requests" do diff -Nur mephisto-0.7.3/test/functional/mephisto_controller_test.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/test/functional/mephisto_controller_test.rb --- mephisto-0.7.3/test/functional/mephisto_controller_test.rb 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/test/functional/mephisto_controller_test.rb 2008-03-31 02:18:56.000000000 -0400 @@ -12,7 +12,6 @@ @controller = MephistoController.new @request = ActionController::TestRequest.new @response = ActionController::TestResponse.new - host! 'test.com' end def test_should_list_on_home @@ -108,6 +107,18 @@ assert_dispatch_action :page end + def test_should_not_show_future_page + dispatch 'about/future' + assert_dispatch_action :page + assert_response :missing + end + + def test_should_not_show_draft_page + dispatch 'about/draft' + assert_dispatch_action :page + assert_response :missing + end + def test_should_render_liquid_templates_on_home dispatch assert_tag 'h1', :content => 'This is the layout' @@ -184,27 +195,45 @@ assert_tag :tag => 'h1', :content => "#{contents(:welcome).title} in #{sections(:about).name}" end - def test_should_render_with_alternate_search_layout - sites(:first).update_attribute :search_layout, 'alt_layout.liquid' - dispatch 'search' - assert_dispatch_action :search - assert_preferred_template :search - assert_layout_template :alt_layout - assert_template_type :search - end - def test_should_search_entries dispatch 'search', :q => 'another' assert_dispatch_action :search assert_equal [contents(:another)], assigns(:articles) assert_equal sites(:first).articles_per_page, liquid(:site).before_method(:articles_per_page) assert_equal 'another', liquid(:search_string) + assert_nil liquid(:section) assert_equal 1, liquid(:search_count) assert_preferred_template :search assert_layout_template :layout assert_template_type :search end + def test_should_search_entries_in_section + Section.update_all ['layout = ?', 'alt_layout'], ['id = ?', sections(:about).id] + dispatch 'search', :q => 'welcome', :s => 'about' + assert_dispatch_action :search + assert_equal [contents(:welcome)], assigns(:articles) + assert_equal 'welcome', liquid(:search_string) + assert_equal 1, liquid(:search_count) + assert_equal sections(:about).to_liquid, liquid(:section) + assert_preferred_template :search + assert_layout_template :alt_layout + assert_template_type :search + end + + def test_should_search_entries_in_home_section + Section.update_all ['layout = ?', 'alt_layout'], ['id = ?', sections(:home).id] + dispatch 'search', :q => 'about', :s => '' + assert_dispatch_action :search + assert_equal [], assigns(:articles) + assert_equal 'about', liquid(:search_string) + assert_equal sections(:home).to_liquid, liquid(:section) + assert_equal 0, liquid(:search_count) + assert_preferred_template :search + assert_layout_template :alt_layout + assert_template_type :search + end + def test_should_search_and_not_find_draft dispatch 'search', :q => 'draft' assert_dispatch_action :search @@ -265,7 +294,7 @@ def test_should_show_navigation_on_paged_sections dispatch 'about' assert_tag 'ul', :attributes => { :id => 'nav' }, - :children => { :count => 3, :only => { :tag => 'li' } } + :children => { :count => 5, :only => { :tag => 'li' } } assert_tag 'ul', :attributes => { :id => 'nav' }, :descendant => { :tag => 'a', :attributes => { :class => 'selected' } } assert_tag 'a', :attributes => { :class => 'selected' }, :content => 'Welcome to Mephisto' @@ -273,7 +302,7 @@ def test_should_set_home_page_on_paged_sections dispatch 'about' - assert_equal 3, liquid(:section).pages.size + assert_equal 5, liquid(:section).pages.size [true, false, false].each_with_index do |expected, i| assert_equal expected, liquid(:section).pages[i][:is_page_home] end @@ -301,13 +330,11 @@ end end - def test_should_sanitize_comment + def test_should_sanitize_comment_not_article date = contents(:welcome).published_at dispatch "#{date.year}/#{date.month}/#{date.day}/welcome-to-mephisto" - evil = %(

      rico’s evil and linkage

      ) - good = %(

      rico’s evil <script>hi</script> and linkage

      ) - assert !@response.body.include?(evil), "includes unsanitized code" - assert @response.body.include?(good), "does not include sanitized code" + assert_select "body script", true, "Article can have some " unless @header_red + @header_red = true + @output.puts " " unless @behaviour_red + @behaviour_red = true + move_progress + @output.puts "
      " + @output.puts " #{h(example.description)}" + @output.puts "
      " + @output.puts "
      #{h(failure.exception.message)}
      " unless failure.exception.nil? + @output.puts "
      #{format_backtrace(failure.exception.backtrace)}
      " unless failure.exception.nil? + @output.puts extra unless extra == "" + @output.puts "
      " + @output.puts "
      " + @output.flush + end + + def example_pending(behaviour_name, example_name, message) + @output.puts " " unless @header_red + @output.puts " " unless @behaviour_red + move_progress + @output.puts "
      #{h(example_name)} (PENDING: #{h(message)})
      " + @output.flush + end + + # Override this method if you wish to output extra HTML for a failed spec. For example, you + # could output links to images or other files produced during the specs. + # + def extra_failure_content(failure) + "
      #{@snippet_extractor.snippet(failure.exception)}
      " + end + + def move_progress + @output.puts " " + @output.flush + end + + def percent_done + result = 100.0 + if @example_count != 0 + result = ((current_example_number).to_f / @example_count.to_f * 1000).to_i / 10.0 + end + result + end + + def dump_failure(counter, failure) + end + + def dump_summary(duration, example_count, failure_count, pending_count) + if dry_run? + totals = "This was a dry-run" + else + totals = "#{example_count} example#{'s' unless example_count == 1}, #{failure_count} failure#{'s' unless failure_count == 1}" + totals << ", #{pending_count} pending" if pending_count > 0 + end + @output.puts "" + @output.puts "" + @output.puts "" + @output.puts "" + @output.puts "" + @output.puts "" + @output.flush + end + + def html_header + <<-EOF + + + + + RSpec results + + + + + + +EOF + end + + def report_header + <<-EOF +
      + + + +
      +

      RSpec Results

      + +
      +

       

      +

       

      +
      +
      + +
      +EOF + end + + def global_scripts + <<-EOF +function moveProgressBar(percentDone) { + document.getElementById("rspec-header").style.width = percentDone +"%"; +} +function makeRed(element_id) { + document.getElementById(element_id).style.background = '#C40D0D'; + document.getElementById(element_id).style.color = '#FFFFFF'; +} + +function makeYellow(element_id) { + if (element_id == "rspec-header" && document.getElementById(element_id).style.background != '#C40D0D') + { + document.getElementById(element_id).style.background = '#FAF834'; + document.getElementById(element_id).style.color = '#000000'; + } + else + { + document.getElementById(element_id).style.background = '#FAF834'; + document.getElementById(element_id).style.color = '#000000'; + } +} +EOF + end + + def global_styles + <<-EOF +#rspec-header { + background: #65C400; color: #fff; +} + +.rspec-report h1 { + margin: 0px 10px 0px 10px; + padding: 10px; + font-family: "Lucida Grande", Helvetica, sans-serif; + font-size: 1.8em; +} + +#summary { + margin: 0; padding: 5px 10px; + font-family: "Lucida Grande", Helvetica, sans-serif; + text-align: right; + position: absolute; + top: 0px; + right: 0px; +} + +#summary p { + margin: 0 0 0 2px; +} + +#summary #totals { + font-size: 1.2em; +} + +.behaviour { + margin: 0 10px 5px; + background: #fff; +} + +dl { + margin: 0; padding: 0 0 5px; + font: normal 11px "Lucida Grande", Helvetica, sans-serif; +} + +dt { + padding: 3px; + background: #65C400; + color: #fff; + font-weight: bold; +} + +dd { + margin: 5px 0 5px 5px; + padding: 3px 3px 3px 18px; +} + +dd.spec.passed { + border-left: 5px solid #65C400; + border-bottom: 1px solid #65C400; + background: #DBFFB4; color: #3D7700; +} + +dd.spec.failed { + border-left: 5px solid #C20000; + border-bottom: 1px solid #C20000; + color: #C20000; background: #FFFBD3; +} + +dd.spec.not_implemented { + border-left: 5px solid #FAF834; + border-bottom: 1px solid #FAF834; + background: #FCFB98; color: #131313; +} + +dd.spec.pending_fixed { + border-left: 5px solid #0000C2; + border-bottom: 1px solid #0000C2; + color: #0000C2; background: #D3FBFF; +} + +.backtrace { + color: #000; + font-size: 12px; +} + +a { + color: #BE5C00; +} + +/* Ruby code, style similar to vibrant ink */ +.ruby { + font-size: 12px; + font-family: monospace; + color: white; + background-color: black; + padding: 0.1em 0 0.2em 0; +} + +.ruby .keyword { color: #FF6600; } +.ruby .constant { color: #339999; } +.ruby .attribute { color: white; } +.ruby .global { color: white; } +.ruby .module { color: white; } +.ruby .class { color: white; } +.ruby .string { color: #66FF00; } +.ruby .ident { color: white; } +.ruby .method { color: #FFCC00; } +.ruby .number { color: white; } +.ruby .char { color: white; } +.ruby .comment { color: #9933CC; } +.ruby .symbol { color: white; } +.ruby .regex { color: #44B4CC; } +.ruby .punct { color: white; } +.ruby .escape { color: white; } +.ruby .interp { color: white; } +.ruby .expr { color: white; } + +.ruby .offending { background-color: gray; } +.ruby .linenum { + width: 75px; + padding: 0.1em 1em 0.2em 0; + color: #000000; + background-color: #FFFBD3; +} +EOF + end + end + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/lib/spec/runner/formatter/profile_formatter.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/lib/spec/runner/formatter/profile_formatter.rb --- mephisto-0.7.3/vendor/plugins/rspec/lib/spec/runner/formatter/profile_formatter.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/lib/spec/runner/formatter/profile_formatter.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,45 @@ +module Spec + module Runner + module Formatter + class ProfileFormatter < ProgressBarFormatter + + def initialize(options, where) + super + @examples = [] + end + + def start(count) + @output.puts "Profiling enabled." + end + + def add_example_group(example) + @behaviour = example + end + + def example_started(example) + @time = Time.now + end + + def example_passed(example) + super + @examples << [@behaviour, example, Time.now - @time] + end + + def start_dump + super + @output.puts "\n\nTop 10 slowest examples:\n" + + @examples = @examples.sort_by do |b, e, t| + t + end.reverse + + @examples[0..9].each do |e| + @output.print red(sprintf("%.7f", e[2])) + @output.puts " #{e[0]} #{e[1]}" + end + @output.flush + end + end + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/lib/spec/runner/formatter/progress_bar_formatter.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/lib/spec/runner/formatter/progress_bar_formatter.rb --- mephisto-0.7.3/vendor/plugins/rspec/lib/spec/runner/formatter/progress_bar_formatter.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/lib/spec/runner/formatter/progress_bar_formatter.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,31 @@ +module Spec + module Runner + module Formatter + class ProgressBarFormatter < BaseTextFormatter + def add_example_group(name) + end + + def example_failed(example, counter, failure) + @output.print colourise('F', failure) + @output.flush + end + + def example_passed(example) + @output.print green('.') + @output.flush + end + + def example_pending(behaviour_name, example_name, message) + super + @output.print yellow('P') + @output.flush + end + + def start_dump + @output.puts + @output.flush + end + end + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/lib/spec/runner/formatter/snippet_extractor.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/lib/spec/runner/formatter/snippet_extractor.rb --- mephisto-0.7.3/vendor/plugins/rspec/lib/spec/runner/formatter/snippet_extractor.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/lib/spec/runner/formatter/snippet_extractor.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,52 @@ +module Spec + module Runner + module Formatter + # This class extracts code snippets by looking at the backtrace of the passed error + class SnippetExtractor #:nodoc: + class NullConverter; def convert(code, pre); code; end; end #:nodoc: + begin; require 'rubygems'; require 'syntax/convertors/html'; @@converter = Syntax::Convertors::HTML.for_syntax "ruby"; rescue LoadError => e; @@converter = NullConverter.new; end + + def snippet(error) + raw_code, line = snippet_for(error.backtrace[0]) + highlighted = @@converter.convert(raw_code, false) + highlighted << "\n# gem install syntax to get syntax highlighting" if @@converter.is_a?(NullConverter) + post_process(highlighted, line) + end + + def snippet_for(error_line) + if error_line =~ /(.*):(\d+)/ + file = $1 + line = $2.to_i + [lines_around(file, line), line] + else + ["# Couldn't get snippet for #{error_line}", 1] + end + end + + def lines_around(file, line) + if File.file?(file) + lines = File.open(file).read.split("\n") + min = [0, line-3].max + max = [line+1, lines.length-1].min + selected_lines = [] + selected_lines.join("\n") + lines[min..max].join("\n") + else + "# Couldn't get snippet for #{file}" + end + end + + def post_process(highlighted, offending_line) + new_lines = [] + highlighted.split("\n").each_with_index do |line, i| + new_line = "#{offending_line+i-2}#{line}" + new_line = "#{new_line}" if i == 2 + new_lines << new_line + end + new_lines.join("\n") + end + + end + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/lib/spec/runner/formatter/specdoc_formatter.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/lib/spec/runner/formatter/specdoc_formatter.rb --- mephisto-0.7.3/vendor/plugins/rspec/lib/spec/runner/formatter/specdoc_formatter.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/lib/spec/runner/formatter/specdoc_formatter.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,36 @@ +module Spec + module Runner + module Formatter + class SpecdocFormatter < BaseTextFormatter + def add_example_group(name) + @output.puts + @output.puts name + @output.flush + end + + def example_failed(example, counter, failure) + message = if failure.expectation_not_met? + "- #{example.description} (FAILED - #{counter})" + else + "- #{example.description} (ERROR - #{counter})" + end + + @output.puts(failure.expectation_not_met? ? red(message) : magenta(message)) + @output.flush + end + + def example_passed(example) + message = "- #{example.description}" + @output.puts green(message) + @output.flush + end + + def example_pending(behaviour_name, example_name, message) + super + @output.puts yellow("- #{example_name} (PENDING: #{message})") + @output.flush + end + end + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/lib/spec/runner/formatter/story/html_formatter.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/lib/spec/runner/formatter/story/html_formatter.rb --- mephisto-0.7.3/vendor/plugins/rspec/lib/spec/runner/formatter/story/html_formatter.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/lib/spec/runner/formatter/story/html_formatter.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,123 @@ +require 'erb' + +module Spec + module Runner + module Formatter + module Story + class HtmlFormatter < BaseTextFormatter + include ERB::Util + + def run_started(count) + @output.puts <<-EOF + + + + + Stories + + + + + + + + + +
      +EOF + end + + def collected_steps(steps) + unless steps.empty? + @output.puts "
        " + steps.each do |step| + @output.puts "
      • #{step}
      • " + end + @output.puts "
      " + end + end + + def run_ended + @output.puts <<-EOF +
      + + +EOF + end + + def story_started(title, narrative) + @output.puts <<-EOF +
      +
      #{h title}
      +
      +

      + #{h(narrative).split("\n").join("
      ")} +

      +EOF + end + + def story_ended(title, narrative) + @output.puts <<-EOF +
      +
      +EOF + end + + def scenario_started(story_title, scenario_name) + @output.puts <<-EOF +
      +
      #{h scenario_name}
      +
      +
        +EOF + end + + def scenario_ended + @output.puts <<-EOF +
      +
      +
      +EOF + end + + def found_scenario(type, description) + end + + def scenario_succeeded(story_title, scenario_name) + scenario_ended + end + + def scenario_pending(story_title, scenario_name, reason) + scenario_ended + end + + def scenario_failed(story_title, scenario_name, err) + scenario_ended + end + + def step_succeeded(type, description, *args) + print_step('passed', type, description, *args) # TODO: uses succeeded CSS class + end + + def step_pending(type, description, *args) + print_step('pending', type, description, *args) + end + + def step_failed(type, description, *args) + print_step('failed', type, description, *args) + end + + def print_step(klass, type, description, *args) + spans = args.map { |arg| "#{arg}" } + i = -1 + inner = type.to_s.capitalize + ' ' + description.gsub(::Spec::Story::Step::PARAM_PATTERN) { |param| spans[i+=1] } + @output.puts "
    • #{inner}
    • " + end + + end + end + end + end +end \ No newline at end of file diff -Nur mephisto-0.7.3/vendor/plugins/rspec/lib/spec/runner/formatter/story/plain_text_formatter.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/lib/spec/runner/formatter/story/plain_text_formatter.rb --- mephisto-0.7.3/vendor/plugins/rspec/lib/spec/runner/formatter/story/plain_text_formatter.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/lib/spec/runner/formatter/story/plain_text_formatter.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,117 @@ +module Spec + module Runner + module Formatter + module Story + class PlainTextFormatter < BaseTextFormatter + def initialize(options, where) + super + @successful_scenario_count = 0 + @pending_scenario_count = 0 + @failed_scenarios = [] + @pending_steps = [] + @previous_type = nil + end + + def run_started(count) + @count = count + @output.puts "Running #@count scenarios:\n" + end + + def story_started(title, narrative) + @output.puts "Story: #{title}\n\n" + narrative.each_line do |line| + @output.print " " + @output.print line + end + end + + def story_ended(title, narrative) + @output.puts + @output.puts + end + + def scenario_started(story_title, scenario_name) + @scenario_already_failed = false + @output.print "\n\nScenario: #{scenario_name}" + @scenario_ok = true + end + + def scenario_succeeded(story_title, scenario_name) + @successful_scenario_count += 1 + end + + def scenario_failed(story_title, scenario_name, err) + @failed_scenarios << [story_title, scenario_name, err] unless @scenario_already_failed + @scenario_already_failed = true + end + + def scenario_pending(story_title, scenario_name, msg) + @pending_steps << [story_title, scenario_name, msg] + @pending_scenario_count += 1 unless @scenario_already_failed + @scenario_already_failed = true + end + + def run_ended + @output.puts "\n\n#@count scenarios: #@successful_scenario_count succeeded, #{@failed_scenarios.size} failed, #@pending_scenario_count pending" + unless @pending_steps.empty? + @output.puts "\nPending Steps:" + @pending_steps.each_with_index do |pending, i| + title, scenario_name, msg = pending + @output.puts "#{i+1}) #{title} (#{scenario_name}): #{msg}" + end + end + unless @failed_scenarios.empty? + @output.print "\nFAILURES:" + @failed_scenarios.each_with_index do |failure, i| + title, scenario_name, err = failure + @output.print %[ + #{i+1}) #{title} (#{scenario_name}) FAILED + #{err.class}: #{err.message} + #{err.backtrace.join("\n")} + ] + end + end + end + + def step_succeeded(type, description, *args) + found_step(type, description, false, *args) + end + + def step_pending(type, description, *args) + found_step(type, description, false, *args) + @output.print " (PENDING)" + @scenario_ok = false + end + + def step_failed(type, description, *args) + found_step(type, description, true, *args) + @output.print red(@scenario_ok ? " (FAILED)" : " (SKIPPED)") + @scenario_ok = false + end + + def collected_steps(steps) + end + + private + + def found_step(type, description, failed, *args) + text = if(type == @previous_type) + "\n And " + else + "\n\n #{type.to_s.capitalize} " + end + i = -1 + text << description.gsub(::Spec::Story::Step::PARAM_PATTERN) { |param| args[i+=1] } + @output.print(failed ? red(text) : green(text)) + + if type == :'given scenario' + @previous_type = :given + else + @previous_type = type + end + end + end + end + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/lib/spec/runner/formatter/story.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/lib/spec/runner/formatter/story.rb --- mephisto-0.7.3/vendor/plugins/rspec/lib/spec/runner/formatter/story.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/lib/spec/runner/formatter/story.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,2 @@ +require 'spec/runner/formatter/story/plain_text_formatter' +require 'spec/runner/formatter/story/html_formatter' diff -Nur mephisto-0.7.3/vendor/plugins/rspec/lib/spec/runner/formatter/text_mate_formatter.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/lib/spec/runner/formatter/text_mate_formatter.rb --- mephisto-0.7.3/vendor/plugins/rspec/lib/spec/runner/formatter/text_mate_formatter.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/lib/spec/runner/formatter/text_mate_formatter.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,16 @@ +require 'spec/runner/formatter/html_formatter' + +module Spec + module Runner + module Formatter + # Formats backtraces so they're clickable by TextMate + class TextMateFormatter < HtmlFormatter + def backtrace_line(line) + line.gsub(/([^:]*\.rb):(\d*)/) do + "#{$1}:#{$2} " + end + end + end + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/lib/spec/runner/formatter.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/lib/spec/runner/formatter.rb --- mephisto-0.7.3/vendor/plugins/rspec/lib/spec/runner/formatter.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/lib/spec/runner/formatter.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,11 @@ +require 'spec/runner/formatter/base_formatter' +require 'spec/runner/formatter/base_text_formatter' +require 'spec/runner/formatter/progress_bar_formatter' +require 'spec/runner/formatter/specdoc_formatter' +require 'spec/runner/formatter/html_formatter' +require 'spec/runner/formatter/text_mate_formatter' +require 'spec/runner/formatter/failing_examples_formatter' +require 'spec/runner/formatter/failing_behaviours_formatter' +require 'spec/runner/formatter/snippet_extractor' +require 'spec/runner/formatter/profile_formatter' +require 'spec/runner/formatter/story' diff -Nur mephisto-0.7.3/vendor/plugins/rspec/lib/spec/runner/heckle_runner.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/lib/spec/runner/heckle_runner.rb --- mephisto-0.7.3/vendor/plugins/rspec/lib/spec/runner/heckle_runner.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/lib/spec/runner/heckle_runner.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,72 @@ +begin + require 'rubygems' + require 'heckle' +rescue LoadError ; raise "You must gem install heckle to use --heckle" ; end + +module Spec + module Runner + # Creates a new Heckler configured to heckle all methods in the classes + # whose name matches +filter+ + class HeckleRunner + def initialize(filter, heckle_class=Heckler) + @filter = filter + @heckle_class = heckle_class + end + + # Runs all the behaviours held by +rspec_options+ once for each of the + # methods in the matched classes. + def heckle_with + if @filter =~ /(.*)[#\.](.*)/ + heckle_method($1, $2) + else + heckle_class_or_module(@filter) + end + end + + def heckle_method(class_name, method_name) + verify_constant(class_name) + heckle = @heckle_class.new(class_name, method_name, rspec_options) + heckle.validate + end + + def heckle_class_or_module(class_or_module_name) + verify_constant(class_or_module_name) + pattern = /^#{class_or_module_name}/ + classes = [] + ObjectSpace.each_object(Class) do |klass| + classes << klass if klass.name =~ pattern + end + + classes.each do |klass| + klass.instance_methods(false).each do |method_name| + heckle = @heckle_class.new(klass.name, method_name, rspec_options) + heckle.validate + end + end + end + + def verify_constant(name) + begin + # This is defined in Heckle + name.to_class + rescue + raise "Heckling failed - \"#{name}\" is not a known class or module" + end + end + end + + #Supports Heckle 1.2 and prior (earlier versions used Heckle::Base) + class Heckler < (Heckle.const_defined?(:Base) ? Heckle::Base : Heckle) + def initialize(klass_name, method_name, rspec_options) + super(klass_name, method_name) + @rspec_options = rspec_options + end + + def tests_pass? + success = @rspec_options.run_examples + success + end + + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/lib/spec/runner/heckle_runner_unsupported.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/lib/spec/runner/heckle_runner_unsupported.rb --- mephisto-0.7.3/vendor/plugins/rspec/lib/spec/runner/heckle_runner_unsupported.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/lib/spec/runner/heckle_runner_unsupported.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,10 @@ +module Spec + module Runner + # Dummy implementation for Windows that just fails (Heckle is not supported on Windows) + class HeckleRunner + def initialize(filter) + raise "Heckle not supported on Windows" + end + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/lib/spec/runner/option_parser.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/lib/spec/runner/option_parser.rb --- mephisto-0.7.3/vendor/plugins/rspec/lib/spec/runner/option_parser.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/lib/spec/runner/option_parser.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,225 @@ +require 'optparse' +require 'stringio' + +module Spec + module Runner + class OptionParser < ::OptionParser + class << self + def parse(args, err, out) + parser = new(err, out) + parser.parse(args) + parser.options + end + end + + attr_reader :options + + OPTIONS = { + :diff => ["-D", "--diff [FORMAT]", "Show diff of objects that are expected to be equal when they are not", + "Builtin formats: unified|u|context|c", + "You can also specify a custom differ class", + "(in which case you should also specify --require)"], + :colour => ["-c", "--colour", "--color", "Show coloured (red/green) output"], + :example => ["-e", "--example [NAME|FILE_NAME]", "Execute example(s) with matching name(s). If the argument is", + "the path to an existing file (typically generated by a previous", + "run using --format failing_examples:file.txt), then the examples", + "on each line of thatfile will be executed. If the file is empty,", + "all examples will be run (as if --example was not specified).", + " ", + "If the argument is not an existing file, then it is treated as", + "an example name directly, causing RSpec to run just the example", + "matching that name"], + :specification => ["-s", "--specification [NAME]", "DEPRECATED - use -e instead", "(This will be removed when autotest works with -e)"], + :line => ["-l", "--line LINE_NUMBER", Integer, "Execute behaviout or specification at given line.", + "(does not work for dynamically generated specs)"], + :format => ["-f", "--format FORMAT[:WHERE]", "Specifies what format to use for output. Specify WHERE to tell", + "the formatter where to write the output. All built-in formats", + "expect WHERE to be a file name, and will write to STDOUT if it's", + "not specified. The --format option may be specified several times", + "if you want several outputs", + " ", + "Builtin formats: ", + "progress|p : Text progress", + "profile|o : Text progress with profiling of 10 slowest examples", + "specdoc|s : Example doc as text", + "html|h : A nice HTML report", + "failing_examples|e : Write all failing examples - input for --example", + "failing_behaviours|b : Write all failing behaviours - input for --example", + " ", + "FORMAT can also be the name of a custom formatter class", + "(in which case you should also specify --require to load it)"], + :require => ["-r", "--require FILE", "Require FILE before running specs", + "Useful for loading custom formatters or other extensions.", + "If this option is used it must come before the others"], + :backtrace => ["-b", "--backtrace", "Output full backtrace"], + :loadby => ["-L", "--loadby STRATEGY", "Specify the strategy by which spec files should be loaded.", + "STRATEGY can currently only be 'mtime' (File modification time)", + "By default, spec files are loaded in alphabetical order if --loadby", + "is not specified."], + :reverse => ["-R", "--reverse", "Run examples in reverse order"], + :timeout => ["-t", "--timeout FLOAT", "Interrupt and fail each example that doesn't complete in the", + "specified time"], + :heckle => ["-H", "--heckle CODE", "If all examples pass, this will mutate the classes and methods", + "identified by CODE little by little and run all the examples again", + "for each mutation. The intent is that for each mutation, at least", + "one example *should* fail, and RSpec will tell you if this is not the", + "case. CODE should be either Some::Module, Some::Class or", + "Some::Fabulous#method}"], + :dry_run => ["-d", "--dry-run", "Invokes formatters without executing the examples."], + :options_file => ["-O", "--options PATH", "Read options from a file"], + :generate_options => ["-G", "--generate-options PATH", "Generate an options file for --options"], + :runner => ["-U", "--runner RUNNER", "Use a custom Runner."], + :drb => ["-X", "--drb", "Run examples via DRb. (For example against script/spec_server)"], + :version => ["-v", "--version", "Show version"], + :help => ["-h", "--help", "You're looking at it"] + } + + def initialize(err, out) + super() + @error_stream = err + @out_stream = out + @options = Options.new(@error_stream, @out_stream) + + @spec_parser = SpecParser.new + @file_factory = File + + self.banner = "Usage: spec (FILE|DIRECTORY|GLOB)+ [options]" + self.separator "" + on(*OPTIONS[:diff]) {|diff| @options.parse_diff(diff)} + on(*OPTIONS[:colour]) {@options.colour = true} + on(*OPTIONS[:example]) {|example| @options.parse_example(example)} + on(*OPTIONS[:specification]) {|example| @options.parse_example(example)} + on(*OPTIONS[:line]) {|line_number| @options.line_number = line_number.to_i} + on(*OPTIONS[:format]) {|format| @options.parse_format(format)} + on(*OPTIONS[:require]) {|requires| invoke_requires(requires)} + on(*OPTIONS[:backtrace]) {@options.backtrace_tweaker = NoisyBacktraceTweaker.new} + on(*OPTIONS[:loadby]) {|loadby| @options.loadby = loadby} + on(*OPTIONS[:reverse]) {@options.reverse = true} + on(*OPTIONS[:timeout]) {|timeout| @options.timeout = timeout.to_f} + on(*OPTIONS[:heckle]) {|heckle| @options.load_heckle_runner(heckle)} + on(*OPTIONS[:dry_run]) {@options.dry_run = true} + on(*OPTIONS[:options_file]) {|options_file| parse_options_file(options_file)} + on(*OPTIONS[:generate_options]) do |options_file| + end + on(*OPTIONS[:runner]) do |runner| + @options.user_input_for_runner = runner + end + on(*OPTIONS[:drb]) {} + on(*OPTIONS[:version]) {parse_version} + on_tail(*OPTIONS[:help]) {parse_help} + end + + def order!(argv, &blk) + @argv = argv + @options.argv = @argv.dup + return if parse_generate_options + return if parse_drb + + super(@argv) do |file| + @options.files << file + blk.call(file) if blk + end + + if @options.line_number + set_spec_from_line_number + end + + @options + end + + protected + def invoke_requires(requires) + requires.split(",").each do |file| + require file + end + end + + def parse_options_file(options_file) + option_file_args = IO.readlines(options_file).map {|l| l.chomp.split " "}.flatten + @argv.push(*option_file_args) + end + + def parse_generate_options + # Remove the --generate-options option and the argument before writing to file + options_file = nil + ['-G', '--generate-options'].each do |option| + if index = @argv.index(option) + @argv.delete_at(index) + options_file = @argv.delete_at(index) + end + end + + if options_file + write_generated_options(options_file) + return true + else + return false + end + end + + def write_generated_options(options_file) + File.open(options_file, 'w') do |io| + io.puts @argv.join("\n") + end + @out_stream.puts "\nOptions written to #{options_file}. You can now use these options with:" + @out_stream.puts "spec --options #{options_file}" + @options.examples_should_not_be_run + end + + def parse_drb + is_drb = false + argv = @options.argv + is_drb ||= argv.delete(OPTIONS[:drb][0]) + is_drb ||= argv.delete(OPTIONS[:drb][1]) + return nil unless is_drb + @options.examples_should_not_be_run + DrbCommandLine.run( + self.class.parse(argv, @error_stream, @out_stream) + ) + true + end + + def parse_version + @out_stream.puts ::Spec::VERSION::DESCRIPTION + exit if stdout? + end + + def parse_help + @out_stream.puts self + exit if stdout? + end + + def set_spec_from_line_number + if @options.examples.empty? + if @options.files.length == 1 + if @file_factory.file?(@options.files[0]) + source = @file_factory.open(@options.files[0]) + example = @spec_parser.spec_name_for(source, @options.line_number) + @options.parse_example(example) + elsif @file_factory.directory?(@options.files[0]) + @error_stream.puts "You must specify one file, not a directory when using the --line option" + exit(1) if stderr? + else + @error_stream.puts "#{@options.files[0]} does not exist" + exit(2) if stderr? + end + else + @error_stream.puts "Only one file can be specified when using the --line option: #{@options.files.inspect}" + exit(3) if stderr? + end + else + @error_stream.puts "You cannot use both --line and --example" + exit(4) if stderr? + end + end + + def stdout? + @out_stream == $stdout + end + + def stderr? + @error_stream == $stderr + end + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/lib/spec/runner/options.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/lib/spec/runner/options.rb --- mephisto-0.7.3/vendor/plugins/rspec/lib/spec/runner/options.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/lib/spec/runner/options.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,245 @@ +module Spec + module Runner + class Options + FILE_SORTERS = { + 'mtime' => lambda {|file_a, file_b| File.mtime(file_b) <=> File.mtime(file_a)} + } + + EXAMPLE_FORMATTERS = { + 'specdoc' => Formatter::SpecdocFormatter, + 's' => Formatter::SpecdocFormatter, + 'html' => Formatter::HtmlFormatter, + 'h' => Formatter::HtmlFormatter, + 'progress' => Formatter::ProgressBarFormatter, + 'p' => Formatter::ProgressBarFormatter, + 'failing_examples' => Formatter::FailingExamplesFormatter, + 'e' => Formatter::FailingExamplesFormatter, + 'failing_behaviours' => Formatter::FailingBehavioursFormatter, + 'b' => Formatter::FailingBehavioursFormatter, + 'profile' => Formatter::ProfileFormatter, + 'o' => Formatter::ProfileFormatter, + 'textmate' => Formatter::TextMateFormatter, + } + + STORY_FORMATTERS = { + 'plain' => Formatter::Story::PlainTextFormatter, + 'html' => Formatter::Story::HtmlFormatter, + 'h' => Formatter::Story::HtmlFormatter + } + + attr_accessor( + :backtrace_tweaker, + :context_lines, + :diff_format, + :dry_run, + :profile, + :examples, + :heckle_runner, + :line_number, + :loadby, + :reporter, + :reverse, + :timeout, + :verbose, + :user_input_for_runner, + :error_stream, + :output_stream, + # TODO: BT - Figure out a better name + :argv + ) + attr_reader :colour, :differ_class, :files, :example_groups + + def initialize(error_stream, output_stream) + @error_stream = error_stream + @output_stream = output_stream + @backtrace_tweaker = QuietBacktraceTweaker.new + @examples = [] + @colour = false + @profile = false + @dry_run = false + @reporter = Reporter.new(self) + @context_lines = 3 + @diff_format = :unified + @files = [] + @example_groups = [] + @user_input_for_runner = nil + @examples_run = false + end + + def add_example_group(example_group) + @example_groups << example_group + end + + def remove_example_group(example_group) + @example_groups.delete(example_group) + end + + def run_examples + return true unless examples_should_be_run? + runner = custom_runner || ExampleGroupRunner.new(self) + + runner.load_files(files_to_load) + if example_groups.empty? + true + else + success = runner.run + @examples_run = true + heckle if heckle_runner + success + end + end + + def examples_run? + @examples_run + end + + def examples_should_not_be_run + @examples_should_be_run = false + end + + def colour=(colour) + @colour = colour + begin; \ + require 'Win32/Console/ANSI' if @colour && PLATFORM =~ /win32/; \ + rescue LoadError ; \ + raise "You must gem install win32console to use colour on Windows" ; \ + end + end + + def parse_diff(format) + case format + when :context, 'context', 'c' + @diff_format = :context + default_differ + when :unified, 'unified', 'u', '', nil + @diff_format = :unified + default_differ + else + @diff_format = :custom + self.differ_class = load_class(format, 'differ', '--diff') + end + end + + def parse_example(example) + if(File.file?(example)) + @examples = File.open(example).read.split("\n") + else + @examples = [example] + end + end + + def parse_format(format_arg) + format, where = ClassAndArgumentsParser.parse(format_arg) + unless where + raise "When using several --format options only one of them can be without a file" if @out_used + where = @output_stream + @out_used = true + end + @format_options ||= [] + @format_options << [format, where] + end + + def formatters + @format_options ||= [['progress', @output_stream]] + @formatters ||= @format_options.map do |format, where| + formatter_type = EXAMPLE_FORMATTERS[format] || load_class(format, 'formatter', '--format') + formatter_type.new(self, where) + end + end + + def story_formatters + @format_options ||= [['plain', @output_stream]] + @story_formatters ||= @format_options.map do |format, where| + formatter_type = STORY_FORMATTERS[format] || load_class(format, 'formatter', '--format') + formatter_type.new(self, where) + end + end + + def load_heckle_runner(heckle) + suffix = [/mswin/, /java/].detect{|p| p =~ RUBY_PLATFORM} ? '_unsupported' : '' + require "spec/runner/heckle_runner#{suffix}" + @heckle_runner = HeckleRunner.new(heckle) + end + + def number_of_examples + @example_groups.inject(0) do |sum, example_group| + sum + example_group.number_of_examples + end + end + + protected + def examples_should_be_run? + return @examples_should_be_run unless @examples_should_be_run.nil? + @examples_should_be_run = true + end + + def differ_class=(klass) + return unless klass + @differ_class = klass + Spec::Expectations.differ = self.differ_class.new(self) + end + + def load_class(name, kind, option) + if name =~ /\A(?:::)?([A-Z]\w*(?:::[A-Z]\w*)*)\z/ + arg = $2 == "" ? nil : $2 + [$1, arg] + else + m = "#{name.inspect} is not a valid class name" + @error_stream.puts m + raise m + end + begin + eval(name, binding, __FILE__, __LINE__) + rescue NameError => e + @error_stream.puts "Couldn't find #{kind} class #{name}" + @error_stream.puts "Make sure the --require option is specified *before* #{option}" + if $_spec_spec ; raise e ; else exit(1) ; end + end + end + + def files_to_load + result = [] + sorted_files.each do |file| + if test ?d, file + result += Dir[File.expand_path("#{file}/**/*.rb")] + elsif test ?f, file + result << file + else + raise "File or directory not found: #{file}" + end + end + result + end + + def custom_runner + return nil unless custom_runner? + klass_name, arg = ClassAndArgumentsParser.parse(user_input_for_runner) + runner_type = load_class(klass_name, 'behaviour runner', '--runner') + return runner_type.new(self, arg) + end + + def custom_runner? + return user_input_for_runner ? true : false + end + + def heckle + returns = self.heckle_runner.heckle_with + self.heckle_runner = nil + returns + end + + def sorted_files + return sorter ? files.sort(&sorter) : files + end + + def sorter + FILE_SORTERS[loadby] + end + + def default_differ + require 'spec/expectations/differs/default' + self.differ_class = Spec::Expectations::Differs::Default + end + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/lib/spec/runner/reporter.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/lib/spec/runner/reporter.rb --- mephisto-0.7.3/vendor/plugins/rspec/lib/spec/runner/reporter.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/lib/spec/runner/reporter.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,136 @@ +module Spec + module Runner + class Reporter + attr_reader :options + + def initialize(options) + @options = options + @options.reporter = self + clear + end + + def add_example_group(name) + formatters.each{|f| f.add_example_group(name)} + @example_group_names << name + end + + def example_started(example) + formatters.each{|f| f.example_started(example)} + end + + def example_finished(example, error=nil, failure_location=nil, pending=false) + @examples << example + + if error.nil? + example_passed(example) + elsif Spec::Example::ExamplePendingError === error + example_pending(@example_group_names.last, example, error.message) + else + example_failed(example, error, failure_location) + end + end + + def start(number_of_examples) + clear + @start_time = Time.new + formatters.each{|f| f.start(number_of_examples)} + end + + def end + @end_time = Time.new + end + + # Dumps the summary and returns the total number of failures + def dump + formatters.each{|f| f.start_dump} + dump_pending + dump_failures + formatters.each do |f| + f.dump_summary(duration, @examples.length, @failures.length, @pending_count) + f.close + end + @failures.length + end + + private + + def formatters + @options.formatters + end + + def backtrace_tweaker + @options.backtrace_tweaker + end + + def clear + @example_group_names = [] + @failures = [] + @pending_count = 0 + @examples = [] + @start_time = nil + @end_time = nil + end + + def dump_failures + return if @failures.empty? + @failures.inject(1) do |index, failure| + formatters.each{|f| f.dump_failure(index, failure)} + index + 1 + end + end + def dump_pending + formatters.each{|f| f.dump_pending} + end + + def duration + return @end_time - @start_time unless (@end_time.nil? or @start_time.nil?) + return "0.0" + end + + def example_passed(name) + formatters.each{|f| f.example_passed(name)} + end + + def example_failed(name, error, failure_location) + backtrace_tweaker.tweak_backtrace(error, failure_location) + example_name = "#{@example_group_names.last} #{name}" + failure = Failure.new(example_name, error) + @failures << failure + formatters.each{|f| f.example_failed(name, @failures.length, failure)} + end + + def example_pending(behaviour_name, example_name, message="Not Yet Implemented") + @pending_count += 1 + formatters.each{|f| f.example_pending(behaviour_name, example_name, message)} + end + + class Failure + attr_reader :exception + + def initialize(example_name, exception) + @example_name = example_name + @exception = exception + end + + def header + if expectation_not_met? + "'#{@example_name}' FAILED" + elsif pending_fixed? + "'#{@example_name}' FIXED" + else + "#{@exception.class.name} in '#{@example_name}'" + end + end + + def pending_fixed? + @exception.is_a?(Spec::Example::PendingExampleFixedError) + end + + def expectation_not_met? + @exception.is_a?(Spec::Expectations::ExpectationNotMetError) + end + + end + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/lib/spec/runner/spec_parser.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/lib/spec/runner/spec_parser.rb --- mephisto-0.7.3/vendor/plugins/rspec/lib/spec/runner/spec_parser.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/lib/spec/runner/spec_parser.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,53 @@ +module Spec + module Runner + # Parses a spec file and finds the nearest example for a given line number. + class SpecParser + def spec_name_for(io, line_number) + source = io.read + behaviour, behaviour_line = behaviour_at_line(source, line_number) + example, example_line = example_at_line(source, line_number) + if behaviour && example && (behaviour_line < example_line) + "#{behaviour} #{example}" + elsif behaviour + behaviour + else + nil + end + end + + protected + + def behaviour_at_line(source, line_number) + find_above(source, line_number, /^\s*(context|describe)\s+(.*)\s+do/) + end + + def example_at_line(source, line_number) + find_above(source, line_number, /^\s*(specify|it)\s+(.*)\s+do/) + end + + # Returns the context/describe or specify/it name and the line number + def find_above(source, line_number, pattern) + lines_above_reversed(source, line_number).each_with_index do |line, n| + return [parse_description($2), line_number-n] if line =~ pattern + end + nil + end + + def lines_above_reversed(source, line_number) + lines = source.split("\n") + lines[0...line_number].reverse + end + + def parse_description(str) + return str[1..-2] if str =~ /^['"].*['"]$/ + if matches = /^['"](.*)['"](,.*)?$/.match(str) + return ::Spec::Example::ExampleGroupDescription.generate_description(matches[1]) + end + if matches = /^(.*)\s*,\s*['"](.*)['"](,.*)?$/.match(str) + return ::Spec::Example::ExampleGroupDescription.generate_description(matches[1], matches[2]) + end + return str + end + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/lib/spec/runner.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/lib/spec/runner.rb --- mephisto-0.7.3/vendor/plugins/rspec/lib/spec/runner.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/lib/spec/runner.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,190 @@ +require 'spec/runner/formatter' +require 'spec/runner/options' +require 'spec/runner/option_parser' +require 'spec/runner/example_group_runner' +require 'spec/runner/command_line' +require 'spec/runner/drb_command_line' +require 'spec/runner/backtrace_tweaker' +require 'spec/runner/reporter' +require 'spec/runner/extensions/object' +require 'spec/runner/spec_parser' +require 'spec/runner/class_and_arguments_parser' + +module Spec + # == Behaviours and Examples + # + # Rather than expressing examples in classes, RSpec uses a custom domain specific language to + # describe Behaviours and Examples of those behaviours. + # + # A Example is the equivalent of a fixture in xUnit-speak. It is a metaphor for the context + # in which you will run your executable example - a set of known objects in a known starting state. + # We begin be describing + # + # describe Account do + # + # before do + # @account = Account.new + # end + # + # it "should have a balance of $0" do + # @account.balance.should == Money.new(0, :dollars) + # end + # + # end + # + # We use the before block to set up the Example (given), and then the #it method to + # hold the example code that expresses the event (when) and the expected outcome (then). + # + # == Helper Methods + # + # A primary goal of RSpec is to keep the examples clear. We therefore prefer + # less indirection than you might see in xUnit examples and in well factored, DRY production code. We feel + # that duplication is OK if removing it makes it harder to understand an example without + # having to look elsewhere to understand its context. + # + # That said, RSpec does support some level of encapsulating common code in helper + # methods that can exist within a context or within an included module. + # + # == Setup and Teardown + # + # You can use before and after within a Example. Both methods take an optional + # scope argument so you can run the block before :each example or before :all examples + # + # describe "..." do + # before :all do + # ... + # end + # + # before :each do + # ... + # end + # + # it "should do something" do + # ... + # end + # + # it "should do something else" do + # ... + # end + # + # after :each do + # ... + # end + # + # after :all do + # ... + # end + # + # end + # + # The before :each block will run before each of the examples, once for each example. Likewise, + # the after :each block will run after each of the examples. + # + # It is also possible to specify a before :all and after :all + # block that will run only once for each behaviour, respectively before the first before :each + # and after the last after :each. The use of these is generally discouraged, because it + # introduces dependencies between the examples. Still, it might prove useful for very expensive operations + # if you know what you are doing. + # + # == Local helper methods + # + # You can include local helper methods by simply expressing them within a context: + # + # describe "..." do + # + # it "..." do + # helper_method + # end + # + # def helper_method + # ... + # end + # + # end + # + # == Included helper methods + # + # You can include helper methods in multiple contexts by expressing them within + # a module, and then including that module in your context: + # + # module AccountExampleHelperMethods + # def helper_method + # ... + # end + # end + # + # describe "A new account" do + # include AccountExampleHelperMethods + # before do + # @account = Account.new + # end + # + # it "should have a balance of $0" do + # helper_method + # @account.balance.should eql(Money.new(0, :dollars)) + # end + # end + # + # == Shared behaviour + # + # You can define a shared behaviour, that may be used on other behaviours + # + # describe "All Editions", :shared => true do + # it "all editions behaviour" ... + # end + # + # describe SmallEdition do + # it_should_behave_like "All Editions" + # + # it "should do small edition stuff" do + # ... + # end + # end + # + # You can also assign the shared behaviour to a module and include that + # + # AllEditions = describe "All Editions", :shared => true do + # it "all editions behaviour" ... + # end + # + # describe SmallEdition do + # it_should_behave_like AllEditions + # + # it "should do small edition stuff" do + # ... + # end + # end + # + # And, for those of you who prefer to use something more like Ruby, you + # can just include the module directly + # + # describe SmallEdition do + # include AllEditions + # + # it "should do small edition stuff" do + # ... + # end + # end + module Runner + class << self + def configuration # :nodoc: + @configuration ||= Spec::Example::Configuration.new + end + + # Use this to configure various configurable aspects of + # RSpec: + # + # Spec::Runner.configure do |configuration| + # # Configure RSpec here + # end + # + # The yielded configuration object is a + # Spec::Example::Configuration instance. See its RDoc + # for details about what you can do with it. + # + def configure + yield configuration + end + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/lib/spec/story/extensions/main.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/lib/spec/story/extensions/main.rb --- mephisto-0.7.3/vendor/plugins/rspec/lib/spec/story/extensions/main.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/lib/spec/story/extensions/main.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,86 @@ +module Spec + module Story + module Extensions + module Main + def Story(title, narrative, params = {}, &body) + ::Spec::Story::Runner.story_runner.Story(title, narrative, params, &body) + end + + # Calling this deprecated is silly, since it hasn't been released yet. But, for + # those who are reading this - this will be deleted before the 1.1 release. + def run_story(*args, &block) + runner = Spec::Story::Runner::PlainTextStoryRunner.new(*args) + runner.instance_eval(&block) if block + runner.run + end + + # Creates (or appends to an existing) a namespaced group of steps for use in Stories + # + # == Examples + # + # # Creating a new group + # steps_for :forms do + # When("user enters $value in the $field field") do ... end + # When("user submits the $form form") do ... end + # end + def steps_for(tag, &block) + steps = rspec_story_steps[tag] + steps.instance_eval(&block) if block + steps + end + + # Creates a context for running a Plain Text Story with specific groups of Steps. + # Also supports adding arbitrary steps that will only be accessible to + # the Story being run. + # + # == Examples + # + # # Run a Story with one group of steps + # with_steps_for :checking_accounts do + # run File.dirname(__FILE__) + "/withdraw_cash" + # end + # + # # Run a Story, adding steps that are only available for this Story + # with_steps_for :accounts do + # Given "user is logged in as account administrator" + # run File.dirname(__FILE__) + "/reconcile_accounts" + # end + # + # # Run a Story with steps from two groups + # with_steps_for :checking_accounts, :savings_accounts do + # run File.dirname(__FILE__) + "/transfer_money" + # end + # + # # Run a Story with a specific Story extension + # with_steps_for :login, :navigation do + # run File.dirname(__FILE__) + "/user_changes_password", :type => RailsStory + # end + def with_steps_for(*tags, &block) + steps = Spec::Story::StepGroup.new do + extend StoryRunnerStepGroupAdapter + end + tags.each {|tag| steps << rspec_story_steps[tag]} + steps.instance_eval(&block) if block + steps + end + + private + + module StoryRunnerStepGroupAdapter + def run(path, options={}) + runner = Spec::Story::Runner::PlainTextStoryRunner.new(path, options) + runner.steps << self + runner.run + end + end + + def rspec_story_steps # :nodoc: + $rspec_story_steps ||= Spec::Story::StepGroupHash.new + end + + end + end + end +end + +include Spec::Story::Extensions::Main \ No newline at end of file diff -Nur mephisto-0.7.3/vendor/plugins/rspec/lib/spec/story/extensions.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/lib/spec/story/extensions.rb --- mephisto-0.7.3/vendor/plugins/rspec/lib/spec/story/extensions.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/lib/spec/story/extensions.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1 @@ +require 'spec/story/extensions/main' diff -Nur mephisto-0.7.3/vendor/plugins/rspec/lib/spec/story/given_scenario.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/lib/spec/story/given_scenario.rb --- mephisto-0.7.3/vendor/plugins/rspec/lib/spec/story/given_scenario.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/lib/spec/story/given_scenario.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,14 @@ +module Spec + module Story + class GivenScenario + def initialize name + @name = name + end + + def perform(instance, ignore_name) + scenario = Runner::StoryRunner.scenario_from_current_story @name + Runner::ScenarioRunner.new.run(scenario, instance) + end + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/lib/spec/story/runner/plain_text_story_runner.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/lib/spec/story/runner/plain_text_story_runner.rb --- mephisto-0.7.3/vendor/plugins/rspec/lib/spec/story/runner/plain_text_story_runner.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/lib/spec/story/runner/plain_text_story_runner.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,48 @@ +module Spec + module Story + module Runner + class PlainTextStoryRunner + # You can initialize a PlainTextStoryRunner with the path to the + # story file or a block, in which you can define the path using load. + # + # == Examples + # + # PlainTextStoryRunner.new('path/to/file') + # + # PlainTextStoryRunner.new do |runner| + # runner.load 'path/to/file' + # end + def initialize(*args) + @options = Hash === args.last ? args.pop : {} + @story_file = args.empty? ? nil : args.shift + yield self if block_given? + end + + def []=(key, value) + @options[key] = value + end + + def load(path) + @story_file = path + end + + def run + raise "You must set a path to the file with the story. See the RDoc." if @story_file.nil? + mediator = Spec::Story::Runner::StoryMediator.new steps, Spec::Story::Runner.story_runner, @options + parser = Spec::Story::Runner::StoryParser.new mediator + + story_text = File.read(@story_file) + parser.parse(story_text.split("\n")) + + mediator.run_stories + end + + def steps + @step_group ||= Spec::Story::StepGroup.new + yield @step_group if block_given? + @step_group + end + end + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/lib/spec/story/runner/scenario_collector.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/lib/spec/story/runner/scenario_collector.rb --- mephisto-0.7.3/vendor/plugins/rspec/lib/spec/story/runner/scenario_collector.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/lib/spec/story/runner/scenario_collector.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,18 @@ +module Spec + module Story + module Runner + class ScenarioCollector + attr_accessor :scenarios + + def initialize(story) + @story = story + @scenarios = [] + end + + def Scenario(name, &body) + @scenarios << Scenario.new(@story, name, &body) + end + end + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/lib/spec/story/runner/scenario_runner.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/lib/spec/story/runner/scenario_runner.rb --- mephisto-0.7.3/vendor/plugins/rspec/lib/spec/story/runner/scenario_runner.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/lib/spec/story/runner/scenario_runner.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,49 @@ +module Spec + module Story + module Runner + class ScenarioRunner + def initialize + @listeners = [] + end + + def run(scenario, world) + @listeners.each { |l| l.scenario_started(scenario.story.title, scenario.name) } + run_story_ignoring_scenarios(scenario.story, world) + + world.start_collecting_errors + world.instance_eval(&scenario.body) + if world.errors.empty? + @listeners.each { |l| l.scenario_succeeded(scenario.story.title, scenario.name) } + else + world.errors.each do |e| + case e + when Spec::Example::ExamplePendingError + @listeners.each { |l| l.scenario_pending(scenario.story.title, scenario.name, e.message) } + else + @listeners.each { |l| l.scenario_failed(scenario.story.title, scenario.name, e) } + end + end + end + end + + def add_listener(listener) + @listeners << listener + end + + private + + def run_story_ignoring_scenarios(story, world) + class << world + def Scenario(name, &block) + # do nothing + end + end + story.run_in(world) + class << world + remove_method(:Scenario) + end + end + end + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/lib/spec/story/runner/story_mediator.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/lib/spec/story/runner/story_mediator.rb --- mephisto-0.7.3/vendor/plugins/rspec/lib/spec/story/runner/story_mediator.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/lib/spec/story/runner/story_mediator.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,123 @@ + module Spec + module Story + module Runner + + class StoryMediator + def initialize(step_group, runner, options={}) + @step_group = step_group + @stories = [] + @runner = runner + @options = options + end + + def stories + @stories.collect { |p| p.to_proc } + end + + def create_story(title, narrative) + @stories << Story.new(title, narrative, @step_group, @options) + end + + def create_scenario(title) + current_story.add_scenario Scenario.new(title) + end + + def create_given(name) + current_scenario.add_step Step.new('Given', name) + end + + def create_given_scenario(name) + current_scenario.add_step Step.new('GivenScenario', name) + end + + def create_when(name) + current_scenario.add_step Step.new('When', name) + end + + def create_then(name) + current_scenario.add_step Step.new('Then', name) + end + + def run_stories + stories.each { |story| @runner.instance_eval(&story) } + end + + private + def current_story + @stories.last + end + + def current_scenario + current_story.current_scenario + end + + class Story + def initialize(title, narrative, step_group, options) + @title = title + @narrative = narrative + @scenarios = [] + @step_group = step_group + @options = options + end + + def to_proc + title = @title + narrative = @narrative + scenarios = @scenarios.collect { |scenario| scenario.to_proc } + options = @options.merge(:steps => @step_group) + lambda do + Story title, narrative, options do + scenarios.each { |scenario| instance_eval(&scenario) } + end + end + end + + def add_scenario(scenario) + @scenarios << scenario + end + + def current_scenario + @scenarios.last + end + end + + class Scenario + def initialize(name) + @name = name + @steps = [] + end + + def to_proc + name = @name + steps = @steps.collect { |step| step.to_proc } + lambda do + Scenario name do + steps.each { |step| instance_eval(&step) } + end + end + end + + def add_step(step) + @steps << step + end + end + + class Step + def initialize(type, name) + @type = type + @name = name + end + + def to_proc + type = @type + name = @name + lambda do + send(type, name) + end + end + end + end + + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/lib/spec/story/runner/story_parser.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/lib/spec/story/runner/story_parser.rb --- mephisto-0.7.3/vendor/plugins/rspec/lib/spec/story/runner/story_parser.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/lib/spec/story/runner/story_parser.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,227 @@ +module Spec + module Story + module Runner + + class IllegalStepError < StandardError + def initialize(state, event) + super("Illegal attempt to create a #{event} after a #{state}") + end + end + + class StoryParser + def initialize(story_mediator) + @story_mediator = story_mediator + @current_story_lines = [] + transition_to(:starting_state) + end + + def parse(lines) + lines.reject! {|line| line == ""} + until lines.empty? + process_line(lines.shift) + end + @state.eof + end + + def process_line(line) + line.strip! + case line + when /^Story: / : @state.story(line) + when /^Scenario: / : @state.scenario(line) + when /^Given:? / : @state.given(line) + when /^GivenScenario:? / : @state.given_scenario(line) + when /^When:? / : @state.event(line) + when /^Then:? / : @state.outcome(line) + when /^And:? / : @state.one_more_of_the_same(line) + else @state.other(line) + end + end + + def init_story(title) + @current_story_lines.clear + add_story_line(title) + end + + def add_story_line(line) + @current_story_lines << line + end + + def create_story() + unless @current_story_lines.empty? + @story_mediator.create_story(@current_story_lines[0].gsub("Story: ",""), @current_story_lines[1..-1].join("\n")) + @current_story_lines.clear + end + end + + def create_scenario(title) + @story_mediator.create_scenario(title.gsub("Scenario: ","")) + end + + def create_given(name) + @story_mediator.create_given(name) + end + + def create_given_scenario(name) + @story_mediator.create_given_scenario(name) + end + + def create_when(name) + @story_mediator.create_when(name) + end + + def create_then(name) + @story_mediator.create_then(name) + end + + def transition_to(key) + @state = states[key] + end + + def states + @states ||= { + :starting_state => StartingState.new(self), + :story_state => StoryState.new(self), + :scenario_state => ScenarioState.new(self), + :given_state => GivenState.new(self), + :when_state => WhenState.new(self), + :then_state => ThenState.new(self) + } + end + + class State + def initialize(parser) + @parser = parser + end + + def story(line) + @parser.init_story(line) + @parser.transition_to(:story_state) + end + + def scenario(line) + @parser.create_scenario(line) + @parser.transition_to(:scenario_state) + end + + def given(line) + @parser.create_given(remove_tag_from(:given, line)) + @parser.transition_to(:given_state) + end + + def given_scenario(line) + @parser.create_given_scenario(remove_tag_from(:givenscenario, line)) + @parser.transition_to(:given_state) + end + + def event(line) + @parser.create_when(remove_tag_from(:when, line)) + @parser.transition_to(:when_state) + end + + def outcome(line) + @parser.create_then(remove_tag_from(:then, line)) + @parser.transition_to(:then_state) + end + + def remove_tag_from(tag, line) + tokens = line.split + # validation of tag can go here + tokens[0].downcase.match(/#{tag.to_s}:?/) ? + (tokens[1..-1].join(' ')) : line + end + + def eof + end + + def other(line) + # no-op - supports header text before the first story in a file + end + end + + class StartingState < State + def initialize(parser) + @parser = parser + end + end + + class StoryState < State + def one_more_of_the_same(line) + other(line) + end + + def story(line) + @parser.create_story + @parser.add_story_line(line) + end + + def scenario(line) + @parser.create_story + @parser.create_scenario(line) + @parser.transition_to(:scenario_state) + end + + def given(line) + other(line) + end + + def event(line) + other(line) + end + + def outcome(line) + other(line) + end + + def other(line) + @parser.add_story_line(line) + end + + def eof + @parser.create_story + end + end + + class ScenarioState < State + def one_more_of_the_same(line) + raise IllegalStepError.new("Scenario", "And") + end + + def scenario(line) + @parser.create_scenario(line) + end + end + + class GivenState < State + def one_more_of_the_same(line) + @parser.create_given(remove_tag_from(:and, line)) + end + + def given(line) + @parser.create_given(remove_tag_from(:given, line)) + end + end + + class WhenState < State + def one_more_of_the_same(line) + @parser.create_when(remove_tag_from(:and ,line)) + end + + def event(line) + @parser.create_when(remove_tag_from(:when ,line)) + end + end + + class ThenState < State + def one_more_of_the_same(line) + @parser.create_then(remove_tag_from(:and ,line)) + end + + def outcome(line) + @parser.create_then(remove_tag_from(:then ,line)) + end + end + + end + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/lib/spec/story/runner/story_runner.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/lib/spec/story/runner/story_runner.rb --- mephisto-0.7.3/vendor/plugins/rspec/lib/spec/story/runner/story_runner.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/lib/spec/story/runner/story_runner.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,67 @@ +module Spec + module Story + module Runner + class StoryRunner + class << self + attr_accessor :current_story_runner + + def scenario_from_current_story(scenario_name) + current_story_runner.scenario_from_current_story(scenario_name) + end + end + + attr_accessor :stories, :scenarios, :current_story + + def initialize(scenario_runner, world_creator = World) + StoryRunner.current_story_runner = self + @scenario_runner = scenario_runner + @world_creator = world_creator + @stories = [] + @scenarios_by_story = {} + @scenarios = [] + @listeners = [] + end + + def Story(title, narrative, params = {}, &body) + story = Story.new(title, narrative, params, &body) + @stories << story + + # collect scenarios + collector = ScenarioCollector.new(story) + story.run_in(collector) + @scenarios += collector.scenarios + @scenarios_by_story[story.title] = collector.scenarios + end + + def run_stories + return if @stories.empty? + @listeners.each { |l| l.run_started(scenarios.size) } + @stories.each do |story| + story.assign_steps_to(World) + @current_story = story + @listeners.each { |l| l.story_started(story.title, story.narrative) } + scenarios = @scenarios_by_story[story.title] + scenarios.each do |scenario| + type = story[:type] || Object + args = story[:args] || [] + world = @world_creator.create(type, *args) + @scenario_runner.run(scenario, world) + end + @listeners.each { |l| l.story_ended(story.title, story.narrative) } + end + unique_steps = World.step_names.uniq.sort + @listeners.each { |l| l.collected_steps(unique_steps) } + @listeners.each { |l| l.run_ended } + end + + def add_listener(listener) + @listeners << listener + end + + def scenario_from_current_story(scenario_name) + @scenarios_by_story[@current_story.title].find {|s| s.name == scenario_name } + end + end + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/lib/spec/story/runner.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/lib/spec/story/runner.rb --- mephisto-0.7.3/vendor/plugins/rspec/lib/spec/story/runner.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/lib/spec/story/runner.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,58 @@ +require 'spec/story/runner/scenario_collector.rb' +require 'spec/story/runner/scenario_runner.rb' +require 'spec/story/runner/story_runner.rb' +require 'spec/story/runner/story_parser.rb' +require 'spec/story/runner/story_mediator.rb' +require 'spec/story/runner/plain_text_story_runner.rb' + +module Spec + module Story + module Runner + class << self + def run_options # :nodoc: + @run_options ||= ::Spec::Runner::OptionParser.parse(ARGV, $stderr, $stdout) + end + + def story_runner # :nodoc: + unless @story_runner + @story_runner = StoryRunner.new(scenario_runner, world_creator) + run_options.story_formatters.each do |formatter| + register_listener(formatter) + end + Runner.register_exit_hook + end + @story_runner + end + + def scenario_runner # :nodoc: + @scenario_runner ||= ScenarioRunner.new + end + + def world_creator # :nodoc: + @world_creator ||= World + end + + # Use this to register a customer output formatter. + def register_listener(listener) + story_runner.add_listener(listener) # run_started, story_started, story_ended, #run_ended + world_creator.add_listener(listener) # found_scenario, step_succeeded, step_failed, step_failed + scenario_runner.add_listener(listener) # scenario_started, scenario_succeeded, scenario_pending, scenario_failed + end + + def register_exit_hook # :nodoc: + # TODO - when story runner uses test/unit runners like example runner does we can kill + # this and also the assorted Kernel.stub!(:at_exit) in examples + at_exit do + Runner.story_runner.run_stories unless $! + end + # TODO exit with non-zero status if run fails + end + + def dry_run + run_options.dry_run + end + + end + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/lib/spec/story/scenario.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/lib/spec/story/scenario.rb --- mephisto-0.7.3/vendor/plugins/rspec/lib/spec/story/scenario.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/lib/spec/story/scenario.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,14 @@ + +module Spec + module Story + class Scenario + attr_accessor :name, :body, :story + + def initialize(story, name, &body) + @story = story + @name = name + @body = body + end + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/lib/spec/story/step.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/lib/spec/story/step.rb --- mephisto-0.7.3/vendor/plugins/rspec/lib/spec/story/step.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/lib/spec/story/step.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,48 @@ +module Spec + module Story + class Step + PARAM_PATTERN = /(\$\w*)/ + + attr_reader :name + def initialize(name, &block) + @name = name + assign_expression(name) + init_module(name, &block) + end + + def perform(instance, *args) + instance.extend(@mod) + instance.__send__(@name, *args) + end + + def init_module(name, &block) + @mod = Module.new do + define_method(name.to_s, &block) + end + end + + def matches?(name) + !(matches = name.match(@expression)).nil? + end + + def parse_args(name) + name.match(@expression)[1..-1] + end + + private + + def assign_expression(name) + expression = name.dup + if String === expression + expression.gsub! '(', '\(' + expression.gsub! ')', '\)' + while expression =~ PARAM_PATTERN + expression.gsub!($1, "(.*)") + end + end + @expression = Regexp.new("^#{expression}$") + end + + end + end +end \ No newline at end of file diff -Nur mephisto-0.7.3/vendor/plugins/rspec/lib/spec/story/step_group.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/lib/spec/story/step_group.rb --- mephisto-0.7.3/vendor/plugins/rspec/lib/spec/story/step_group.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/lib/spec/story/step_group.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,90 @@ +module Spec + module Story + + class StepGroupHash < Hash + def initialize + super do |h,k| + h[k] = Spec::Story::StepGroup.new + end + end + end + + class StepGroup + def self.steps(&block) + @step_group ||= StepGroup.new(false) + @step_group.instance_eval(&block) if block + @step_group + end + + def initialize(init_defaults=true,&block) + @hash_of_lists_of_steps = Hash.new {|h, k| h[k] = []} + if init_defaults + self.class.steps.add_to(self) + end + instance_eval(&block) if block + end + + def find(type, name) + @hash_of_lists_of_steps[type].each do |step| + return step if step.matches?(name) + end + return nil + end + + def GivenScenario(name, &block) + create_matcher(:given_scenario, name, &block) + end + + def Given(name, &block) + create_matcher(:given, name, &block) + end + + def When(name, &block) + create_matcher(:when, name, &block) + end + + def Then(name, &block) + create_matcher(:then, name, &block) + end + + alias :given_scenario :GivenScenario + alias :given :Given + alias :when :When + alias :then :Then + + + def add(type, steps) + (@hash_of_lists_of_steps[type] << steps).flatten! + end + + def clear + @hash_of_lists_of_steps.clear + end + + def empty? + [:given_scenario, :given, :when, :then].each do |type| + return false unless @hash_of_lists_of_steps[type].empty? + end + return true + end + + def add_to(other_step_matchers) + [:given_scenario, :given, :when, :then].each do |type| + other_step_matchers.add(type, @hash_of_lists_of_steps[type]) + end + end + + def <<(other_step_matchers) + other_step_matchers.add_to(self) if other_step_matchers.respond_to?(:add_to) + end + + # TODO - make me private + def create_matcher(type, name, &block) + matcher = Step.new(name, &block) + @hash_of_lists_of_steps[type] << matcher + matcher + end + + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/lib/spec/story/step_mother.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/lib/spec/story/step_mother.rb --- mephisto-0.7.3/vendor/plugins/rspec/lib/spec/story/step_mother.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/lib/spec/story/step_mother.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,37 @@ +module Spec + module Story + class StepMother + def initialize + @steps = StepGroup.new + end + + def use(new_step_group) + @steps << new_step_group + end + + def store(type, step) + @steps.add(type, step) + end + + def find(type, name) + if @steps.find(type, name).nil? + @steps.add(type, + Step.new(name) do + raise Spec::Example::ExamplePendingError.new("Unimplemented step: #{name}") + end + ) + end + @steps.find(type, name) + end + + def clear + @steps.clear + end + + def empty? + @steps.empty? + end + + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/lib/spec/story/story.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/lib/spec/story/story.rb --- mephisto-0.7.3/vendor/plugins/rspec/lib/spec/story/story.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/lib/spec/story/story.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,42 @@ +module Spec + module Story + class Story + attr_reader :title, :narrative + + def initialize(title, narrative, params = {}, &body) + @body = body + @title = title + @narrative = narrative + @params = params + end + + def [](key) + @params[key] + end + + def run_in(obj) + obj.instance_eval(&@body) + end + + def assign_steps_to(assignee) + if @params[:steps] + assignee.use(@params[:steps]) + else + case keys = @params[:steps_for] + when Symbol + keys = [keys] + when nil + keys = [] + end + keys.each do |key| + assignee.use(steps_for(key)) + end + end + end + + def steps_for(key) + $rspec_story_steps[key] + end + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/lib/spec/story/world.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/lib/spec/story/world.rb --- mephisto-0.7.3/vendor/plugins/rspec/lib/spec/story/world.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/lib/spec/story/world.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,124 @@ +require 'rubygems' +require 'spec/expectations' +require 'spec/matchers' +require 'spec/example/pending' + +module Spec + module Story +=begin + A World represents the actual instance a scenario will run in. + + The runner ensures any instance variables and methods defined anywhere + in a story block are available to all the scenarios. This includes + variables that are created or referenced inside Given, When and Then + blocks. +=end + module World + include ::Spec::Example::Pending + include ::Spec::Matchers + # store steps and listeners in the singleton metaclass. + # This serves both to keep them out of the way of runtime Worlds + # and to make them available to all instances. + class << self + def create(cls = Object, *args) + cls.new(*args).extend(World) + end + + def listeners + @listeners ||= [] + end + + def add_listener(listener) + listeners() << listener + end + + def step_mother + @step_mother ||= StepMother.new + end + + def use(steps) + step_mother.use(steps) + end + + def step_names + @step_names ||= [] + end + + def run_given_scenario_with_suspended_listeners(world, type, name, scenario) + current_listeners = Array.new(listeners) + begin + listeners.each { |l| l.found_scenario(type, name) } + @listeners.clear + scenario.perform(world, name) unless ::Spec::Story::Runner.dry_run + ensure + @listeners.replace(current_listeners) + end + end + + def store_and_call(world, type, name, *args, &block) + if block_given? + step_mother.store(type, Step.new(name, &block)) + end + step = step_mother.find(type, name) + + step_name = step.name + step_names << step_name + + # It's important to have access to the parsed args here, so + # we can give them to the listeners. The HTML reporter needs + # the args so it can style them. See the generated output in + # story_server/prototype/rspec_stories.html (generated by rake stories) + args = step.parse_args(name) if args.empty? + begin + step.perform(world, *args) unless ::Spec::Story::Runner.dry_run + listeners.each { |l| l.step_succeeded(type, step_name, *args) } + rescue Exception => e + case e + when Spec::Example::ExamplePendingError + @listeners.each { |l| l.step_pending(type, step_name, *args) } + else + @listeners.each { |l| l.step_failed(type, step_name, *args) } + end + errors << e + end + end + + def errors + @errors ||= [] + end + end # end of class << self + + def start_collecting_errors + errors.clear + end + + def errors + World.errors + end + + def GivenScenario(name) + World.run_given_scenario_with_suspended_listeners(self, :'given scenario', name, GivenScenario.new(name)) + @__previous_step = :given + end + + def Given(name, *args, &block) + World.store_and_call self, :given, name, *args, &block + @__previous_step = :given + end + + def When(name, *args, &block) + World.store_and_call self, :when, name, *args, &block + @__previous_step = :when + end + + def Then(name, *args, &block) + World.store_and_call self, :then, name, *args, &block + @__previous_step = :then + end + + def And(name, *args, &block) + World.store_and_call self, @__previous_step, name, *args, &block + end + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/lib/spec/story.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/lib/spec/story.rb --- mephisto-0.7.3/vendor/plugins/rspec/lib/spec/story.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/lib/spec/story.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,9 @@ +require 'spec/story/extensions' +require 'spec/story/given_scenario' +require 'spec/story/runner' +require 'spec/story/scenario' +require 'spec/story/step' +require 'spec/story/step_group' +require 'spec/story/step_mother' +require 'spec/story/story' +require 'spec/story/world' diff -Nur mephisto-0.7.3/vendor/plugins/rspec/lib/spec/test_case_adapter.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/lib/spec/test_case_adapter.rb --- mephisto-0.7.3/vendor/plugins/rspec/lib/spec/test_case_adapter.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/lib/spec/test_case_adapter.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,10 @@ +require 'spec/expectations' +require 'spec/matchers' + +module Test + module Unit + class TestCase + include Spec::Matchers + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/lib/spec/translator.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/lib/spec/translator.rb --- mephisto-0.7.3/vendor/plugins/rspec/lib/spec/translator.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/lib/spec/translator.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,114 @@ +require 'fileutils' + +module Spec + class Translator + def translate(from, to) + from = File.expand_path(from) + to = File.expand_path(to) + if File.directory?(from) + translate_dir(from, to) + elsif(from =~ /\.rb$/) + translate_file(from, to) + end + end + + def translate_dir(from, to) + FileUtils.mkdir_p(to) unless File.directory?(to) + Dir["#{from}/*"].each do |sub_from| + path = sub_from[from.length+1..-1] + sub_to = File.join(to, path) + translate(sub_from, sub_to) + end + end + + def translate_file(from, to) + translation = "" + File.open(from) do |io| + io.each_line do |line| + translation << translate_line(line) + end + end + File.open(to, "w") do |io| + io.write(translation) + end + end + + def translate_line(line) + # Translate deprecated mock constraints + line.gsub!(/:any_args/, 'any_args') + line.gsub!(/:anything/, 'anything') + line.gsub!(/:boolean/, 'boolean') + line.gsub!(/:no_args/, 'no_args') + line.gsub!(/:numeric/, 'an_instance_of(Numeric)') + line.gsub!(/:string/, 'an_instance_of(String)') + + return line if line =~ /(should_not|should)_receive/ + + line.gsub!(/(^\s*)context([\s*|\(]['|"|A-Z])/, '\1describe\2') + line.gsub!(/(^\s*)specify([\s*|\(]['|"|A-Z])/, '\1it\2') + line.gsub!(/(^\s*)context_setup(\s*[do|\{])/, '\1before(:all)\2') + line.gsub!(/(^\s*)context_teardown(\s*[do|\{])/, '\1after(:all)\2') + line.gsub!(/(^\s*)setup(\s*[do|\{])/, '\1before(:each)\2') + line.gsub!(/(^\s*)teardown(\s*[do|\{])/, '\1after(:each)\2') + + if line =~ /(.*\.)(should_not|should)(?:_be)(?!_)(.*)/m + pre = $1 + should = $2 + post = $3 + be_or_equal = post =~ /(<|>)/ ? "be" : "equal" + + return "#{pre}#{should} #{be_or_equal}#{post}" + end + + if line =~ /(.*\.)(should_not|should)_(?!not)\s*(.*)/m + pre = $1 + should = $2 + post = $3 + + post.gsub!(/^raise/, 'raise_error') + post.gsub!(/^throw/, 'throw_symbol') + + unless standard_matcher?(post) + post = "be_#{post}" + end + + # Add parenthesis + post.gsub!(/^(\w+)\s+([\w|\.|\,|\(.*\)|\'|\"|\:|@| ]+)(\})/, '\1(\2)\3') # inside a block + post.gsub!(/^(redirect_to)\s+(.*)/, '\1(\2)') # redirect_to, which often has http: + post.gsub!(/^(\w+)\s+([\w|\.|\,|\(.*\)|\{.*\}|\'|\"|\:|@| ]+)/, '\1(\2)') + post.gsub!(/(\s+\))/, ')') + post.gsub!(/\)\}/, ') }') + post.gsub!(/^(\w+)\s+(\/.*\/)/, '\1(\2)') #regexps + line = "#{pre}#{should} #{post}" + end + + line + end + + def standard_matcher?(matcher) + patterns = [ + /^be/, + /^be_close/, + /^eql/, + /^equal/, + /^has/, + /^have/, + /^change/, + /^include/, + /^match/, + /^raise_error/, + /^respond_to/, + /^redirect_to/, + /^satisfy/, + /^throw_symbol/, + # Extra ones that we use in spec_helper + /^pass/, + /^fail/, + /^fail_with/, + ] + matched = patterns.detect{ |p| matcher =~ p } + !matched.nil? + end + + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/lib/spec/version.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/lib/spec/version.rb --- mephisto-0.7.3/vendor/plugins/rspec/lib/spec/version.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/lib/spec/version.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,23 @@ +module Spec + module VERSION + unless defined? MAJOR + MAJOR = 1 + MINOR = 1 + TINY = 0 + RELEASE_CANDIDATE = nil + + # RANDOM_TOKEN: 0.885013695004692 + REV = "$LastChangedRevision: 2958 $".match(/LastChangedRevision: (\d+)/)[1] + + STRING = [MAJOR, MINOR, TINY].join('.') + TAG = "REL_#{[MAJOR, MINOR, TINY, RELEASE_CANDIDATE].compact.join('_')}".upcase.gsub(/\.|-/, '_') + FULL_VERSION = "#{[MAJOR, MINOR, TINY, RELEASE_CANDIDATE].compact.join('.')} (r#{REV})" + + NAME = "RSpec" + URL = "http://rspec.rubyforge.org/" + + DESCRIPTION = "#{NAME}-#{FULL_VERSION} - BDD for Ruby\n#{URL}" + end + end +end + diff -Nur mephisto-0.7.3/vendor/plugins/rspec/lib/spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/lib/spec.rb --- mephisto-0.7.3/vendor/plugins/rspec/lib/spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/lib/spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,38 @@ +require 'spec/version' +require 'spec/matchers' +require 'spec/expectations' +require 'spec/translator' +require 'spec/example' +require 'spec/extensions' +require 'spec/runner' +require 'spec/story' + +if Object.const_defined?(:Test); \ + require 'spec/extensions/test'; \ +end +module Spec + class << self + def run? + @run || rspec_options.examples_run? + end + + def run; \ + return true if run?; \ + result = rspec_options.run_examples; \ + @run = true; \ + result; \ + end + attr_writer :run + + def exit?; \ + !Object.const_defined?(:Test) || Test::Unit.run?; \ + end + end +end + +at_exit do \ + unless $! || Spec.run?; \ + success = Spec.run; \ + exit success if Spec.exit?; \ + end \ +end \ No newline at end of file diff -Nur mephisto-0.7.3/vendor/plugins/rspec/plugins/mock_frameworks/flexmock.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/plugins/mock_frameworks/flexmock.rb --- mephisto-0.7.3/vendor/plugins/rspec/plugins/mock_frameworks/flexmock.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/plugins/mock_frameworks/flexmock.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,23 @@ +#!/usr/bin/env ruby +# +# Created by Jim Weirich on 2007-04-10. +# Copyright (c) 2007. All rights reserved. + +require 'flexmock/rspec' + +module Spec + module Plugins + module MockFramework + include FlexMock::MockContainer + def setup_mocks_for_rspec + # No setup required + end + def verify_mocks_for_rspec + flexmock_verify + end + def teardown_mocks_for_rspec + flexmock_close + end + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/plugins/mock_frameworks/mocha.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/plugins/mock_frameworks/mocha.rb --- mephisto-0.7.3/vendor/plugins/rspec/plugins/mock_frameworks/mocha.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/plugins/mock_frameworks/mocha.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,19 @@ +require 'mocha/standalone' +require 'mocha/object' + +module Spec + module Plugins + module MockFramework + include Mocha::Standalone + def setup_mocks_for_rspec + mocha_setup + end + def verify_mocks_for_rspec + mocha_verify + end + def teardown_mocks_for_rspec + mocha_teardown + end + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/plugins/mock_frameworks/rr.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/plugins/mock_frameworks/rr.rb --- mephisto-0.7.3/vendor/plugins/rspec/plugins/mock_frameworks/rr.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/plugins/mock_frameworks/rr.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,21 @@ +require 'rr' + +patterns = ::Spec::Runner::QuietBacktraceTweaker::IGNORE_PATTERNS +patterns.push(RR::Errors::BACKTRACE_IDENTIFIER) + +module Spec + module Plugins + module MockFramework + include RR::Extensions::InstanceMethods + def setup_mocks_for_rspec + RR::Space.instance.reset + end + def verify_mocks_for_rspec + RR::Space.instance.verify_doubles + end + def teardown_mocks_for_rspec + RR::Space.instance.reset + end + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/plugins/mock_frameworks/rspec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/plugins/mock_frameworks/rspec.rb --- mephisto-0.7.3/vendor/plugins/rspec/plugins/mock_frameworks/rspec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/plugins/mock_frameworks/rspec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,18 @@ +require File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "lib", "spec", "mocks")) + +module Spec + module Plugins + module MockFramework + include Spec::Mocks::SpecMethods + def setup_mocks_for_rspec + $rspec_mocks ||= Spec::Mocks::Space.new + end + def verify_mocks_for_rspec + $rspec_mocks.verify_all + end + def teardown_mocks_for_rspec + $rspec_mocks.reset_all + end + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/rake_tasks/examples.rake technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/rake_tasks/examples.rake --- mephisto-0.7.3/vendor/plugins/rspec/rake_tasks/examples.rake 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/rake_tasks/examples.rake 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,7 @@ +require 'rake' +require 'spec/rake/spectask' + +desc "Run all examples" +Spec::Rake::SpecTask.new('examples') do |t| + t.spec_files = FileList['examples/**/*.rb'] +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/rake_tasks/examples_with_rcov.rake technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/rake_tasks/examples_with_rcov.rake --- mephisto-0.7.3/vendor/plugins/rspec/rake_tasks/examples_with_rcov.rake 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/rake_tasks/examples_with_rcov.rake 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,9 @@ +require 'rake' +require 'spec/rake/spectask' + +desc "Run all examples with RCov" +Spec::Rake::SpecTask.new('examples_with_rcov') do |t| + t.spec_files = FileList['examples/**/*.rb'] + t.rcov = true + t.rcov_opts = ['--exclude', 'examples'] +end \ No newline at end of file diff -Nur mephisto-0.7.3/vendor/plugins/rspec/rake_tasks/failing_examples_with_html.rake technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/rake_tasks/failing_examples_with_html.rake --- mephisto-0.7.3/vendor/plugins/rspec/rake_tasks/failing_examples_with_html.rake 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/rake_tasks/failing_examples_with_html.rake 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,9 @@ +require 'rake' +require 'spec/rake/spectask' + +desc "Generate HTML report for failing examples" +Spec::Rake::SpecTask.new('failing_examples_with_html') do |t| + t.spec_files = FileList['failing_examples/**/*.rb'] + t.spec_opts = ["--format", "html:../doc/output/documentation/tools/failing_examples.html", "--diff"] + t.fail_on_error = false +end \ No newline at end of file diff -Nur mephisto-0.7.3/vendor/plugins/rspec/rake_tasks/verify_rcov.rake technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/rake_tasks/verify_rcov.rake --- mephisto-0.7.3/vendor/plugins/rspec/rake_tasks/verify_rcov.rake 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/rake_tasks/verify_rcov.rake 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,7 @@ +require 'rake' +require 'spec/rake/verify_rcov' + +RCov::VerifyTask.new(:verify_rcov => :spec) do |t| + t.threshold = 100.0 # Make sure you have rcov 0.7 or higher! + t.index_html = '../doc/output/coverage/index.html' +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/README.jruby technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/README.jruby --- mephisto-0.7.3/vendor/plugins/rspec/spec/README.jruby 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/README.jruby 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,14 @@ += Running specs on JRuby = + +svn co http://svn.codehaus.org/jruby/trunk jruby +cd jruby/jruby +ant clean +ant +# put JRuby's bin dir on your PATH +jruby -S gem install rake --no-ri --no-rdoc +jruby -S gem install diff-lcs +cd ../testsuites/rspec +mkdir target +jruby -S rake checkout_code +cd target/rspec +jruby bin/spec spec -c diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/autotest/discover_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/autotest/discover_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/autotest/discover_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/autotest/discover_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,19 @@ +require File.dirname(__FILE__) + "/../autotest_helper" + +module DiscoveryHelper + def load_discovery + require File.dirname(__FILE__) + "/../../lib/autotest/discover" + end +end + + +class Autotest + describe Rspec, "discovery" do + include DiscoveryHelper + + it "should add the rspec autotest plugin" do + Autotest.should_receive(:add_discovery).and_yield + load_discovery + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/autotest/rspec_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/autotest/rspec_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/autotest/rspec_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/autotest/rspec_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,264 @@ +require File.dirname(__FILE__) + "/../autotest_helper" + +class Autotest + + module AutotestHelper + def rspec_output + <<-HERE +.............PPF + +1) +'false should be false' FAILED +expected: true, + got: false (using ==) +./spec/autotest/rspec_spec.rb:203: + +Finished in 0.158674 seconds + +16 examples, 1 failure, 2 pending + +Pending: +Autotest::Rspec handling failed results should return an array of failed examples and errors (TODO) +Autotest::Rspec tests/specs for a given file should find all the specs for a given file (TODO) +HERE + end + + + def common_setup + @proc = mock Proc + @kernel = mock Kernel + @kernel.stub!(:proc).and_return @proc + + File.stub!(:exists).and_return true + @windows_alt_separator = "\\" + @posix_separator = '/' + + @rspec_output = rspec_output + end + end + + describe Rspec, "rspec_commands" do + it "should contain the various commands, ordered by preference" do + Rspec.new.spec_commands.should == [ + File.expand_path("#{File.dirname(__FILE__)}/../../bin/spec"), + "#{Config::CONFIG['bindir']}/spec" + ] + end + end + + describe Rspec, "selection of rspec command" do + include AutotestHelper + + before :each do + common_setup + @rspec_autotest = Rspec.new(@kernel) + end + + it "should try to find the spec command if it exists in ./bin and use it above everything else" do + File.stub!(:exists?).and_return true + + spec_path = File.expand_path("#{File.dirname(__FILE__)}/../../bin/spec") + File.should_receive(:exists?).with(spec_path).and_return true + @rspec_autotest.spec_command.should == spec_path + end + + it "should otherwise select the default spec command in gem_dir/bin/spec" do + @rspec_autotest.stub!(:spec_commands).and_return ["/foo/spec"] + Config::CONFIG.stub!(:[]).and_return "/foo" + File.should_receive(:exists?).with("/foo/spec").and_return(true) + + @rspec_autotest.spec_command.should == "/foo/spec" + end + + it "should raise an error if no spec command is found at all" do + File.stub!(:exists?).and_return false + + lambda { + @rspec_autotest.spec_command + }.should raise_error(RspecCommandError, "No spec command could be found!") + end + + end + + describe Rspec, "selection of rspec command (windows compatibility issues)" do + include AutotestHelper + + before :each do + common_setup + end + + it "should use the ALT_SEPARATOR if it is non-nil" do + @rspec_autotest = Rspec.new(@kernel, @posix_separator, @windows_alt_separator) + spec_command = File.expand_path("#{File.dirname(__FILE__)}/../../bin/spec") + @rspec_autotest.stub!(:spec_commands).and_return [spec_command] + @rspec_autotest.spec_command.should == spec_command.gsub('/', '\\') + end + + it "should not use the ALT_SEPATOR if it is nil" do + @windows_alt_separator = nil + @rspec_autotest = Rspec.new(@kernel, @posix_separator, @windows_alt_separator) + spec_command = File.expand_path("#{File.dirname(__FILE__)}/../../bin/spec") + @rspec_autotest.stub!(:spec_commands).and_return [spec_command] + @rspec_autotest.spec_command.should == spec_command + end + end + + describe Rspec, "adding spec.opts --options" do + before :each do + @rspec_autotest = Rspec.new + end + + it "should return the command line option to add spec.opts if the options file exists" do + File.stub!(:exist?).and_return true + @rspec_autotest.add_options_if_present.should == "-O spec/spec.opts " + end + + it "should return an empty string if no spec.opts exists" do + File.stub!(:exist?).and_return false + Rspec.new.add_options_if_present.should == "" + end + end + + describe Rspec do + before :each do + @rspec_autotest = Rspec.new + @rspec_autotest.stub!(:ruby).and_return "ruby" + @rspec_autotest.stub!(:add_options_if_present).and_return "-O spec/spec.opts" + + @ruby = @rspec_autotest.ruby + @spec_command = @rspec_autotest.spec_command + @options = @rspec_autotest.add_options_if_present + @files_to_test = { + :spec => ["file_one", "file_two"] + } + # this is not the inner representation of Autotest! + @rspec_autotest.stub!(:files_to_test).and_return @files_to_test + @files_to_test.stub!(:keys).and_return @files_to_test[:spec] + @to_test = @files_to_test.keys.flatten.join ' ' + end + + it "should make the apropriate test command" do + @rspec_autotest.make_test_cmd(@files_to_test).should == "#{@ruby} -S #{@spec_command} #{@options} #{@to_test}" + end + end + + describe Rspec, "test mappings" do + before :each do + @proc = mock Proc + @kernel = mock Kernel + @kernel.stub!(:proc).and_return @proc + @rspec_autotest = Rspec.new(@kernel) + end + + it "should map all filenames in spec/ which end in .rb" do + @rspec_autotest.test_mappings[%r%^spec/.*\.rb$%].should == @proc + end + + it "should map all names in lib which end in .rb to the corresponding ones in spec/" do + @rspec_autotest.test_mappings[%r%^lib/(.*)\.rb$%].should == @proc + end + + it "should find all files in spec/shares/* and the spec helper in spec/spec_helper" do + @rspec_autotest.test_mappings[%r%^spec/(spec_helper|shared/.*)\.rb$%].should == @proc + end + end + + describe Rspec, "handling results" do + include AutotestHelper + + before :each do + common_setup + @rspec_autotest = Rspec.new(@kernel, @posix_separator, @windows_alt_separator) + @rspec_autotest.stub!(:hook) + + @results = mock String + @results.stub!(:scan).and_return "" + end + + it "should call hook(:red) if there are failures" do + @rspec_autotest.stub!(:consolidate_failures).and_return ["spec/some_spec.rb"] + + @rspec_autotest.should_receive(:hook).with(:red) + @rspec_autotest.handle_results(@results) + end + + it "should call hook(:green) if there are no failures" do + @rspec_autotest.stub!(:consolidate_failures).and_return [] + @rspec_autotest.should_receive(:hook).with(:green) + @rspec_autotest.handle_results(@results) + end + end + + describe Rspec, "handling failed results" do + include AutotestHelper + + before :each do + common_setup + end + + it %(should scan the output into a multi-dimensional array, + consisting of the failing spec's name as the first element, + and the failure as the second) do + @rspec_autotest = Rspec.new + @rspec_autotest.failed_results(@rspec_output).should == [ + [ + "false should be false", + "expected: true,\n got: false (using ==)\n./spec/autotest/rspec_spec.rb:203:" + ] + ] + end + end + + describe Rspec, "specs for a given file" do + before :each do + @lib_file = "lib/something.rb" + @spec_file = "spec/something_spec.rb" + @rspec_autotest = Rspec.new + + @rspec_autotest.instance_variable_set("@files", {@lib_file => Time.now, @spec_file => Time.now}) + @rspec_autotest.stub!(:find_files_to_test).and_return true + end + + it "should find the spec file for a given lib file" do + @rspec_autotest.specs_for_file(@lib_file).should == [@spec_file] + end + + it "should find the spec file if given a spec file" do + @rspec_autotest.specs_for_file(@spec_file).should == [@spec_file] + end + + it "should only find the file if the file is being tracked (in @file)" do + @other_file = "lib/some_non_tracked_file" + @rspec_autotest.specs_for_file(@other_file).should == [] + end + end + + describe Rspec, "consolidating failures" do + include AutotestHelper + + before :each do + common_setup + @rspec_autotest = Rspec.new + + @spec_file = "./spec/autotest/rspec_spec.rb" + @rspec_autotest.instance_variable_set("@files", {@spec_file => Time.now}) + @rspec_autotest.stub!(:find_files_to_test).and_return true + end + + it "should return no failures if no failures were given in the output" do + @rspec_autotest.stub!(:failed_results).and_return [[]] + @rspec_autotest.consolidate_failures(@rspec_autotest.failed_results).should == {} + end + + it "should return a hash with the spec filename => spec name for each failure or error" do + @rspec_autotest.stub!(:failed_results).and_return([ + [ + "false should be false", + "expected: true,\n got: false (using ==)\n./spec/autotest/rspec_spec.rb:203:" + ] + ]) + @rspec_autotest.consolidate_failures(@rspec_autotest.failed_results).should == {@spec_file => ["false should be false"]} + end + + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/autotest_helper.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/autotest_helper.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/autotest_helper.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/autotest_helper.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,5 @@ +require "rubygems" +require 'autotest' +dir = File.dirname(__FILE__) +require "#{dir}/spec_helper" +require File.expand_path("#{dir}/../lib/autotest/rspec") \ No newline at end of file diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/rspec_suite.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/rspec_suite.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/rspec_suite.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/rspec_suite.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,7 @@ +if __FILE__ == $0 + dir = File.dirname(__FILE__) + Dir["#{dir}/**/*_spec.rb"].each do |file| +# puts "require '#{file}'" + require file + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/example/configuration_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/example/configuration_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/example/configuration_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/example/configuration_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,290 @@ +require File.dirname(__FILE__) + '/../../spec_helper.rb' + +module Spec + module Example + ConfigurationSpec = + describe Configuration, :shared => true do + before(:each) do + @config = Configuration.new + @behaviour = mock("behaviour") + end + end + + describe Configuration, "#mock_with" do + include ConfigurationSpec + it "should default mock framework to rspec" do + @config.mock_framework.should =~ /\/plugins\/mock_frameworks\/rspec$/ + end + + it "should let you set rspec mocking explicitly" do + @config.mock_with(:rspec) + @config.mock_framework.should =~ /\/plugins\/mock_frameworks\/rspec$/ + end + + it "should let you set mocha" do + @config.mock_with(:mocha) + @config.mock_framework.should =~ /\/plugins\/mock_frameworks\/mocha$/ + end + + it "should let you set flexmock" do + @config.mock_with(:flexmock) + @config.mock_framework.should =~ /\/plugins\/mock_frameworks\/flexmock$/ + end + + it "should let you set rr" do + @config.mock_with(:rr) + @config.mock_framework.should =~ /\/plugins\/mock_frameworks\/rr$/ + end + + it "should let you set an arbitrary adapter module" do + adapter = Module.new + @config.mock_with(adapter) + @config.mock_framework.should == adapter + end + end + + describe Configuration, "#include" do + include ConfigurationSpec + + before do + @original_configuration = Spec::Runner.configuration + spec_configuration = @config + Spec::Runner.instance_eval {@configuration = spec_configuration} + @example_group_class = Class.new(ExampleGroup) do + class << self + def this_class_has_special_methods + end + end + end + ExampleGroupFactory.register(:foobar, @example_group_class) + end + + after do + original_configuration = @original_configuration + Spec::Runner.instance_eval {@configuration = original_configuration} + ExampleGroupFactory.reset + end + + it "should include the submitted module in ExampleGroup subclasses" do + mod = Module.new + @config.include mod + Class.new(@example_group_class).included_modules.should include(mod) + end + + it "should let you define modules to be included for a specific type" do + mod = Module.new + @config.include mod, :behaviour_type => :foobar + Class.new(@example_group_class).included_modules.should include(mod) + end + + it "should not include modules in a type they are not intended for" do + mod = Module.new + @other_example_group_class = Class.new(ExampleGroup) + ExampleGroupFactory.register(:baz, @other_example_group_class) + + @config.include mod, :behaviour_type => :foobar + + Class.new(@other_example_group_class).included_modules.should_not include(mod) + end + + it "should not extend the ExampleGroup baseclass (to enable the included hook to work properly)" do + pending("need to figure out how to best express this one") + end + end + + ConfigurationCallbacksSpec = + describe Configuration, " callbacks", :shared => true do + before do + @config = Configuration.new + @special_behaviour = Class.new(ExampleGroup) + @special_child_behaviour = Class.new(@special_behaviour) + @nonspecial_behaviour = Class.new(ExampleGroup) + ExampleGroupFactory.register(:special, @special_behaviour) + ExampleGroupFactory.register(:special_child, @special_child_behaviour) + ExampleGroupFactory.register(:non_special, @nonspecial_behaviour) + @behaviour = @special_child_behaviour.describe "Special Example Group" + @unselected_behaviour = Class.new(@nonspecial_behaviour).describe "Non Special Example Group" + end + + after do + ExampleGroupFactory.reset + end + end + + describe Configuration, "#prepend_before" do + include ConfigurationCallbacksSpec + + it "prepends the before block on all instances of the passed in behaviour_type" do + order = [] + @config.prepend_before(:all) do + order << :prepend__before_all + end + @config.prepend_before(:all, :behaviour_type => :special) do + order << :special_prepend__before_all + end + @config.prepend_before(:all, :behaviour_type => :special_child) do + order << :special_child_prepend__before_all + end + @config.prepend_before(:each) do + order << :prepend__before_each + end + @config.prepend_before(:each, :behaviour_type => :special) do + order << :special_prepend__before_each + end + @config.prepend_before(:each, :behaviour_type => :special_child) do + order << :special_child_prepend__before_each + end + @config.prepend_before(:all, :behaviour_type => :non_special) do + order << :special_prepend__before_all + end + @config.prepend_before(:each, :behaviour_type => :non_special) do + order << :special_prepend__before_each + end + @behaviour.it "calls prepend_before" do + end + + @behaviour.suite.run + order.should == [ + :prepend__before_all, + :special_prepend__before_all, + :special_child_prepend__before_all, + :prepend__before_each, + :special_prepend__before_each, + :special_child_prepend__before_each + ] + end + end + + describe Configuration, "#append_before" do + include ConfigurationCallbacksSpec + + it "calls append_before on the behaviour_type" do + order = [] + @config.append_before(:all) do + order << :append_before_all + end + @config.append_before(:all, :behaviour_type => :special) do + order << :special_append_before_all + end + @config.append_before(:all, :behaviour_type => :special_child) do + order << :special_child_append_before_all + end + @config.append_before(:each) do + order << :append_before_each + end + @config.append_before(:each, :behaviour_type => :special) do + order << :special_append_before_each + end + @config.append_before(:each, :behaviour_type => :special_child) do + order << :special_child_append_before_each + end + @config.append_before(:all, :behaviour_type => :non_special) do + order << :special_append_before_all + end + @config.append_before(:each, :behaviour_type => :non_special) do + order << :special_append_before_each + end + @behaviour.it "calls append_before" do + end + + @behaviour.suite.run + order.should == [ + :append_before_all, + :special_append_before_all, + :special_child_append_before_all, + :append_before_each, + :special_append_before_each, + :special_child_append_before_each + ] + end + end + + describe Configuration, "#prepend_after" do + include ConfigurationCallbacksSpec + + it "prepends the after block on all instances of the passed in behaviour_type" do + order = [] + @config.prepend_after(:all) do + order << :prepend__after_all + end + @config.prepend_after(:all, :behaviour_type => :special) do + order << :special_prepend__after_all + end + @config.prepend_after(:all, :behaviour_type => :special) do + order << :special_child_prepend__after_all + end + @config.prepend_after(:each) do + order << :prepend__after_each + end + @config.prepend_after(:each, :behaviour_type => :special) do + order << :special_prepend__after_each + end + @config.prepend_after(:each, :behaviour_type => :special) do + order << :special_child_prepend__after_each + end + @config.prepend_after(:all, :behaviour_type => :non_special) do + order << :special_prepend__after_all + end + @config.prepend_after(:each, :behaviour_type => :non_special) do + order << :special_prepend__after_each + end + @behaviour.it "calls prepend_after" do + end + + @behaviour.suite.run + order.should == [ + :special_child_prepend__after_each, + :special_prepend__after_each, + :prepend__after_each, + :special_child_prepend__after_all, + :special_prepend__after_all, + :prepend__after_all + ] + end + end + + describe Configuration, "#append_after" do + include ConfigurationCallbacksSpec + + it "calls append_after on the behaviour_type" do + order = [] + @config.append_after(:all) do + order << :append__after_all + end + @config.append_after(:all, :behaviour_type => :special) do + order << :special_append__after_all + end + @config.append_after(:all, :behaviour_type => :special_child) do + order << :special_child_append__after_all + end + @config.append_after(:each) do + order << :append__after_each + end + @config.append_after(:each, :behaviour_type => :special) do + order << :special_append__after_each + end + @config.append_after(:each, :behaviour_type => :special_child) do + order << :special_child_append__after_each + end + @config.append_after(:all, :behaviour_type => :non_special) do + order << :non_special_append_after_all + end + @config.append_after(:each, :behaviour_type => :non_special) do + order << :non_special_append_after_each + end + @behaviour.it "calls append_after" do + end + + @behaviour.suite.run + order.should == [ + :special_child_append__after_each, + :special_append__after_each, + :append__after_each, + :special_child_append__after_all, + :special_append__after_all, + :append__after_all + ] + end + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/example/example_group_class_definition_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/example/example_group_class_definition_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/example/example_group_class_definition_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/example/example_group_class_definition_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,48 @@ +require File.dirname(__FILE__) + '/../../spec_helper' + +module Spec + module Example + class ExampleGroupSubclass < ExampleGroup + class << self + attr_accessor :examples_ran + end + + @@klass_variable_set = true + CONSTANT = :foobar + + before do + @instance_variable = :hello + end + + it "should run" do + self.class.examples_ran = true + end + + it "should have access to instance variables" do + @instance_variable.should == :hello + end + + it "should have access to class variables" do + @@klass_variable_set.should == true + end + + it "should have access to constants" do + CONSTANT.should == :foobar + end + + it "should have access to methods defined in the Example Group" do + a_method.should == 22 + end + + def a_method + 22 + end + end + + describe ExampleGroupSubclass do + it "should run" do + ExampleGroupSubclass.examples_ran.should be_true + end + end + end +end \ No newline at end of file diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/example/example_group_description_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/example/example_group_description_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/example/example_group_description_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/example/example_group_description_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,98 @@ +require File.dirname(__FILE__) + '/../../spec_helper' + +module Spec + module Example + describe ExampleGroupDescription, " constructed with a single String" do + before(:each) {@description = ExampleGroupDescription.new("abc")} + + it "should provide that string as its name" do + @description.description.should == "abc" + end + it "should provide nil as its type" do + @description.described_type.should be_nil + end + it "should respond to []" do + @description[:key].should be_nil + end + it "should respond to []=" do + @description[:key] = :value + @description[:key].should == :value + end + it "should return for == when value matches description" do + @description.should == "abc" + end + it "should return for == when value is other description that matches description" do + @description.should == ExampleGroupDescription.new("abc") + end + end + + describe ExampleGroupDescription, " constructed with a Type" do + before(:each) {@description = ExampleGroupDescription.new(ExampleGroup)} + + it "should provide a String representation of that type (fully qualified) as its name" do + @description.description.should == "Spec::Example::ExampleGroup" + end + it "should provide that type (fully qualified) as its type" do + @description.described_type.should == Spec::Example::ExampleGroup + end + end + + describe ExampleGroupDescription, " constructed with a Type and a String" do + before(:each) {@description = ExampleGroupDescription.new(ExampleGroup, " behaving")} + + it "should include the type and second String in its name" do + @description.description.should == "Spec::Example::ExampleGroup behaving" + end + it "should provide that type (fully qualified) as its type" do + @description.described_type.should == Spec::Example::ExampleGroup + end + end + + describe ExampleGroupDescription, "constructed with a Type and a String not starting with a space" do + before(:each) {@description = ExampleGroupDescription.new(ExampleGroup, "behaving")} + + it "should include the type and second String with a space in its name" do + @description.description.should == "Spec::Example::ExampleGroup behaving" + end + end + + describe ExampleGroupDescription, "constructed with a Type and a String starting with a ." do + before(:each) {@description = ExampleGroupDescription.new(ExampleGroup, ".behaving")} + + it "should include the type and second String with a space in its name" do + @description.description.should == "Spec::Example::ExampleGroup.behaving" + end + end + + describe ExampleGroupDescription, "constructed with a Type and a String starting with a #" do + before(:each) {@description = ExampleGroupDescription.new(ExampleGroup, "#behaving")} + + it "should include the type and second String with a space in its name" do + @description.description.should == "Spec::Example::ExampleGroup#behaving" + end + end + + describe ExampleGroupDescription, "constructed with String, Type, String" do + before(:each) {@description = ExampleGroupDescription.new("A", Hash, "with one entry")} + + it "should include create a description with all arguments" do + @description.description.should == "A Hash with one entry" + end + end + + describe ExampleGroupDescription, " constructed with options" do + before(:each) do + @description = ExampleGroupDescription.new(ExampleGroup, :a => "b", :spec_path => "blah") + end + + it "should expose its options" do + @description[:a].should == "b" + end + + it "should wrap spec path using File.expand_path" do + @description[:spec_path].should == File.expand_path("blah") + end + end + + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/example/example_group_factory_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/example/example_group_factory_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/example/example_group_factory_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/example/example_group_factory_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,145 @@ +require File.dirname(__FILE__) + '/../../spec_helper' + +module Spec + module Example + describe ExampleGroupFactory, "with :foobar registered as custom type" do + + before do + @behaviour = Class.new(ExampleGroup) + ExampleGroupFactory.register(:foobar, @behaviour) + end + + after do + ExampleGroupFactory.reset + end + + it "should #get the default behaviour type when passed nil" do + ExampleGroupFactory.get(nil).should == ExampleGroup + end + + it "should #get custom type for :foobar" do + ExampleGroupFactory.get(:foobar).should == @behaviour + end + + it "should #get the actual type when that is passed in" do + ExampleGroupFactory.get(@behaviour).should == @behaviour + end + + it "should #get nil for unregistered non-nil values" do + ExampleGroupFactory.get(:does_not_exist).should be_nil + end + + it "should raise error for #get! with unknown key" do + proc do + ExampleGroupFactory.get!(:does_not_exist) + end.should raise_error + end + end + + describe ExampleGroupFactory, "#create_example_group" do + it "should create a uniquely named class" do + behaviour = Spec::Example::ExampleGroupFactory.create_example_group("behaviour") {} + behaviour.name.should =~ /Spec::Example::ExampleGroup::Subclass_\d+/ + end + + it "should create a Spec::Example::Example subclass by default" do + behaviour = Spec::Example::ExampleGroupFactory.create_example_group("behaviour") {} + behaviour.superclass.should == Spec::Example::ExampleGroup + end + + it "should create a Spec::Example::Example when :type => :default" do + behaviour = Spec::Example::ExampleGroupFactory.create_example_group( + "behaviour", :type => :default + ) {} + behaviour.superclass.should == Spec::Example::ExampleGroup + end + + it "should create a Spec::Example::Example when :behaviour_type => :default" do + behaviour = Spec::Example::ExampleGroupFactory.create_example_group( + "behaviour", :behaviour_type => :default + ) {} + behaviour.superclass.should == Spec::Example::ExampleGroup + end + + it "should create specified type when :type => :something_other_than_default" do + klass = Class.new(ExampleGroup) do + def initialize(*args, &block); end + end + Spec::Example::ExampleGroupFactory.register(:something_other_than_default, klass) + behaviour = Spec::Example::ExampleGroupFactory.create_example_group( + "behaviour", :type => :something_other_than_default + ) {} + behaviour.superclass.should == klass + end + + it "should create specified type when :behaviour_type => :something_other_than_default" do + klass = Class.new(ExampleGroup) do + def initialize(*args, &block); end + end + Spec::Example::ExampleGroupFactory.register(:something_other_than_default, klass) + behaviour = Spec::Example::ExampleGroupFactory.create_example_group( + "behaviour", :behaviour_type => :something_other_than_default + ) {} + behaviour.superclass.should == klass + end + + it "should create a type indicated by :spec_path" do + klass = Class.new(ExampleGroup) do + def initialize(*args, &block); end + end + Spec::Example::ExampleGroupFactory.register(:something_other_than_default, klass) + behaviour = Spec::Example::ExampleGroupFactory.create_example_group( + "behaviour", :spec_path => "./spec/something_other_than_default/some_spec.rb" + ) {} + behaviour.superclass.should == klass + end + + it "should create a type indicated by :spec_path (with spec_path generated by caller on windows)" do + klass = Class.new(ExampleGroup) do + def initialize(*args, &block); end + end + Spec::Example::ExampleGroupFactory.register(:something_other_than_default, klass) + behaviour = Spec::Example::ExampleGroupFactory.create_example_group( + "behaviour", :spec_path => "./spec\\something_other_than_default\\some_spec.rb" + ) {} + behaviour.superclass.should == klass + end + + it "should create and register a Spec::Example::Example if :shared => true" do + shared_example_group = Spec::Example::ExampleGroupFactory.create_example_group( + "name", :spec_path => '/blah/spec/models/blah.rb', :behaviour_type => :controller, :shared => true + ) {} + shared_example_group.should be_an_instance_of(Spec::Example::SharedExampleGroup) + SharedExampleGroup.shared_example_groups.should include(shared_example_group) + end + + it "should favor the :behaviour_type over the :spec_path" do + klass = Class.new(ExampleGroup) do + def initialize(*args, &block); end + end + Spec::Example::ExampleGroupFactory.register(:something_other_than_default, klass) + behaviour = Spec::Example::ExampleGroupFactory.create_example_group( + "name", :spec_path => '/blah/spec/models/blah.rb', :behaviour_type => :something_other_than_default + ) {} + behaviour.superclass.should == klass + end + + it "should register ExampleGroup by default" do + example_group = Spec::Example::ExampleGroupFactory.create_example_group("The ExampleGroup") do + end + rspec_options.example_groups.should include(example_group) + end + + it "should enable unregistering of ExampleGroups" do + example_group = Spec::Example::ExampleGroupFactory.create_example_group("The ExampleGroup") do + unregister + end + rspec_options.example_groups.should_not include(example_group) + end + + after(:each) do + Spec::Example::ExampleGroupFactory.reset + end + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/example/example_group_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/example/example_group_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/example/example_group_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/example/example_group_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,468 @@ +require File.dirname(__FILE__) + '/../../spec_helper' + +module Spec + module Example + describe ExampleGroup do + attr_reader :options, :example_group, :result, :reporter + before(:all) do + @original_rspec_options = $rspec_options + end + + before(:each) do + @options = ::Spec::Runner::Options.new(StringIO.new, StringIO.new) + $rspec_options = @options + options.formatters << mock("formatter", :null_object => true) + options.backtrace_tweaker = mock("backtrace_tweaker", :null_object => true) + @reporter = FakeReporter.new(@options) + options.reporter = reporter + @example_group = Class.new(ExampleGroup) do + describe("example") + it "does nothing" + end + class << example_group + public :include + end + @result = nil + end + + after(:each) do + $rspec_options = @original_rspec_options + ExampleGroup.reset + end + + describe ExampleGroup, ".describe" do + attr_reader :child_example_group + before do + @child_example_group = @example_group.describe("Another ExampleGroup") do + it "should pass" do + true.should be_true + end + end + end + + it "should create a subclass of the ExampleGroup when passed a block" do + child_example_group.superclass.should == @example_group + @options.example_groups.should include(child_example_group) + end + + it "should not inherit examples" do + child_example_group.examples.length.should == 1 + end + end + + describe ExampleGroup, ".it" do + it "should should create an example instance" do + lambda { + @example_group.it("") + }.should change { @example_group.examples.length }.by(1) + end + end + + describe ExampleGroup, ".xit" do + before(:each) do + Kernel.stub!(:warn) + end + + it "should NOT should create an example instance" do + lambda { + @example_group.xit("") + }.should_not change(@example_group.examples, :length) + end + + it "should warn that it is disabled" do + Kernel.should_receive(:warn).with("Example disabled: foo") + @example_group.xit("foo") + end + end + + describe ExampleGroup, ".suite" do + it "should return an empty ExampleSuite when there is no description" do + ExampleGroup.description.should be_nil + ExampleGroup.suite.should be_instance_of(ExampleSuite) + ExampleGroup.suite.tests.should be_empty + end + + it "should return an ExampleSuite with Examples" do + behaviour = Class.new(ExampleGroup) do + describe('example') + it "should pass" do + 1.should == 1 + end + end + suite = behaviour.suite + suite.tests.length.should == 1 + suite.tests.first._example.description.should == "should pass" + end + + it "should include methods that begin with test and has an arity of 0 in suite" do + behaviour = Class.new(ExampleGroup) do + describe('example') + def test_any_args(*args) + true.should be_true + end + def test_something + 1.should == 1 + end + def test + raise "This is not a real test" + end + def testify + raise "This is not a real test" + end + end + suite = behaviour.suite + suite.tests.length.should == 2 + descriptions = suite.tests.collect {|test| test._example.description}.sort + descriptions.should == ["test_any_args", "test_something"] + suite.run.should be_true + end + + it "should include methods that begin with should and has an arity of 0 in suite" do + behaviour = Class.new(ExampleGroup) do + describe('example') + def shouldCamelCase + true.should be_true + end + def should_any_args(*args) + true.should be_true + end + def should_something + 1.should == 1 + end + def should_not_something + 1.should_not == 2 + end + def should + raise "This is not a real example" + end + def should_not + raise "This is not a real example" + end + end + behaviour = behaviour.dup + suite = behaviour.suite + suite.tests.length.should == 4 + descriptions = suite.tests.collect {|test| test._example.description}.sort + descriptions.should include("shouldCamelCase") + descriptions.should include("should_any_args") + descriptions.should include("should_something") + descriptions.should include("should_not_something") + end + + it "should not include methods that begin with test_ and has an arity > 0 in suite" do + behaviour = Class.new(ExampleGroup) do + describe('example') + def test_invalid(foo) + 1.should == 1 + end + def testInvalidCamelCase(foo) + 1.should == 1 + end + end + suite = behaviour.suite + suite.tests.length.should == 0 + end + + it "should not include methods that begin with should_ and has an arity > 0 in suite" do + behaviour = Class.new(ExampleGroup) do + describe('example') + def should_invalid(foo) + 1.should == 1 + end + def shouldInvalidCamelCase(foo) + 1.should == 1 + end + def should_not_invalid(foo) + 1.should == 1 + end + end + suite = behaviour.suite + suite.tests.length.should == 0 + end + end + + describe ExampleGroup, ".description" do + it "should return the same description instance for each call" do + @example_group.description.should eql(@example_group.description) + end + end + + describe ExampleGroup, ".remove_after" do + it "should unregister a given after(:each) block" do + after_all_ran = false + @example_group.it("example") {} + proc = Proc.new { after_all_ran = true } + ExampleGroup.after(:each, &proc) + suite = @example_group.suite + suite.run + after_all_ran.should be_true + + after_all_ran = false + ExampleGroup.remove_after(:each, &proc) + suite = @example_group.suite + suite.run + after_all_ran.should be_false + end + end + + describe ExampleGroup, ".include" do + it "should have accessible class methods from included module" do + mod1_method_called = false + mod1 = Module.new do + class_methods = Module.new do + define_method :mod1_method do + mod1_method_called = true + end + end + + metaclass.class_eval do + define_method(:included) do |receiver| + receiver.extend class_methods + end + end + end + + mod2_method_called = false + mod2 = Module.new do + class_methods = Module.new do + define_method :mod2_method do + mod2_method_called = true + end + end + + metaclass.class_eval do + define_method(:included) do |receiver| + receiver.extend class_methods + end + end + end + + @example_group.include mod1, mod2 + + @example_group.mod1_method + @example_group.mod2_method + mod1_method_called.should be_true + mod2_method_called.should be_true + end + end + + describe ExampleGroup, ".number_of_examples" do + it "should count number of specs" do + proc do + @example_group.it("one") {} + @example_group.it("two") {} + @example_group.it("three") {} + @example_group.it("four") {} + end.should change {@example_group.number_of_examples}.by(4) + end + end + + describe ExampleGroup, ".class_eval" do + it "should allow constants to be defined" do + behaviour = Class.new(ExampleGroup) do + describe('example') + FOO = 1 + it "should reference FOO" do + FOO.should == 1 + end + end + suite = behaviour.suite + suite.run + Object.const_defined?(:FOO).should == false + end + end + + describe ExampleGroup, '.register' do + it "should add ExampleGroup to set of ExampleGroups to be run" do + example_group.register + options.example_groups.should include(example_group) + end + end + + describe ExampleGroup, '.unregister' do + before do + example_group.register + options.example_groups.should include(example_group) + end + + it "should remove ExampleGroup from set of ExampleGroups to be run" do + example_group.unregister + options.example_groups.should_not include(example_group) + end + end + end + + class ExampleModuleScopingSpec < ExampleGroup + describe ExampleGroup, " via a class definition" + + module Foo + module Bar + def self.loaded? + true + end + end + end + include Foo + + it "should understand module scoping" do + Bar.should be_loaded + end + + @@foo = 1 + + it "should allow class variables to be defined" do + @@foo.should == 1 + end + end + + class ExampleClassVariablePollutionSpec < ExampleGroup + describe ExampleGroup, " via a class definition without a class variable" + + it "should not retain class variables from other Example classes" do + proc do + @@foo + end.should raise_error + end + end + + describe ExampleGroup, '.run functional example' do + def count + @count ||= 0 + @count = @count + 1 + @count + end + + before(:all) do + count.should == 1 + end + + before(:all) do + count.should == 2 + end + + before(:each) do + count.should == 3 + end + + before(:each) do + count.should == 4 + end + + it "should run before(:all), before(:each), example, after(:each), after(:all) in order" do + count.should == 5 + end + + after(:each) do + count.should == 7 + end + + after(:each) do + count.should == 6 + end + + after(:all) do + count.should == 9 + end + + after(:all) do + count.should == 8 + end + end + + describe ExampleGroup, "#initialize" do + the_behaviour = self + it "should have copy of behaviour" do + the_behaviour.superclass.should == ExampleGroup + end + end + + describe ExampleGroup, "#pending" do + it "should raise a Pending error when its block fails" do + block_ran = false + lambda { + pending("something") do + block_ran = true + raise "something wrong with my example" + end + }.should raise_error(Spec::Example::ExamplePendingError, "something") + block_ran.should == true + end + + it "should raise Spec::Example::PendingExampleFixedError when its block does not fail" do + block_ran = false + lambda { + pending("something") do + block_ran = true + end + }.should raise_error(Spec::Example::PendingExampleFixedError, "Expected pending 'something' to fail. No Error was raised.") + block_ran.should == true + end + end + + describe ExampleGroup, "#run" do + before do + @options = ::Spec::Runner::Options.new(StringIO.new, StringIO.new) + @original_rspec_options = $rspec_options + $rspec_options = @options + end + + after do + $rspec_options = @original_rspec_options + end + + it "should not run when there are no examples" do + behaviour = Class.new(ExampleGroup) do + describe("Foobar") + end + behaviour.examples.should be_empty + + reporter = mock("Reporter") + reporter.should_not_receive(:add_example_group) + suite = behaviour.suite + suite.run + end + end + + class ExampleSubclass < ExampleGroup + end + + describe ExampleGroup, "subclasses" do + after do + ExampleGroupFactory.reset + end + + it "should have access to the described_type" do + behaviour = Class.new(ExampleSubclass) do + describe(Array) + end + behaviour.send(:described_type).should == Array + end + end + + describe Enumerable do + def each(&block) + ["4", "2", "1"].each(&block) + end + + it "should be included in examples because it is a module" do + map{|e| e.to_i}.should == [4,2,1] + end + end + + describe "An", Enumerable, "as a second argument" do + def each(&block) + ["4", "2", "1"].each(&block) + end + + it "should be included in examples because it is a module" do + map{|e| e.to_i}.should == [4,2,1] + end + end + + describe String do + it "should not be included in examples because it is not a module" do + lambda{self.map}.should raise_error(NoMethodError, /undefined method `map' for/) + end + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/example/example_matcher_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/example/example_matcher_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/example/example_matcher_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/example/example_matcher_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,96 @@ +require File.dirname(__FILE__) + '/../../spec_helper.rb' + +module Spec + module Example + module ExampleMatcherSpecHelper + class MatchDescription + def initialize(description) + @description = description + end + + def matches?(matcher) + matcher.matches?(@description) + end + + def failure_message + "expected matcher.matches?(#{@description.inspect}) to return true, got false" + end + + def negative_failure_message + "expected matcher.matches?(#{@description.inspect}) to return false, got true" + end + end + def match_description(description) + MatchDescription.new(description) + end + end + + describe ExampleMatcher, "#matches?" do + include ExampleMatcherSpecHelper + + it "should match correct behaviour and example" do + matcher = ExampleMatcher.new("behaviour", "example") + matcher.should match_description("behaviour example") + end + + it "should not match wrong example" do + matcher = ExampleMatcher.new("behaviour", "other example") + matcher.should_not match_description("behaviour example") + end + + it "should not match wrong behaviour" do + matcher = ExampleMatcher.new("other behaviour", "example") + matcher.should_not match_description("behaviour example") + end + + it "should match example only" do + matcher = ExampleMatcher.new("behaviour", "example") + matcher.should match_description("example") + end + + it "should match behaviour only" do + matcher = ExampleMatcher.new("behaviour", "example") + matcher.should match_description("behaviour") + end + + it "should match behaviour ending with before(:all)" do + matcher = ExampleMatcher.new("behaviour", "example") + matcher.should match_description("behaviour before(:all)") + end + + it "should escape regexp chars" do + matcher = ExampleMatcher.new("(con|text)", "[example]") + matcher.should_not match_description("con p") + end + + it "should match when behaviour is modularized" do + matcher = ExampleMatcher.new("MyModule::MyClass", "example") + matcher.should match_description("MyClass example") + end + end + + describe ExampleMatcher, "#matches? normal case" do + it "matches when passed in example matches" do + matcher = ExampleMatcher.new("Foo", "bar") + matcher.matches?(["no match", "Foo bar"]).should == true + end + + it "does not match when no passed in examples match" do + matcher = ExampleMatcher.new("Foo", "bar") + matcher.matches?(["no match1", "no match2"]).should == false + end + end + + describe ExampleMatcher, "#matches? where description has '::' in it" do + it "matches when passed in example matches" do + matcher = ExampleMatcher.new("Foo::Bar", "baz") + matcher.matches?(["no match", "Foo::Bar baz"]).should == true + end + + it "does not match when no passed in examples match" do + matcher = ExampleMatcher.new("Foo::Bar", "baz") + matcher.matches?(["no match1", "no match2"]).should == false + end + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/example/example_methods_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/example/example_methods_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/example/example_methods_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/example/example_methods_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,75 @@ +require File.dirname(__FILE__) + '/../../spec_helper' + +module Spec + module Example + module ModuleThatIsReopened + end + + module ExampleMethods + include ModuleThatIsReopened + end + + module ModuleThatIsReopened + def module_that_is_reopened_method + end + end + + describe "ExampleMethods with an included module that is reopened" do + it "should have repoened methods" do + method(:module_that_is_reopened_method).should_not be_nil + end + end + + describe ExampleMethods, " lifecycle" do + before do + @options = ::Spec::Runner::Options.new(StringIO.new, StringIO.new) + @options.formatters << mock("formatter", :null_object => true) + @options.backtrace_tweaker = mock("backtrace_tweaker", :null_object => true) + @reporter = FakeReporter.new(@options) + @options.reporter = @reporter + + ExampleMethods.before_all_parts.should == [] + ExampleMethods.before_each_parts.should == [] + ExampleMethods.after_each_parts.should == [] + ExampleMethods.after_all_parts.should == [] + def ExampleMethods.count + @count ||= 0 + @count = @count + 1 + @count + end + end + + after do + ExampleMethods.instance_variable_set("@before_all_parts", []) + ExampleMethods.instance_variable_set("@before_each_parts", []) + ExampleMethods.instance_variable_set("@after_each_parts", []) + ExampleMethods.instance_variable_set("@after_all_parts", []) + end + + it "should pass before and after callbacks to all ExampleGroup subclasses" do + ExampleMethods.before(:all) do + ExampleMethods.count.should == 1 + end + + ExampleMethods.before(:each) do + ExampleMethods.count.should == 2 + end + + ExampleMethods.after(:each) do + ExampleMethods.count.should == 3 + end + + ExampleMethods.after(:all) do + ExampleMethods.count.should == 4 + end + + @example_group = Class.new(ExampleGroup) do + it "should use ExampleMethods callbacks" do + end + end + @example_group.suite.run + ExampleMethods.count.should == 5 + end + end + end +end \ No newline at end of file diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/example/example_runner_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/example/example_runner_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/example/example_runner_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/example/example_runner_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,250 @@ +require File.dirname(__FILE__) + '/../../spec_helper.rb' + +module Spec + module Example + describe ExampleRunner, "#run", :shared => true do + before(:each) do + @options = ::Spec::Runner::Options.new(StringIO.new, StringIO.new) + @reporter = ::Spec::Runner::Reporter.new(@options) + @options.reporter = @reporter + @example_group_class = Class.new(ExampleGroup) do + describe("Some Examples") + end + end + + def create_runner(example_definition) + example = @example_group_class.new(example_definition) + runner = ExampleRunner.new(@options, example) + runner.stub!(:verify_mocks) + runner.stub!(:teardown_mocks) + runner + end + end + + describe ExampleRunner, "#run with blank passing example" do + it_should_behave_like "Spec::Example::ExampleRunner#run" + + before do + @e = @example_group_class.it("example") {} + @runner = create_runner(@e) + end + + it "should send reporter example_started" do + @reporter.should_receive(:example_started).with(equal(@e)) + @runner.run + end + + it "should report its name for dry run" do + @options.dry_run = true + @reporter.should_receive(:example_finished).with(equal(@e), nil, "example") + @runner.run + end + + it "should report success" do + @reporter.should_receive(:example_finished).with(equal(@e), nil, nil) + @runner.run + end + end + + describe ExampleRunner, "#run with a failing example" do + predicate_matchers[:is_a] = [:is_a?] + it_should_behave_like "Spec::Example::ExampleRunner#run" + + before do + @e = @example_group_class.it("example") do + (2+2).should == 5 + end + @runner = create_runner(@e) + end + + it "should report failure due to failure" do + @reporter.should_receive(:example_finished).with( + equal(@e), + is_a(Spec::Expectations::ExpectationNotMetError), + "example" + ) + @runner.run + end + end + + describe ExampleRunner, "#run with a erroring example" do + it_should_behave_like "Spec::Example::ExampleRunner#run" + + before do + @error = error = NonStandardError.new("in body") + @example_definition = @example_group_class.it("example") do + raise(error) + end + @runner = create_runner(@example_definition) + end + + it "should report failure due to error" do + @reporter.should_receive(:example_finished).with( + equal(@example_definition), + @error, + "example" + ) + @runner.run + end + + it "should run after_each block" do + @example_group_class.after(:each) do + raise("in after_each") + end + @reporter.should_receive(:example_finished) do |example_definition, error, location| + example_definition.should equal(@example_definition) + location.should eql("example") + error.message.should eql("in body") + end + @runner.run + end + end + + describe ExampleRunner, "#run where before_each fails" do + it_should_behave_like "Spec::Example::ExampleRunner#run" + + before do + @example_ran = example_ran = false + @example_definition = @example_group_class.it("should not run") do + example_ran = true + end + @runner = create_runner(@example_definition) + @example_group_class.before(:each) {raise NonStandardError, "in before_each"} + end + + it "should not run example block if before_each fails" do + @runner.run + @example_ran.should == false + end + + it "should run after_each block" do + after_each_ran = false + @example_group_class.after(:each) {after_each_ran = true} + @runner.run + after_each_ran.should == true + end + + it "should report failure location when in before_each" do + @reporter.should_receive(:example_finished) do |example_definition, error, location| + example_definition.should equal(@example_definition) + error.message.should eql("in before_each") + location.should eql("before(:each)") + end + @runner.run + end + end + + describe ExampleRunner, "#run where after_each fails" do + it_should_behave_like "Spec::Example::ExampleRunner#run" + + before do + @example_ran = example_ran = false + @example_definition = @example_group_class.it("should not run") do + example_ran = true + end + @runner = create_runner(@example_definition) + @example_group_class.after(:each) { raise(NonStandardError.new("in after_each")) } + end + + it "should report failure location when in after_each" do + @reporter.should_receive(:example_finished) do |example_definition, error, location| + example_definition.should equal(@example_definition) + error.message.should eql("in after_each") + location.should eql("after(:each)") + end + @runner.run + end + end + + describe ExampleRunner, "#run with use cases" do + predicate_matchers[:is_a] = [:is_a?] + it_should_behave_like "Spec::Example::ExampleRunner#run" + + it "should run example block in scope of example" do + scope_object = nil + @example_definition = @example_group_class.it("should pass") do + self.instance_of?(Example).should == false + scope_object = self + end + @runner = create_runner(@example_definition) + @example_group_instance = @runner.example_group_instance + + @reporter.should_receive(:example_finished).with(equal(@example_definition), nil, nil) + @runner.run + + scope_object.should == @example_group_instance + scope_object.should be_instance_of(@example_group_class) + end + + it "should report NO NAME when told to use generated description with --dry-run" do + @options.dry_run = true + example_definition = @example_group_class.it(:__generate_docstring) do + 5.should == 5 + end + runner = create_runner(example_definition) + + @reporter.should_receive(:example_finished) do |example_definition, error, location| + example_definition.description.should == "NO NAME (Because of --dry-run)" + location.should == "NO NAME (Because of --dry-run)" + end + runner.run + end + + it "should report given name if present with --dry-run" do + @options.dry_run = true + example_definition = @example_group_class.it("example name") do + 5.should == 5 + end + runner = create_runner(example_definition) + + @reporter.should_receive(:example_finished) do |example_definition, error, location| + example_definition.description.should == "example name" + location.should == "example name" + end + runner.run + end + + it "should report NO NAME when told to use generated description with no expectations" do + example_definition = @example_group_class.it(:__generate_docstring) {} + runner = create_runner(example_definition) + @reporter.should_receive(:example_finished) do |example, error, location| + example.description.should == "NO NAME (Because there were no expectations)" + end + runner.run + end + + it "should report NO NAME when told to use generated description and matcher fails" do + example_definition = @example_group_class.it(:__generate_docstring) do + 5.should "" # Has no matches? method.. + end + runner = create_runner(example_definition) + + @reporter.should_receive(:example_finished) do |example, error, location| + example_definition.description.should == "NO NAME (Because of Error raised in matcher)" + location.should == "NO NAME (Because of Error raised in matcher)" + end + runner.run + end + + it "should report generated description when told to and it is available" do + example_definition = @example_group_class.it(:__generate_docstring) { + 5.should == 5 + } + runner = create_runner(example_definition) + + @reporter.should_receive(:example_finished) do |example_definition, error, location| + example_definition.description.should == "should == 5" + end + runner.run + end + + it "should unregister description_generated callback (lest a memory leak should build up)" do + example_definition = @example_group_class.it("something") + runner = create_runner(example_definition) + + Spec::Matchers.should_receive(:clear_generated_description) + runner.run + end + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/example/example_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/example/example_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/example/example_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/example/example_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,26 @@ +require File.dirname(__FILE__) + '/../../spec_helper' + +module Spec + module Example + describe Example do + before(:each) do + @example = Example.new "example" do + foo + end + end + + it "should tell you its docstring" do + @example.description.should == "example" + end + + it "should execute its block in the context provided" do + context = Class.new do + def foo + "foo" + end + end.new + @example.run_in(context).should == "foo" + end + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/example/example_suite_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/example/example_suite_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/example/example_suite_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/example/example_suite_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,593 @@ +require File.dirname(__FILE__) + '/../../spec_helper' + +module Spec + module Example + describe ExampleSuite, "#run", :shared => true do + before :all do + @original_rspec_options = $rspec_options + end + + before :each do + @options = ::Spec::Runner::Options.new(StringIO.new, StringIO.new) + $rspec_options = @options + @formatter = mock("formatter", :null_object => true) + @options.formatters << @formatter + @options.backtrace_tweaker = mock("backtrace_tweaker", :null_object => true) + @reporter = FakeReporter.new(@options) + @options.reporter = @reporter + @behaviour = Class.new(ExampleGroup) do + describe("example") + it "does nothing" do + end + end + class << @behaviour + public :include + end + end + + after :each do + $rspec_options = @original_rspec_options + ExampleGroup.reset + end + end + + describe ExampleSuite, "#run without failure in example", :shared => true do + it_should_behave_like "Spec::Example::ExampleSuite#run" + + it "should not add an example failure to the TestResult" do + suite = @behaviour.suite + suite.run.should be_true + end + end + + describe ExampleSuite, "#run with failure in example", :shared => true do + it_should_behave_like "Spec::Example::ExampleSuite#run" + + it "should add an example failure to the TestResult" do + suite = @behaviour.suite + suite.run.should be_false + end + end + + describe ExampleSuite, "#run on dry run" do + it_should_behave_like "Spec::Example::ExampleSuite#run" + + before do + @options.dry_run = true + end + + it "should not run before(:all) or after(:all)" do + before_all_ran = false + after_all_ran = false + ExampleGroup.before(:all) { before_all_ran = true } + ExampleGroup.after(:all) { after_all_ran = true } + @behaviour.it("should") {} + suite = @behaviour.suite + suite.run + before_all_ran.should be_false + after_all_ran.should be_false + end + + it "should not run example" do + example_ran = false + @behaviour.it("should") {example_ran = true} + suite = @behaviour.suite + suite.run + example_ran.should be_false + end + end + + describe ExampleSuite, "#run with success" do + it_should_behave_like "Spec::Example::ExampleSuite#run without failure in example" + + before do + @special_behaviour = Class.new(ExampleGroup) + ExampleGroupFactory.register(:special, @special_behaviour) + @not_special_behaviour = Class.new(ExampleGroup) + ExampleGroupFactory.register(:not_special, @not_special_behaviour) + end + + after do + ExampleGroupFactory.reset + end + + it "should send reporter add_example_group" do + suite = @behaviour.suite + suite.run + @reporter.added_behaviour.should == "example" + end + + it "should run example on run" do + example_ran = false + @behaviour.it("should") {example_ran = true} + suite = @behaviour.suite + suite.run + example_ran.should be_true + end + + it "should run before(:all) block only once" do + before_all_run_count_run_count = 0 + @behaviour.before(:all) {before_all_run_count_run_count += 1} + @behaviour.it("test") {true} + @behaviour.it("test2") {true} + suite = @behaviour.suite + suite.run + before_all_run_count_run_count.should == 1 + end + + it "should run after(:all) block only once" do + after_all_run_count = 0 + @behaviour.after(:all) {after_all_run_count += 1} + @behaviour.it("test") {true} + @behaviour.it("test2") {true} + suite = @behaviour.suite + suite.run + after_all_run_count.should == 1 + @reporter.rspec_verify + end + + it "after(:all) should have access to all instance variables defined in before(:all)" do + context_instance_value_in = "Hello there" + context_instance_value_out = "" + @behaviour.before(:all) { @instance_var = context_instance_value_in } + @behaviour.after(:all) { context_instance_value_out = @instance_var } + @behaviour.it("test") {true} + suite = @behaviour.suite + suite.run + context_instance_value_in.should == context_instance_value_out + end + + it "should copy instance variables from before(:all)'s execution context into spec's execution context" do + context_instance_value_in = "Hello there" + context_instance_value_out = "" + @behaviour.before(:all) { @instance_var = context_instance_value_in } + @behaviour.it("test") {context_instance_value_out = @instance_var} + suite = @behaviour.suite + suite.run + context_instance_value_in.should == context_instance_value_out + end + + it "should not add global before callbacks for untargetted behaviours" do + fiddle = [] + + ExampleGroup.before(:all) { fiddle << "Example.before(:all)" } + ExampleGroup.prepend_before(:all) { fiddle << "Example.prepend_before(:all)" } + @special_behaviour.before(:each) { fiddle << "Example.before(:each, :behaviour_type => :special)" } + @special_behaviour.prepend_before(:each) { fiddle << "Example.prepend_before(:each, :behaviour_type => :special)" } + @special_behaviour.before(:all) { fiddle << "Example.before(:all, :behaviour_type => :special)" } + @special_behaviour.prepend_before(:all) { fiddle << "Example.prepend_before(:all, :behaviour_type => :special)" } + + behaviour = Class.new(ExampleGroup) do + describe("I'm not special", :behaviour_type => :not_special) + it "does nothing" + end + suite = behaviour.suite + suite.run + fiddle.should == [ + 'Example.prepend_before(:all)', + 'Example.before(:all)', + ] + end + + it "should add global before callbacks for targetted behaviours" do + fiddle = [] + + ExampleGroup.before(:all) { fiddle << "Example.before(:all)" } + ExampleGroup.prepend_before(:all) { fiddle << "Example.prepend_before(:all)" } + @special_behaviour.before(:each) { fiddle << "special.before(:each, :behaviour_type => :special)" } + @special_behaviour.prepend_before(:each) { fiddle << "special.prepend_before(:each, :behaviour_type => :special)" } + @special_behaviour.before(:all) { fiddle << "special.before(:all, :behaviour_type => :special)" } + @special_behaviour.prepend_before(:all) { fiddle << "special.prepend_before(:all, :behaviour_type => :special)" } + @special_behaviour.append_before(:each) { fiddle << "special.append_before(:each, :behaviour_type => :special)" } + + behaviour = Class.new(@special_behaviour).describe("I'm a special behaviour") {} + behaviour.it("test") {true} + suite = behaviour.suite + suite.run + fiddle.should == [ + 'Example.prepend_before(:all)', + 'Example.before(:all)', + 'special.prepend_before(:all, :behaviour_type => :special)', + 'special.before(:all, :behaviour_type => :special)', + 'special.prepend_before(:each, :behaviour_type => :special)', + 'special.before(:each, :behaviour_type => :special)', + 'special.append_before(:each, :behaviour_type => :special)', + ] + end + + it "should order before callbacks from global to local" do + fiddle = [] + ExampleGroup.prepend_before(:all) { fiddle << "Example.prepend_before(:all)" } + ExampleGroup.before(:all) { fiddle << "Example.before(:all)" } + @behaviour.prepend_before(:all) { fiddle << "prepend_before(:all)" } + @behaviour.before(:all) { fiddle << "before(:all)" } + @behaviour.prepend_before(:each) { fiddle << "prepend_before(:each)" } + @behaviour.before(:each) { fiddle << "before(:each)" } + suite = @behaviour.suite + suite.run + fiddle.should == [ + 'Example.prepend_before(:all)', + 'Example.before(:all)', + 'prepend_before(:all)', + 'before(:all)', + 'prepend_before(:each)', + 'before(:each)' + ] + end + + it "should order after callbacks from local to global" do + @reporter.should_receive(:add_example_group).with any_args() + @reporter.should_receive(:example_finished).with any_args() + + fiddle = [] + @behaviour.after(:each) { fiddle << "after(:each)" } + @behaviour.append_after(:each) { fiddle << "append_after(:each)" } + @behaviour.after(:all) { fiddle << "after(:all)" } + @behaviour.append_after(:all) { fiddle << "append_after(:all)" } + ExampleGroup.after(:all) { fiddle << "Example.after(:all)" } + ExampleGroup.append_after(:all) { fiddle << "Example.append_after(:all)" } + suite = @behaviour.suite + suite.run + fiddle.should == [ + 'after(:each)', + 'append_after(:each)', + 'after(:all)', + 'append_after(:all)', + 'Example.after(:all)', + 'Example.append_after(:all)' + ] + end + + it "should have accessible instance methods from included module" do + @reporter.should_receive(:add_example_group).with any_args() + @reporter.should_receive(:example_finished).with any_args() + + mod1_method_called = false + mod1 = Module.new do + define_method :mod1_method do + mod1_method_called = true + end + end + + mod2_method_called = false + mod2 = Module.new do + define_method :mod2_method do + mod2_method_called = true + end + end + + @behaviour.include mod1, mod2 + + @behaviour.it("test") do + mod1_method + mod2_method + end + suite = @behaviour.suite + suite.run + mod1_method_called.should be_true + mod2_method_called.should be_true + end + + it "should include targetted modules included using configuration" do + mod1 = Module.new + mod2 = Module.new + mod3 = Module.new + Spec::Runner.configuration.include(mod1, mod2) + Spec::Runner.configuration.include(mod3, :behaviour_type => :not_special) + + behaviour = Class.new(@special_behaviour).describe("I'm special", :behaviour_type => :special) do + it "does nothing" + end + suite = behaviour.suite + suite.run + + behaviour.included_modules.should include(mod1) + behaviour.included_modules.should include(mod2) + behaviour.included_modules.should_not include(mod3) + end + + it "should include any predicate_matchers included using configuration" do + $included_predicate_matcher_found = false + Spec::Runner.configuration.predicate_matchers[:do_something] = :does_something? + behaviour = Class.new(ExampleGroup) do + describe('example') + it "should respond to do_something" do + $included_predicate_matcher_found = respond_to?(:do_something) + end + end + suite = behaviour.suite + suite.run + $included_predicate_matcher_found.should be(true) + end + + it "should use a mock framework set up in config" do + mod = Module.new do + class << self + def included(mod) + $included_module = mod + end + end + end + + begin + $included_module = nil + Spec::Runner.configuration.mock_with mod + + behaviour = Class.new(ExampleGroup) do + describe('example') + it "does nothing" + end + suite = behaviour.suite + suite.run + + $included_module.should_not be_nil + ensure + Spec::Runner.configuration.mock_with :rspec + end + end + end + + describe ExampleSuite, "#run with pending example that has a failing assertion" do + it_should_behave_like "Spec::Example::ExampleSuite#run without failure in example" + + before do + @behaviour.it("should be pending") do + pending("Example fails") {false.should be_true} + end + end + + it "should send example_pending to formatter" do + @formatter.should_receive(:example_pending).with("example", "should be pending", "Example fails") + suite = @behaviour.suite + suite.run + end + end + + describe ExampleSuite, "#run with pending example that does not have a failing assertion" do + it_should_behave_like "Spec::Example::ExampleSuite#run with failure in example" + + before do + @behaviour.it("should be pending") do + pending("Example passes") {true.should be_true} + end + end + + it "should send example_pending to formatter" do + @formatter.should_receive(:example_pending).with("example", "should be pending", "Example passes") + suite = @behaviour.suite + suite.run + end + end + + describe ExampleSuite, "#run when before(:all) fails" do + it_should_behave_like "Spec::Example::ExampleSuite#run" + + before do + ExampleGroup.before(:all) { raise NonStandardError, "before(:all) failure" } + end + + it "should not run any example" do + spec_ran = false + @behaviour.it("test") {spec_ran = true} + suite = @behaviour.suite + suite.run + spec_ran.should be_false + end + + it "should run ExampleGroup after(:all)" do + after_all_ran = false + ExampleGroup.after(:all) { after_all_ran = true } + suite = @behaviour.suite + suite.run + after_all_ran.should be_true + end + + it "should run behaviour after(:all)" do + after_all_ran = false + @behaviour.after(:all) { after_all_ran = true } + suite = @behaviour.suite + suite.run + after_all_ran.should be_true + end + + it "should supply before(:all) as description" do + @reporter.should_receive(:example_finished) do |example, error, location| + example.description.should eql("before(:all)") + error.message.should eql("before(:all) failure") + location.should eql("before(:all)") + end + + @behaviour.it("test") {true} + suite = @behaviour.suite + suite.run + end + end + + describe ExampleSuite, "#run when before(:each) fails" do + it_should_behave_like "Spec::Example::ExampleSuite#run with failure in example" + + before do + ExampleGroup.before(:each) { raise NonStandardError } + end + + it "should run after(:all)" do + after_all_ran = false + ExampleGroup.after(:all) { after_all_ran = true } + suite = @behaviour.suite + suite.run + after_all_ran.should be_true + end + end + + describe ExampleSuite, "#run when any example fails" do + it_should_behave_like "Spec::Example::ExampleSuite#run with failure in example" + + before do + @behaviour.it("should") { raise NonStandardError } + end + + it "should run after(:all)" do + after_all_ran = false + ExampleGroup.after(:all) { after_all_ran = true } + suite = @behaviour.suite + suite.run + after_all_ran.should be_true + end + end + + describe ExampleSuite, "#run when first after(:each) block fails" do + it_should_behave_like "Spec::Example::ExampleSuite#run" + + it "should add an example failure to the TestResult" do + second_after_ran = false + @behaviour.after(:each) do + second_after_ran = true + end + first_after_ran = false + @behaviour.after(:each) do + first_after_ran = true + raise "first" + end + + suite = @behaviour.suite + suite.run.should be_false + end + + it "should run second after(:each) block" do + second_after_ran = false + @behaviour.after(:each) do + second_after_ran = true + end + first_after_ran = false + @behaviour.after(:each) do + first_after_ran = true + raise "first" + end + + @reporter.should_receive(:example_finished) do |example, error, location| + example.should equal(example) + error.message.should eql("first") + location.should eql("after(:each)") + end + suite = @behaviour.suite + suite.run + first_after_ran.should be_true + second_after_ran.should be_true + end + end + + describe ExampleSuite, "#run when first before(:each) block fails" do + it_should_behave_like "Spec::Example::ExampleSuite#run" + + it "should add an example failure to the TestResult" do + first_before_ran = false + @behaviour.before(:each) do + first_before_ran = true + raise "first" + end + second_before_ran = false + @behaviour.before(:each) do + second_before_ran = true + end + + suite = @behaviour.suite + suite.run.should be_false + end + + it "should not run second before(:each)" do + first_before_ran = false + @behaviour.before(:each) do + first_before_ran = true + raise "first" + end + second_before_ran = false + @behaviour.before(:each) do + second_before_ran = true + end + + @reporter.should_receive(:example_finished) do |name, error, location, example_not_implemented| + name.should eql("example") + error.message.should eql("first") + location.should eql("before(:each)") + example_not_implemented.should be_false + end + suite = @behaviour.suite + suite.run + first_before_ran.should be_true + second_before_ran.should be_false + end + end + + describe ExampleSuite, "#run when failure in after(:all)" do + it_should_behave_like "Spec::Example::ExampleSuite#run" + + before do + ExampleGroup.after(:all) { raise NonStandardError, "in after(:all)" } + end + + it "should return false" do + suite = @behaviour.suite + suite.run.should be_false + end + + it "should provide after(:all) as description" do + @reporter.should_receive(:example_finished) do |example, error, location| + example.description.should eql("after(:all)") + error.message.should eql("in after(:all)") + location.should eql("after(:all)") + end + + suite = @behaviour.suite + suite.run + end + end + + describe ExampleSuite, "#size" do + it "returns the number of examples in the behaviour" do + behaviour = Class.new(ExampleGroup) do + describe("Some Examples") + it("does something") {} + it("does something else") {} + end + suite = behaviour.suite + suite.size.should == 2 + end + end + + describe ExampleSuite, "#empty?" do + it "when there are examples; returns true" do + behaviour = Class.new(ExampleGroup) do + describe("Some Examples") + it("does something") {} + end + suite = behaviour.suite + suite.size.should be > 0 + + suite.should_not be_empty + end + + it "when there are no examples; returns true" do + behaviour = Class.new(ExampleGroup) do + describe("Some Examples") + end + suite = behaviour.suite + suite.size.should == 0 + + suite.should be_empty + end + end + + describe ExampleSuite, "#delete" do + it "removes the passed in example" do + behaviour = Class.new(ExampleGroup) do + describe("Some Examples") + it("does something") {} + end + suite = behaviour.suite + suite.delete(suite.examples.first) + + suite.should be_empty + end + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/example/nested_example_group_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/example/nested_example_group_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/example/nested_example_group_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/example/nested_example_group_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,59 @@ +require File.dirname(__FILE__) + '/../../spec_helper' + +module Spec + module Example + describe 'Nested Example Groups' do + parent = self + + def count + @count ||= 0 + @count = @count + 1 + @count + end + + before(:all) do + count.should == 1 + end + + before(:all) do + count.should == 2 + end + + before(:each) do + count.should == 3 + end + + before(:each) do + count.should == 4 + end + + it "should run before(:all), before(:each), example, after(:each), after(:all) in order" do + count.should == 5 + end + + after(:each) do + count.should == 7 + end + + after(:each) do + count.should == 6 + end + + after(:all) do + count.should == 9 + end + + after(:all) do + count.should == 8 + end + + describe 'nested example group' do + self.superclass.should == parent + + it "should run all before and after callbacks" do + count.should == 5 + end + end + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/example/pending_module_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/example/pending_module_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/example/pending_module_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/example/pending_module_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,31 @@ +module Spec + module Example + describe Pending do + + it 'should raise an ExamplePendingError if no block is supplied' do + lambda { + include Pending + pending "TODO" + }.should raise_error(ExamplePendingError, /TODO/) + end + + it 'should raise an ExamplePendingError if a supplied block fails as expected' do + lambda { + include Pending + pending "TODO" do + raise "oops" + end + }.should raise_error(ExamplePendingError, /TODO/) + end + + it 'should raise a PendingExampleFixedError if a supplied block starts working' do + lambda { + include Pending + pending "TODO" do + # success! + end + }.should raise_error(PendingExampleFixedError, /TODO/) + end + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/example/predicate_matcher_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/example/predicate_matcher_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/example/predicate_matcher_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/example/predicate_matcher_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,21 @@ +require File.dirname(__FILE__) + '/../../spec_helper' + +module Spec + module Example + class Fish + def can_swim?(distance_in_yards) + distance_in_yards < 1000 + end + end + + describe "predicate_matcher[method_on_object] = matcher_method" do + predicate_matchers[:swim] = :can_swim? + it "should match matcher_method if method_on_object returns true" do + swim(100).matches?(Fish.new).should be_true + end + it "should not match matcher_method if method_on_object returns false" do + swim(10000).matches?(Fish.new).should be_false + end + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/example/shared_example_group_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/example/shared_example_group_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/example/shared_example_group_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/example/shared_example_group_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,272 @@ +require File.dirname(__FILE__) + '/../../spec_helper' + +module Spec + module Example + describe ExampleGroup, "with :shared => true" do + before(:each) do + @options = ::Spec::Runner::Options.new(StringIO.new, StringIO.new) + @original_rspec_options = $rspec_options + $rspec_options = @options + @formatter = Spec::Mocks::Mock.new("formatter", :null_object => true) + @options.formatters << @formatter + @behaviour = Class.new(ExampleGroup).describe("behaviour") + class << @behaviour + public :include + end + end + + after(:each) do + $rspec_options = @original_rspec_options + @formatter.rspec_verify + @behaviour = nil + $shared_example_groups.clear unless $shared_example_groups.nil? + end + + def make_shared_example_group(name, opts=nil, &block) + behaviour = SharedExampleGroup.new(name, :shared => true, &block) + SharedExampleGroup.add_shared_example_group(behaviour) + behaviour + end + + def non_shared_example_group() + @non_shared_example_group ||= Class.new(ExampleGroup).describe("behaviour") + end + + it "should accept an optional options hash" do + lambda { Class.new(ExampleGroup).describe("context") }.should_not raise_error(Exception) + lambda { Class.new(ExampleGroup).describe("context", :shared => true) }.should_not raise_error(Exception) + end + + it "should return all shared behaviours" do + b1 = make_shared_example_group("b1", :shared => true) {} + b2 = make_shared_example_group("b2", :shared => true) {} + + b1.should_not be(nil) + b2.should_not be(nil) + + SharedExampleGroup.find_shared_example_group("b1").should equal(b1) + SharedExampleGroup.find_shared_example_group("b2").should equal(b2) + end + + it "should register as shared behaviour" do + behaviour = make_shared_example_group("behaviour") {} + SharedExampleGroup.shared_example_groups.should include(behaviour) + end + + it "should not be shared when not configured as shared" do + behaviour = non_shared_example_group + SharedExampleGroup.shared_example_groups.should_not include(behaviour) + end + + it "should raise if run when shared" do + behaviour = make_shared_example_group("context") {} + $example_ran = false + behaviour.it("test") {$example_ran = true} + lambda { behaviour.run(@formatter) }.should raise_error + $example_ran.should be_false + end + + it "should contain examples when shared" do + shared_example_group = make_shared_example_group("shared behaviour") {} + shared_example_group.it("shared example") {} + shared_example_group.number_of_examples.should == 1 + end + + it "should complain when adding a second shared behaviour with the same description" do + describe "shared behaviour", :shared => true do + end + lambda do + describe "shared behaviour", :shared => true do + end + end.should raise_error(ArgumentError) + end + + it "should NOT complain when adding the same shared behaviour instance again" do + shared_example_group = Class.new(ExampleGroup).describe("shared behaviour", :shared => true) + SharedExampleGroup.add_shared_example_group(shared_example_group) + SharedExampleGroup.add_shared_example_group(shared_example_group) + end + + it "should NOT complain when adding the same shared behaviour again (i.e. file gets reloaded)" do + lambda do + 2.times do + describe "shared behaviour which gets loaded twice", :shared => true do + end + end + end.should_not raise_error(ArgumentError) + end + + it "should NOT complain when adding the same shared behaviour in same file with different absolute path" do + shared_example_group_1 = Class.new(ExampleGroup).describe("shared behaviour", :shared => true) + shared_example_group_2 = Class.new(ExampleGroup).describe("shared behaviour", :shared => true) + + shared_example_group_1.description[:spec_path] = "/my/spec/a/../shared.rb" + shared_example_group_2.description[:spec_path] = "/my/spec/b/../shared.rb" + + SharedExampleGroup.add_shared_example_group(shared_example_group_1) + SharedExampleGroup.add_shared_example_group(shared_example_group_2) + end + + it "should complain when adding a different shared behaviour with the same name in a different file with the same basename" do + shared_example_group_1 = Class.new(ExampleGroup).describe("shared behaviour", :shared => true) + shared_example_group_2 = Class.new(ExampleGroup).describe("shared behaviour", :shared => true) + + shared_example_group_1.description[:spec_path] = "/my/spec/a/shared.rb" + shared_example_group_2.description[:spec_path] = "/my/spec/b/shared.rb" + + SharedExampleGroup.add_shared_example_group(shared_example_group_1) + lambda do + SharedExampleGroup.add_shared_example_group(shared_example_group_2) + end.should raise_error(ArgumentError, /already exists/) + end + + it "should add examples to current behaviour using it_should_behave_like" do + shared_example_group = make_shared_example_group("shared behaviour") {} + shared_example_group.it("shared example") {} + shared_example_group.it("shared example 2") {} + + @behaviour.it("example") {} + @behaviour.number_of_examples.should == 1 + @behaviour.it_should_behave_like("shared behaviour") + @behaviour.number_of_examples.should == 3 + end + + it "should add examples to current behaviour using include" do + shared_example_group = describe "all things", :shared => true do + it "should do stuff" do end + end + + behaviour = describe "one thing" do + include shared_example_group + end + + behaviour.number_of_examples.should == 1 + end + + it "should add examples to current behaviour using it_should_behave_like with a module" do + AllThings = describe "all things", :shared => true do + it "should do stuff" do end + end + + behaviour = describe "one thing" do + it_should_behave_like AllThings + end + + behaviour.number_of_examples.should == 1 + end + + it "should run shared examples" do + shared_example_ran = false + shared_example_group = make_shared_example_group("shared behaviour") {} + shared_example_group.it("shared example") { shared_example_ran = true } + + example_ran = false + + @behaviour.it_should_behave_like("shared behaviour") + @behaviour.it("example") {example_ran = true} + suite = @behaviour.suite + suite.run + example_ran.should be_true + shared_example_ran.should be_true + end + + it "should run setup and teardown from shared behaviour" do + shared_setup_ran = false + shared_teardown_ran = false + shared_example_group = make_shared_example_group("shared behaviour") {} + shared_example_group.before { shared_setup_ran = true } + shared_example_group.after { shared_teardown_ran = true } + shared_example_group.it("shared example") { shared_example_ran = true } + + example_ran = false + + @behaviour.it_should_behave_like("shared behaviour") + @behaviour.it("example") {example_ran = true} + suite = @behaviour.suite + suite.run + example_ran.should be_true + shared_setup_ran.should be_true + shared_teardown_ran.should be_true + end + + it "should run before(:all) and after(:all) only once from shared behaviour" do + shared_before_all_run_count = 0 + shared_after_all_run_count = 0 + shared_example_group = make_shared_example_group("shared behaviour") {} + shared_example_group.before(:all) { shared_before_all_run_count += 1} + shared_example_group.after(:all) { shared_after_all_run_count += 1} + shared_example_group.it("shared example") { shared_example_ran = true } + + example_ran = false + + @behaviour.it_should_behave_like("shared behaviour") + @behaviour.it("example") {example_ran = true} + suite = @behaviour.suite + suite.run + example_ran.should be_true + shared_before_all_run_count.should == 1 + shared_after_all_run_count.should == 1 + end + + it "should include modules, included into shared behaviour, into current behaviour" do + @formatter.should_receive(:add_example_group).with(any_args) + @formatter.should_receive(:example_finished).twice.with(any_args) + + shared_example_group = make_shared_example_group("shared behaviour") {} + shared_example_group.it("shared example") { shared_example_ran = true } + + mod1_method_called = false + mod1 = Module.new do + define_method :mod1_method do + mod1_method_called = true + end + end + + mod2_method_called = false + mod2 = Module.new do + define_method :mod2_method do + mod2_method_called = true + end + end + + shared_example_group.include mod2 + + @behaviour.it_should_behave_like("shared behaviour") + @behaviour.include mod1 + + @behaviour.it("test") do + mod1_method + mod2_method + end + suite = @behaviour.suite + suite.run + mod1_method_called.should be_true + mod2_method_called.should be_true + end + + it "should make methods defined in the shared behaviour available in consuming behaviour" do + shared_example_group = make_shared_example_group("shared behaviour xyz") do + def a_shared_helper_method + "this got defined in a shared behaviour" + end + end + @behaviour.it_should_behave_like("shared behaviour xyz") + success = false + @behaviour.it("should access a_shared_helper_method") do + a_shared_helper_method + success = true + end + suite = @behaviour.suite + suite.run + success.should be_true + end + + it "should raise when named shared behaviour can not be found" do + lambda { + @behaviour.it_should_behave_like("non-existent shared example group") + violated + }.should raise_error("Shared Example Group 'non-existent shared example group' can not be found") + end + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/expectations/differs/default_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/expectations/differs/default_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/expectations/differs/default_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/expectations/differs/default_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,109 @@ +require File.dirname(__FILE__) + '/../../../spec_helper.rb' + +module Spec + module Fixtures + class Animal + def initialize(name,species) + @name,@species = name,species + end + + def inspect + <<-EOA + + EOA + end + end + end +end + +describe "Diff" do + before(:each) do + @options = ::Spec::Runner::Options.new(StringIO.new, StringIO.new) + @differ = Spec::Expectations::Differs::Default.new(@options) + end + + it "should output unified diff of two strings" do + expected="foo\nbar\nzap\nthis\nis\nsoo\nvery\nvery\nequal\ninsert\na\nline\n" + actual="foo\nzap\nbar\nthis\nis\nsoo\nvery\nvery\nequal\ninsert\na\nanother\nline\n" + expected_diff="\n\n@@ -1,6 +1,6 @@\n foo\n-bar\n zap\n+bar\n this\n is\n soo\n@@ -9,5 +9,6 @@\n equal\n insert\n a\n+another\n line\n" + diff = @differ.diff_as_string(expected, actual) + diff.should eql(expected_diff) + end + + it "should output unified diff message of two arrays" do + expected = [ :foo, 'bar', :baz, 'quux', :metasyntactic, 'variable', :delta, 'charlie', :width, 'quite wide' ] + actual = [ :foo, 'bar', :baz, 'quux', :metasyntactic, 'variable', :delta, 'tango' , :width, 'very wide' ] + + expected_diff = <<'EOD' + + +@@ -5,7 +5,7 @@ + :metasyntactic, + "variable", + :delta, +- "charlie", ++ "tango", + :width, +- "quite wide"] ++ "very wide"] +EOD + + + diff = @differ.diff_as_object(expected,actual) + diff.should == expected_diff + end + + it "should output unified diff message of two objects" do + expected = Spec::Fixtures::Animal.new "bob", "giraffe" + actual = Spec::Fixtures::Animal.new "bob", "tortoise" + + expected_diff = <<'EOD' + +@@ -1,5 +1,5 @@ + +EOD + + diff = @differ.diff_as_object(expected,actual) + diff.should == expected_diff + end + +end + + +describe "Diff in context format" do + before(:each) do + @options = Spec::Runner::Options.new(StringIO.new, StringIO.new) + @options.diff_format = :context + @differ = Spec::Expectations::Differs::Default.new(@options) + end + + it "should output unified diff message of two objects" do + expected = Spec::Fixtures::Animal.new "bob", "giraffe" + actual = Spec::Fixtures::Animal.new "bob", "tortoise" + + expected_diff = <<'EOD' + +*************** +*** 1,5 **** + +--- 1,5 ---- + +EOD + + diff = @differ.diff_as_object(expected,actual) + diff.should == expected_diff + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/expectations/extensions/object_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/expectations/extensions/object_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/expectations/extensions/object_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/expectations/extensions/object_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,107 @@ +require File.dirname(__FILE__) + '/../../../spec_helper.rb' + +describe Object, "#should" do + before(:each) do + @target = "target" + @matcher = mock("matcher") + @matcher.stub!(:matches?).and_return(true) + @matcher.stub!(:failure_message) + end + + it "should accept and interact with a matcher" do + @matcher.should_receive(:matches?).with(@target).and_return(true) + @target.should @matcher + end + + it "should ask for a failure_message when matches? returns false" do + @matcher.should_receive(:matches?).with(@target).and_return(false) + @matcher.should_receive(:failure_message).and_return("the failure message") + lambda { + @target.should @matcher + }.should fail_with("the failure message") + end + + it "should raise error if it receives false directly" do + lambda { + @target.should false + }.should raise_error(Spec::Expectations::InvalidMatcherError) + end + + it "should raise error if it receives false (evaluated)" do + lambda { + @target.should eql?("foo") + }.should raise_error(Spec::Expectations::InvalidMatcherError) + end + + it "should raise error if it receives true" do + lambda { + @target.should true + }.should raise_error(Spec::Expectations::InvalidMatcherError) + end + + it "should raise error if it receives nil" do + lambda { + @target.should nil + }.should raise_error(Spec::Expectations::InvalidMatcherError) + end + + it "should raise error if it receives no argument and it is not used as a left side of an operator" do + pending "Is it even possible to catch this?" + lambda { + @target.should + }.should raise_error(Spec::Expectations::InvalidMatcherError) + end +end + +describe Object, "#should_not" do + before(:each) do + @target = "target" + @matcher = mock("matcher") + end + + it "should accept and interact with a matcher" do + @matcher.should_receive(:matches?).with(@target).and_return(false) + @matcher.stub!(:negative_failure_message) + + @target.should_not @matcher + end + + it "should ask for a negative_failure_message when matches? returns true" do + @matcher.should_receive(:matches?).with(@target).and_return(true) + @matcher.should_receive(:negative_failure_message).and_return("the negative failure message") + lambda { + @target.should_not @matcher + }.should fail_with("the negative failure message") + end + + it "should raise error if it receives false directly" do + lambda { + @target.should_not false + }.should raise_error(Spec::Expectations::InvalidMatcherError) + end + + it "should raise error if it receives false (evaluated)" do + lambda { + @target.should_not eql?("foo") + }.should raise_error(Spec::Expectations::InvalidMatcherError) + end + + it "should raise error if it receives true" do + lambda { + @target.should_not true + }.should raise_error(Spec::Expectations::InvalidMatcherError) + end + + it "should raise error if it receives nil" do + lambda { + @target.should_not nil + }.should raise_error(Spec::Expectations::InvalidMatcherError) + end + + it "should raise error if it receives no argument and it is not used as a left side of an operator" do + pending "Is it even possible to catch this?" + lambda { + @target.should_not + }.should raise_error(Spec::Expectations::InvalidMatcherError) + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/expectations/fail_with_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/expectations/fail_with_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/expectations/fail_with_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/expectations/fail_with_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,71 @@ +require File.dirname(__FILE__) + '/../../spec_helper.rb' + +describe Spec::Expectations, "#fail_with with no diff" do + before(:each) do + @old_differ = Spec::Expectations.differ + Spec::Expectations.differ = nil + end + + it "should handle just a message" do + lambda { + Spec::Expectations.fail_with "the message" + }.should fail_with("the message") + end + + it "should handle an Array" do + lambda { + Spec::Expectations.fail_with ["the message","expected","actual"] + }.should fail_with("the message") + end + + after(:each) do + Spec::Expectations.differ = @old_differ + end +end + +describe Spec::Expectations, "#fail_with with diff" do + before(:each) do + @old_differ = Spec::Expectations.differ + @differ = mock("differ") + Spec::Expectations.differ = @differ + end + + it "should not call differ if no expected/actual" do + lambda { + Spec::Expectations.fail_with "the message" + }.should fail_with("the message") + end + + it "should call differ if expected/actual are presented separately" do + @differ.should_receive(:diff_as_string).and_return("diff") + lambda { + Spec::Expectations.fail_with "the message", "expected", "actual" + }.should fail_with("the message\nDiff:diff") + end + + it "should call differ if expected/actual are not strings" do + @differ.should_receive(:diff_as_object).and_return("diff") + lambda { + Spec::Expectations.fail_with "the message", :expected, :actual + }.should fail_with("the message\nDiff:diff") + end + + it "should not call differ if expected or actual are procs" do + @differ.should_not_receive(:diff_as_string) + @differ.should_not_receive(:diff_as_object) + lambda { + Spec::Expectations.fail_with "the message", lambda {}, lambda {} + }.should fail_with("the message") + end + + it "should call differ if expected/actual are presented in an Array with message" do + @differ.should_receive(:diff_as_string).with("actual","expected").and_return("diff") + lambda { + Spec::Expectations.fail_with(["the message", "expected", "actual"]) + }.should fail_with(/the message\nDiff:diff/) + end + + after(:each) do + Spec::Expectations.differ = @old_differ + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/extensions/main_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/extensions/main_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/extensions/main_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/extensions/main_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,48 @@ +require File.dirname(__FILE__) + '/../../spec_helper.rb' + +module Spec + module Extensions + describe Main do + before(:each) do + @main = Class.new do; include Main; end + @original_rspec_options, $rspec_options = $rspec_options, nil + end + + after(:each) do + $rspec_options = @original_rspec_options + $rspec_story_steps = @original_rspec_story_steps + end + + it "should create an Options object" do + @main.send(:rspec_options).should be_instance_of(Spec::Runner::Options) + @main.send(:rspec_options).should === $rspec_options + end + + specify {@main.should respond_to(:describe)} + specify {@main.should respond_to(:context)} + + it "should raise when no block given to describe" do + lambda { @main.describe "foo" }.should raise_error(ArgumentError) + end + + it "should raise when no description given to describe" do + lambda { @main.describe do; end }.should raise_error(ArgumentError) + end + + it "should registered ExampleGroups by default" do + example_group = @main.describe("The ExampleGroup") do + end + + rspec_options.example_groups.should include(example_group) + end + + it "should not run unregistered ExampleGroups" do + example_group = @main.describe("The ExampleGroup") do + unregister + end + + rspec_options.example_groups.should_not include(example_group) + end + end + end +end \ No newline at end of file diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/matchers/be_close_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/matchers/be_close_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/matchers/be_close_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/matchers/be_close_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,39 @@ +require File.dirname(__FILE__) + '/../../spec_helper.rb' +module Spec + module Matchers + describe BeClose do + it "should match when value == target" do + BeClose.new(5.0, 0.5).matches?(5.0).should be_true + end + it "should match when value < (target + delta)" do + BeClose.new(5.0, 0.5).matches?(5.49).should be_true + end + it "should match when value > (target - delta)" do + BeClose.new(5.0, 0.5).matches?(4.51).should be_true + end + it "should not match when value == (target - delta)" do + BeClose.new(5.0, 0.5).matches?(4.5).should be_false + end + it "should not match when value < (target - delta)" do + BeClose.new(5.0, 0.5).matches?(4.49).should be_false + end + it "should not match when value == (target + delta)" do + BeClose.new(5.0, 0.5).matches?(5.5).should be_false + end + it "should not match when value > (target + delta)" do + BeClose.new(5.0, 0.5).matches?(5.51).should be_false + end + it "should provide a useful failure message" do + #given + matcher = BeClose.new(5.0, 0.5) + #when + matcher.matches?(5.51) + #then + matcher.failure_message.should == "expected 5.0 +/- (< 0.5), got 5.51" + end + it "should describe itself" do + BeClose.new(5.0, 0.5).description.should == "be close to 5.0 (within +- 0.5)" + end + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/matchers/be_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/matchers/be_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/matchers/be_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/matchers/be_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,209 @@ +require File.dirname(__FILE__) + '/../../spec_helper.rb' + +describe "should be_predicate" do + it "should pass when actual returns true for :predicate?" do + actual = stub("actual", :happy? => true) + actual.should be_happy + end + + it "should pass when actual returns true for :predicates? (present tense)" do + actual = stub("actual", :exists? => true) + actual.should be_exist + end + + it "should fail when actual returns false for :predicate?" do + actual = stub("actual", :happy? => false) + lambda { + actual.should be_happy + }.should fail_with("expected happy? to return true, got false") + end + + it "should fail when actual does not respond to :predicate?" do + lambda { + Object.new.should be_happy + }.should raise_error(NameError) + end +end + +describe "should_not be_predicate" do + it "should pass when actual returns false for :sym?" do + actual = stub("actual", :happy? => false) + actual.should_not be_happy + end + + it "should fail when actual returns true for :sym?" do + actual = stub("actual", :happy? => true) + lambda { + actual.should_not be_happy + }.should fail_with("expected happy? to return false, got true") + end + + it "should fail when actual does not respond to :sym?" do + lambda { + Object.new.should_not be_happy + }.should raise_error(NameError) + end +end + +describe "should be_predicate(*args)" do + it "should pass when actual returns true for :predicate?(*args)" do + actual = mock("actual") + actual.should_receive(:older_than?).with(3).and_return(true) + actual.should be_older_than(3) + end + + it "should fail when actual returns false for :predicate?(*args)" do + actual = mock("actual") + actual.should_receive(:older_than?).with(3).and_return(false) + lambda { + actual.should be_older_than(3) + }.should fail_with("expected older_than?(3) to return true, got false") + end + + it "should fail when actual does not respond to :predicate?" do + lambda { + Object.new.should be_older_than(3) + }.should raise_error(NameError) + end +end + +describe "should_not be_predicate(*args)" do + it "should pass when actual returns false for :predicate?(*args)" do + actual = mock("actual") + actual.should_receive(:older_than?).with(3).and_return(false) + actual.should_not be_older_than(3) + end + + it "should fail when actual returns true for :predicate?(*args)" do + actual = mock("actual") + actual.should_receive(:older_than?).with(3).and_return(true) + lambda { + actual.should_not be_older_than(3) + }.should fail_with("expected older_than?(3) to return false, got true") + end + + it "should fail when actual does not respond to :predicate?" do + lambda { + Object.new.should_not be_older_than(3) + }.should raise_error(NameError) + end +end + +describe "should be_true" do + it "should pass when actual equal(true)" do + true.should be_true + end + + it "should fail when actual equal(false)" do + lambda { + false.should be_true + }.should fail_with("expected true, got false") + end +end + +describe "should be_false" do + it "should pass when actual equal(false)" do + false.should be_false + end + + it "should fail when actual equal(true)" do + lambda { + true.should be_false + }.should fail_with("expected false, got true") + end +end + +describe "should be_nil" do + it "should pass when actual is nil" do + nil.should be_nil + end + + it "should fail when actual is not nil" do + lambda { + :not_nil.should be_nil + }.should fail_with("expected nil, got :not_nil") + end +end + +describe "should_not be_nil" do + it "should pass when actual is not nil" do + :not_nil.should_not be_nil + end + + it "should fail when actual is nil" do + lambda { + nil.should_not be_nil + }.should fail_with("expected not nil, got nil") + end +end + +describe "should be <" do + it "should pass when < operator returns true" do + 3.should be < 4 + end + + it "should fail when < operator returns false" do + lambda { 3.should be < 3 }.should fail_with("expected < 3, got 3") + end +end + +describe "should be <=" do + it "should pass when <= operator returns true" do + 3.should be <= 4 + 4.should be <= 4 + end + + it "should fail when <= operator returns false" do + lambda { 3.should be <= 2 }.should fail_with("expected <= 2, got 3") + end +end + +describe "should be >=" do + it "should pass when >= operator returns true" do + 4.should be >= 4 + 5.should be >= 4 + end + + it "should fail when >= operator returns false" do + lambda { 3.should be >= 4 }.should fail_with("expected >= 4, got 3") + end +end + +describe "should be >" do + it "should pass when > operator returns true" do + 5.should be > 4 + end + + it "should fail when > operator returns false" do + lambda { 3.should be > 4 }.should fail_with("expected > 4, got 3") + end +end + +describe "should be ==" do + it "should pass when == operator returns true" do + 5.should be == 5 + end + + it "should fail when == operator returns false" do + lambda { 3.should be == 4 }.should fail_with("expected == 4, got 3") + end +end + +describe "should be ===" do + it "should pass when === operator returns true" do + Hash.should be === Hash.new + end + + it "should fail when === operator returns false" do + lambda { Hash.should be === "not a hash" }.should fail_with(%[expected === "not a hash", got Hash]) + end +end + +describe "should be(value)" do + it "should pass if actual.equal?(value)" do + 5.should be(5) + end + it "should fail if !actual.equal?(value)" do + lambda { 5.should be(6) }.should fail_with("expected 6, got 5") + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/matchers/change_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/matchers/change_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/matchers/change_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/matchers/change_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,319 @@ +#Based on patch from Wilson Bilkovich + +require File.dirname(__FILE__) + '/../../spec_helper.rb' +class SomethingExpected + attr_accessor :some_value +end + +describe "should change(actual, message)" do + before(:each) do + @instance = SomethingExpected.new + @instance.some_value = 5 + end + + it "should pass when actual is modified by the block" do + lambda {@instance.some_value = 6}.should change(@instance, :some_value) + end + + it "should fail when actual is not modified by the block" do + lambda do + lambda {}.should change(@instance, :some_value) + end.should fail_with("some_value should have changed, but is still 5") + end +end + +describe "should_not change(actual, message)" do + before(:each) do + @instance = SomethingExpected.new + @instance.some_value = 5 + end + + it "should pass when actual is not modified by the block" do + lambda { }.should_not change(@instance, :some_value) + end + + it "should fail when actual is not modified by the block" do + lambda do + lambda {@instance.some_value = 6}.should_not change(@instance, :some_value) + end.should fail_with("some_value should not have changed, but did change from 5 to 6") + end +end + +describe "should change { block }" do + before(:each) do + @instance = SomethingExpected.new + @instance.some_value = 5 + end + + it "should pass when actual is modified by the block" do + lambda {@instance.some_value = 6}.should change { @instance.some_value } + end + + it "should fail when actual is not modified by the block" do + lambda do + lambda {}.should change{ @instance.some_value } + end.should fail_with("result should have changed, but is still 5") + end + + it "should warn if passed a block using do/end" do + lambda do + lambda {}.should change do + end + end.should raise_error(Spec::Matchers::MatcherError, /block passed to should or should_not/) + end +end + +describe "should_not change { block }" do + before(:each) do + @instance = SomethingExpected.new + @instance.some_value = 5 + end + + it "should pass when actual is modified by the block" do + lambda {}.should_not change{ @instance.some_value } + end + + it "should fail when actual is not modified by the block" do + lambda do + lambda {@instance.some_value = 6}.should_not change { @instance.some_value } + end.should fail_with("result should not have changed, but did change from 5 to 6") + end + + it "should warn if passed a block using do/end" do + lambda do + lambda {}.should_not change do + end + end.should raise_error(Spec::Matchers::MatcherError, /block passed to should or should_not/) + end +end + +describe "should change(actual, message).by(expected)" do + before(:each) do + @instance = SomethingExpected.new + @instance.some_value = 5 + end + + it "should pass when attribute is changed by expected amount" do + lambda { @instance.some_value += 1 }.should change(@instance, :some_value).by(1) + end + + it "should fail when the attribute is changed by unexpected amount" do + lambda do + lambda { @instance.some_value += 2 }.should change(@instance, :some_value).by(1) + end.should fail_with("some_value should have been changed by 1, but was changed by 2") + end + + it "should fail when the attribute is changed by unexpected amount in the opposite direction" do + lambda do + lambda { @instance.some_value -= 1 }.should change(@instance, :some_value).by(1) + end.should fail_with("some_value should have been changed by 1, but was changed by -1") + end +end + +describe "should change{ block }.by(expected)" do + before(:each) do + @instance = SomethingExpected.new + @instance.some_value = 5 + end + + it "should pass when attribute is changed by expected amount" do + lambda { @instance.some_value += 1 }.should change{@instance.some_value}.by(1) + end + + it "should fail when the attribute is changed by unexpected amount" do + lambda do + lambda { @instance.some_value += 2 }.should change{@instance.some_value}.by(1) + end.should fail_with("result should have been changed by 1, but was changed by 2") + end + + it "should fail when the attribute is changed by unexpected amount in the opposite direction" do + lambda do + lambda { @instance.some_value -= 1 }.should change{@instance.some_value}.by(1) + end.should fail_with("result should have been changed by 1, but was changed by -1") + end +end + +describe "should change(actual, message).by_at_least(expected)" do + before(:each) do + @instance = SomethingExpected.new + @instance.some_value = 5 + end + + it "should pass when attribute is changed by greater than the expected amount" do + lambda { @instance.some_value += 2 }.should change(@instance, :some_value).by_at_least(1) + end + + it "should pass when attribute is changed by the expected amount" do + lambda { @instance.some_value += 2 }.should change(@instance, :some_value).by_at_least(2) + end + + it "should fail when the attribute is changed by less than the expected amount" do + lambda do + lambda { @instance.some_value += 1 }.should change(@instance, :some_value).by_at_least(2) + end.should fail_with("some_value should have been changed by at least 2, but was changed by 1") + end + +end + +describe "should change{ block }.by_at_least(expected)" do + before(:each) do + @instance = SomethingExpected.new + @instance.some_value = 5 + end + + it "should pass when attribute is changed by greater than expected amount" do + lambda { @instance.some_value += 2 }.should change{@instance.some_value}.by_at_least(1) + end + + it "should pass when attribute is changed by the expected amount" do + lambda { @instance.some_value += 2 }.should change{@instance.some_value}.by_at_least(2) + end + + it "should fail when the attribute is changed by less than the unexpected amount" do + lambda do + lambda { @instance.some_value += 1 }.should change{@instance.some_value}.by_at_least(2) + end.should fail_with("result should have been changed by at least 2, but was changed by 1") + end +end + + +describe "should change(actual, message).by_at_most(expected)" do + before(:each) do + @instance = SomethingExpected.new + @instance.some_value = 5 + end + + it "should pass when attribute is changed by less than the expected amount" do + lambda { @instance.some_value += 2 }.should change(@instance, :some_value).by_at_most(3) + end + + it "should pass when attribute is changed by the expected amount" do + lambda { @instance.some_value += 2 }.should change(@instance, :some_value).by_at_most(2) + end + + it "should fail when the attribute is changed by greater than the expected amount" do + lambda do + lambda { @instance.some_value += 2 }.should change(@instance, :some_value).by_at_most(1) + end.should fail_with("some_value should have been changed by at most 1, but was changed by 2") + end + +end + +describe "should change{ block }.by_at_most(expected)" do + before(:each) do + @instance = SomethingExpected.new + @instance.some_value = 5 + end + + it "should pass when attribute is changed by less than expected amount" do + lambda { @instance.some_value += 2 }.should change{@instance.some_value}.by_at_most(3) + end + + it "should pass when attribute is changed by the expected amount" do + lambda { @instance.some_value += 2 }.should change{@instance.some_value}.by_at_most(2) + end + + it "should fail when the attribute is changed by greater than the unexpected amount" do + lambda do + lambda { @instance.some_value += 2 }.should change{@instance.some_value}.by_at_most(1) + end.should fail_with("result should have been changed by at most 1, but was changed by 2") + end +end + +describe "should change(actual, message).from(old)" do + before(:each) do + @instance = SomethingExpected.new + @instance.some_value = 'string' + end + + it "should pass when attribute is == to expected value before executing block" do + lambda { @instance.some_value = "astring" }.should change(@instance, :some_value).from("string") + end + + it "should fail when attribute is not == to expected value before executing block" do + lambda do + lambda { @instance.some_value = "knot" }.should change(@instance, :some_value).from("cat") + end.should fail_with("some_value should have initially been \"cat\", but was \"string\"") + end +end + +describe "should change{ block }.from(old)" do + before(:each) do + @instance = SomethingExpected.new + @instance.some_value = 'string' + end + + it "should pass when attribute is == to expected value before executing block" do + lambda { @instance.some_value = "astring" }.should change{@instance.some_value}.from("string") + end + + it "should fail when attribute is not == to expected value before executing block" do + lambda do + lambda { @instance.some_value = "knot" }.should change{@instance.some_value}.from("cat") + end.should fail_with("result should have initially been \"cat\", but was \"string\"") + end +end + +describe "should change(actual, message).to(new)" do + before(:each) do + @instance = SomethingExpected.new + @instance.some_value = 'string' + end + + it "should pass when attribute is == to expected value after executing block" do + lambda { @instance.some_value = "cat" }.should change(@instance, :some_value).to("cat") + end + + it "should fail when attribute is not == to expected value after executing block" do + lambda do + lambda { @instance.some_value = "cat" }.should change(@instance, :some_value).from("string").to("dog") + end.should fail_with("some_value should have been changed to \"dog\", but is now \"cat\"") + end +end + +describe "should change{ block }.to(new)" do + before(:each) do + @instance = SomethingExpected.new + @instance.some_value = 'string' + end + + it "should pass when attribute is == to expected value after executing block" do + lambda { @instance.some_value = "cat" }.should change{@instance.some_value}.to("cat") + end + + it "should fail when attribute is not == to expected value after executing block" do + lambda do + lambda { @instance.some_value = "cat" }.should change{@instance.some_value}.from("string").to("dog") + end.should fail_with("result should have been changed to \"dog\", but is now \"cat\"") + end +end + +describe "should change(actual, message).from(old).to(new)" do + before(:each) do + @instance = SomethingExpected.new + @instance.some_value = 'string' + end + + it "should pass when #to comes before #from" do + lambda { @instance.some_value = "cat" }.should change(@instance, :some_value).to("cat").from("string") + end + + it "should pass when #from comes before #to" do + lambda { @instance.some_value = "cat" }.should change(@instance, :some_value).from("string").to("cat") + end +end + +describe "should change{ block }.from(old).to(new)" do + before(:each) do + @instance = SomethingExpected.new + @instance.some_value = 'string' + end + + it "should pass when #to comes before #from" do + lambda { @instance.some_value = "cat" }.should change{@instance.some_value}.to("cat").from("string") + end + + it "should pass when #from comes before #to" do + lambda { @instance.some_value = "cat" }.should change{@instance.some_value}.from("string").to("cat") + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/matchers/description_generation_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/matchers/description_generation_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/matchers/description_generation_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/matchers/description_generation_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,157 @@ +require File.dirname(__FILE__) + '/../../spec_helper.rb' + +describe "Matchers should be able to generate their own descriptions" do + before(:each) do + Spec::Matchers.clear_generated_description + end + + after(:each) do + Spec::Matchers.clear_generated_description + end + + it "should == expected" do + "this".should == "this" + Spec::Matchers.generated_description.should == "should == \"this\"" + end + + it "should not == expected" do + "this".should_not == "that" + Spec::Matchers.generated_description.should == "should not == \"that\"" + end + + it "should be empty (arbitrary predicate)" do + [].should be_empty + Spec::Matchers.generated_description.should == "should be empty" + end + + it "should not be empty (arbitrary predicate)" do + [1].should_not be_empty + Spec::Matchers.generated_description.should == "should not be empty" + end + + it "should be true" do + true.should be_true + Spec::Matchers.generated_description.should == "should be true" + end + + it "should be false" do + false.should be_false + Spec::Matchers.generated_description.should == "should be false" + end + + it "should be nil" do + nil.should be_nil + Spec::Matchers.generated_description.should == "should be nil" + end + + it "should be > n" do + 5.should be > 3 + Spec::Matchers.generated_description.should == "should be > 3" + end + + it "should be predicate arg1, arg2 and arg3" do + 5.0.should be_between(0,10) + Spec::Matchers.generated_description.should == "should be between 0 and 10" + end + + it "should be_few_words predicate should be transformed to 'be few words'" do + 5.should be_kind_of(Fixnum) + Spec::Matchers.generated_description.should == "should be kind of Fixnum" + end + + it "should preserve a proper prefix for be predicate" do + 5.should be_a_kind_of(Fixnum) + Spec::Matchers.generated_description.should == "should be a kind of Fixnum" + 5.should be_an_instance_of(Fixnum) + Spec::Matchers.generated_description.should == "should be an instance of Fixnum" + end + + it "should equal" do + expected = "expected" + expected.should equal(expected) + Spec::Matchers.generated_description.should == "should equal \"expected\"" + end + + it "should_not equal" do + 5.should_not equal(37) + Spec::Matchers.generated_description.should == "should not equal 37" + end + + it "should eql" do + "string".should eql("string") + Spec::Matchers.generated_description.should == "should eql \"string\"" + end + + it "should not eql" do + "a".should_not eql(:a) + Spec::Matchers.generated_description.should == "should not eql :a" + end + + it "should have_key" do + {:a => "a"}.should have_key(:a) + Spec::Matchers.generated_description.should == "should have key :a" + end + + it "should have n items" do + team.should have(3).players + Spec::Matchers.generated_description.should == "should have 3 players" + end + + it "should have at least n items" do + team.should have_at_least(2).players + Spec::Matchers.generated_description.should == "should have at least 2 players" + end + + it "should have at most n items" do + team.should have_at_most(4).players + Spec::Matchers.generated_description.should == "should have at most 4 players" + end + + it "should include" do + [1,2,3].should include(3) + Spec::Matchers.generated_description.should == "should include 3" + end + + it "should match" do + "this string".should match(/this string/) + Spec::Matchers.generated_description.should == "should match /this string/" + end + + it "should raise_error" do + lambda { raise }.should raise_error + Spec::Matchers.generated_description.should == "should raise Exception" + end + + it "should raise_error with type" do + lambda { raise }.should raise_error(RuntimeError) + Spec::Matchers.generated_description.should == "should raise RuntimeError" + end + + it "should raise_error with type and message" do + lambda { raise "there was an error" }.should raise_error(RuntimeError, "there was an error") + Spec::Matchers.generated_description.should == "should raise RuntimeError with \"there was an error\"" + end + + it "should respond_to" do + [].should respond_to(:insert) + Spec::Matchers.generated_description.should == "should respond to #insert" + end + + it "should throw symbol" do + lambda { throw :what_a_mess }.should throw_symbol + Spec::Matchers.generated_description.should == "should throw a Symbol" + end + + it "should throw symbol (with named symbol)" do + lambda { throw :what_a_mess }.should throw_symbol(:what_a_mess) + Spec::Matchers.generated_description.should == "should throw :what_a_mess" + end + + def team + Class.new do + def players + [1,2,3] + end + end.new + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/matchers/eql_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/matchers/eql_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/matchers/eql_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/matchers/eql_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,28 @@ +require File.dirname(__FILE__) + '/../../spec_helper.rb' + +module Spec + module Matchers + describe Eql do + it "should match when actual.eql?(expected)" do + Eql.new(1).matches?(1).should be_true + end + it "should not match when !actual.eql?(expected)" do + Eql.new(1).matches?(2).should be_false + end + it "should describe itself" do + matcher = Eql.new(1) + matcher.description.should == "eql 1" + end + it "should provide message, expected and actual on #failure_message" do + matcher = Eql.new("1") + matcher.matches?(1) + matcher.failure_message.should == ["expected \"1\", got 1 (using .eql?)", "1", 1] + end + it "should provide message, expected and actual on #negative_failure_message" do + matcher = Eql.new(1) + matcher.matches?(1) + matcher.negative_failure_message.should == ["expected 1 not to equal 1 (using .eql?)", 1, 1] + end + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/matchers/equal_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/matchers/equal_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/matchers/equal_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/matchers/equal_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,28 @@ +require File.dirname(__FILE__) + '/../../spec_helper.rb' + +module Spec + module Matchers + describe Equal do + it "should match when actual.equal?(expected)" do + Equal.new(1).matches?(1).should be_true + end + it "should not match when !actual.equal?(expected)" do + Equal.new("1").matches?("1").should be_false + end + it "should describe itself" do + matcher = Equal.new(1) + matcher.description.should == "equal 1" + end + it "should provide message, expected and actual on #failure_message" do + matcher = Equal.new("1") + matcher.matches?(1) + matcher.failure_message.should == ["expected \"1\", got 1 (using .equal?)", "1", 1] + end + it "should provide message, expected and actual on #negative_failure_message" do + matcher = Equal.new(1) + matcher.matches?(1) + matcher.negative_failure_message.should == ["expected 1 not to equal 1 (using .equal?)", 1, 1] + end + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/matchers/exist_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/matchers/exist_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/matchers/exist_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/matchers/exist_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,75 @@ +require File.dirname(__FILE__) + '/../../spec_helper.rb' + +# NOTE - this was initially handled by an explicit matcher, but is now +# handled by a default set of predicate_matchers. + +# module Spec +# module Matchers +# class Exist +# def matches? actual +# @actual = actual +# @actual.exist? +# end +# def failure_message +# "expected #{@actual.inspect} to exist, but it doesn't." +# end +# def negative_failure_message +# "expected #{@actual.inspect} to not exist, but it does." +# end +# end +# def exist; Exist.new; end +# end +# end + + +class Substance + def initialize exists, description + @exists = exists + @description = description + end + def exist? + @exists + end + def inspect + @description + end +end + +class SubstanceTester + include Spec::Matchers + def initialize substance + @substance = substance + end + def should_exist + @substance.should exist + end +end + +describe "should exist" do + before(:each) do + @real = Substance.new true, 'something real' + @imaginary = Substance.new false, 'something imaginary' + end + + it "should pass if target exists" do + @real.should exist + end + + it "should fail if target does not exist" do + lambda { @imaginary.should exist }. + should fail + end +end + +describe "should exist, outside of a behavior" do + before(:each) do + @real = Substance.new true, 'something real' + @imaginary = Substance.new false, 'something imaginary' + end + it "should pass if target exists" do + pending("need to either find a way to include stock predicate matchers in Spec::Matchers or add Bret's Exist matcher") do + real_tester = SubstanceTester.new @real + real_tester.should_exist + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/matchers/handler_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/matchers/handler_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/matchers/handler_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/matchers/handler_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,129 @@ +require File.dirname(__FILE__) + '/../../spec_helper.rb' + +module ExampleExpectations + + class ArbitraryMatcher + def initialize(*args, &block) + if args.last.is_a? Hash + @expected = args.last[:expected] + end + if block_given? + @expected = block.call + end + @block = block + end + + def matches?(target) + @target = target + return @expected == target + end + + def with(new_value) + @expected = new_value + self + end + + def failure_message + "expected #{@expected}, got #{@target}" + end + + def negative_failure_message + "expected not #{@expected}, got #{@target}" + end + end + + class PositiveOnlyMatcher < ArbitraryMatcher + undef negative_failure_message rescue nil + end + + def arbitrary_matcher(*args, &block) + ArbitraryMatcher.new(*args, &block) + end + + def positive_only_matcher(*args, &block) + PositiveOnlyMatcher.new(*args, &block) + end + +end + +module Spec + module Expectations + describe ExpectationMatcherHandler, ".handle_matcher" do + it "should ask the matcher if it matches" do + matcher = mock("matcher") + actual = Object.new + matcher.should_receive(:matches?).with(actual).and_return(true) + ExpectationMatcherHandler.handle_matcher(actual, matcher) + end + + it "should explain when the matcher parameter is not a matcher" do + begin + nonmatcher = mock("nonmatcher") + actual = Object.new + ExpectationMatcherHandler.handle_matcher(actual, nonmatcher) + rescue Spec::Expectations::InvalidMatcherError => e + end + + e.message.should =~ /^Expected a matcher, got / + end + end + + describe NegativeExpectationMatcherHandler, ".handle_matcher" do + it "should explain when matcher does not support should_not" do + matcher = mock("matcher") + matcher.stub!(:matches?) + actual = Object.new + lambda { + NegativeExpectationMatcherHandler.handle_matcher(actual, matcher) + }.should fail_with(/Matcher does not support should_not.\n/) + end + + it "should ask the matcher if it matches" do + matcher = mock("matcher") + actual = Object.new + matcher.stub!(:negative_failure_message) + matcher.should_receive(:matches?).with(actual).and_return(false) + NegativeExpectationMatcherHandler.handle_matcher(actual, matcher) + end + + it "should explain when the matcher parameter is not a matcher" do + begin + nonmatcher = mock("nonmatcher") + actual = Object.new + NegativeExpectationMatcherHandler.handle_matcher(actual, nonmatcher) + rescue Spec::Expectations::InvalidMatcherError => e + end + + e.message.should =~ /^Expected a matcher, got / + end + end + + describe ExpectationMatcherHandler do + include ExampleExpectations + + it "should handle submitted args" do + 5.should arbitrary_matcher(:expected => 5) + 5.should arbitrary_matcher(:expected => "wrong").with(5) + lambda { 5.should arbitrary_matcher(:expected => 4) }.should fail_with("expected 4, got 5") + lambda { 5.should arbitrary_matcher(:expected => 5).with(4) }.should fail_with("expected 4, got 5") + 5.should_not arbitrary_matcher(:expected => 4) + 5.should_not arbitrary_matcher(:expected => 5).with(4) + lambda { 5.should_not arbitrary_matcher(:expected => 5) }.should fail_with("expected not 5, got 5") + lambda { 5.should_not arbitrary_matcher(:expected => 4).with(5) }.should fail_with("expected not 5, got 5") + end + + it "should handle the submitted block" do + 5.should arbitrary_matcher { 5 } + 5.should arbitrary_matcher(:expected => 4) { 5 } + 5.should arbitrary_matcher(:expected => 4).with(5) { 3 } + end + + it "should explain when matcher does not support should_not" do + lambda { + 5.should_not positive_only_matcher(:expected => 5) + }.should fail_with(/Matcher does not support should_not.\n/) + end + + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/matchers/has_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/matchers/has_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/matchers/has_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/matchers/has_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,37 @@ +require File.dirname(__FILE__) + '/../../spec_helper.rb' + +describe "should have_sym(*args)" do + it "should pass if #has_sym?(*args) returns true" do + {:a => "A"}.should have_key(:a) + end + + it "should fail if #has_sym?(*args) returns false" do + lambda { + {:b => "B"}.should have_key(:a) + }.should fail_with("expected #has_key?(:a) to return true, got false") + end + + it "should fail if target does not respond to #has_sym?" do + lambda { + Object.new.should have_key(:a) + }.should raise_error(NoMethodError) + end +end + +describe "should_not have_sym(*args)" do + it "should pass if #has_sym?(*args) returns false" do + {:a => "A"}.should_not have_key(:b) + end + + it "should fail if #has_sym?(*args) returns true" do + lambda { + {:a => "A"}.should_not have_key(:a) + }.should fail_with("expected #has_key?(:a) to return false, got true") + end + + it "should fail if target does not respond to #has_sym?" do + lambda { + Object.new.should have_key(:a) + }.should raise_error(NoMethodError) + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/matchers/have_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/matchers/have_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/matchers/have_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/matchers/have_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,272 @@ +require File.dirname(__FILE__) + '/../../spec_helper.rb' + +module HaveSpecHelper + def create_collection_owner_with(n) + owner = Spec::Expectations::Helper::CollectionOwner.new + (1..n).each do |n| + owner.add_to_collection_with_length_method(n) + owner.add_to_collection_with_size_method(n) + end + owner + end +end + +describe "should have(n).items" do + include HaveSpecHelper + + it "should pass if target has a collection of items with n members" do + owner = create_collection_owner_with(3) + owner.should have(3).items_in_collection_with_length_method + owner.should have(3).items_in_collection_with_size_method + end + + it "should convert :no to 0" do + owner = create_collection_owner_with(0) + owner.should have(:no).items_in_collection_with_length_method + owner.should have(:no).items_in_collection_with_size_method + end + + it "should fail if target has a collection of items with < n members" do + owner = create_collection_owner_with(3) + lambda { + owner.should have(4).items_in_collection_with_length_method + }.should fail_with("expected 4 items_in_collection_with_length_method, got 3") + lambda { + owner.should have(4).items_in_collection_with_size_method + }.should fail_with("expected 4 items_in_collection_with_size_method, got 3") + end + + it "should fail if target has a collection of items with > n members" do + owner = create_collection_owner_with(3) + lambda { + owner.should have(2).items_in_collection_with_length_method + }.should fail_with("expected 2 items_in_collection_with_length_method, got 3") + lambda { + owner.should have(2).items_in_collection_with_size_method + }.should fail_with("expected 2 items_in_collection_with_size_method, got 3") + end +end + +describe "should have(n).items where result responds to items but returns something other than a collection" do + it "should provide a meaningful error" do + owner = Class.new do + def items + Object.new + end + end.new + lambda do + owner.should have(3).items + end.should raise_error("expected items to be a collection but it does not respond to #length or #size") + end +end + +describe "should_not have(n).items" do + include HaveSpecHelper + + it "should pass if target has a collection of items with < n members" do + owner = create_collection_owner_with(3) + owner.should_not have(4).items_in_collection_with_length_method + owner.should_not have(4).items_in_collection_with_size_method + end + + it "should pass if target has a collection of items with > n members" do + owner = create_collection_owner_with(3) + owner.should_not have(2).items_in_collection_with_length_method + owner.should_not have(2).items_in_collection_with_size_method + end + + it "should fail if target has a collection of items with n members" do + owner = create_collection_owner_with(3) + lambda { + owner.should_not have(3).items_in_collection_with_length_method + }.should fail_with("expected target not to have 3 items_in_collection_with_length_method, got 3") + lambda { + owner.should_not have(3).items_in_collection_with_size_method + }.should fail_with("expected target not to have 3 items_in_collection_with_size_method, got 3") + end +end + +describe "should have_exactly(n).items" do + include HaveSpecHelper + + it "should pass if target has a collection of items with n members" do + owner = create_collection_owner_with(3) + owner.should have_exactly(3).items_in_collection_with_length_method + owner.should have_exactly(3).items_in_collection_with_size_method + end + + it "should convert :no to 0" do + owner = create_collection_owner_with(0) + owner.should have_exactly(:no).items_in_collection_with_length_method + owner.should have_exactly(:no).items_in_collection_with_size_method + end + + it "should fail if target has a collection of items with < n members" do + owner = create_collection_owner_with(3) + lambda { + owner.should have_exactly(4).items_in_collection_with_length_method + }.should fail_with("expected 4 items_in_collection_with_length_method, got 3") + lambda { + owner.should have_exactly(4).items_in_collection_with_size_method + }.should fail_with("expected 4 items_in_collection_with_size_method, got 3") + end + + it "should fail if target has a collection of items with > n members" do + owner = create_collection_owner_with(3) + lambda { + owner.should have_exactly(2).items_in_collection_with_length_method + }.should fail_with("expected 2 items_in_collection_with_length_method, got 3") + lambda { + owner.should have_exactly(2).items_in_collection_with_size_method + }.should fail_with("expected 2 items_in_collection_with_size_method, got 3") + end +end + +describe "should have_at_least(n).items" do + include HaveSpecHelper + + it "should pass if target has a collection of items with n members" do + owner = create_collection_owner_with(3) + owner.should have_at_least(3).items_in_collection_with_length_method + owner.should have_at_least(3).items_in_collection_with_size_method + end + + it "should pass if target has a collection of items with > n members" do + owner = create_collection_owner_with(3) + owner.should have_at_least(2).items_in_collection_with_length_method + owner.should have_at_least(2).items_in_collection_with_size_method + end + + it "should fail if target has a collection of items with < n members" do + owner = create_collection_owner_with(3) + lambda { + owner.should have_at_least(4).items_in_collection_with_length_method + }.should fail_with("expected at least 4 items_in_collection_with_length_method, got 3") + lambda { + owner.should have_at_least(4).items_in_collection_with_size_method + }.should fail_with("expected at least 4 items_in_collection_with_size_method, got 3") + end + + it "should provide educational negative failure messages" do + #given + owner = create_collection_owner_with(3) + length_matcher = have_at_least(3).items_in_collection_with_length_method + size_matcher = have_at_least(3).items_in_collection_with_size_method + + #when + length_matcher.matches?(owner) + size_matcher.matches?(owner) + + #then + length_matcher.negative_failure_message.should == <<-EOF +Isn't life confusing enough? +Instead of having to figure out the meaning of this: + should_not have_at_least(3).items_in_collection_with_length_method +We recommend that you use this instead: + should have_at_most(2).items_in_collection_with_length_method +EOF + + size_matcher.negative_failure_message.should == <<-EOF +Isn't life confusing enough? +Instead of having to figure out the meaning of this: + should_not have_at_least(3).items_in_collection_with_size_method +We recommend that you use this instead: + should have_at_most(2).items_in_collection_with_size_method +EOF + end +end + +describe "should have_at_most(n).items" do + include HaveSpecHelper + + it "should pass if target has a collection of items with n members" do + owner = create_collection_owner_with(3) + owner.should have_at_most(3).items_in_collection_with_length_method + owner.should have_at_most(3).items_in_collection_with_size_method + end + + it "should fail if target has a collection of items with > n members" do + owner = create_collection_owner_with(3) + lambda { + owner.should have_at_most(2).items_in_collection_with_length_method + }.should fail_with("expected at most 2 items_in_collection_with_length_method, got 3") + lambda { + owner.should have_at_most(2).items_in_collection_with_size_method + }.should fail_with("expected at most 2 items_in_collection_with_size_method, got 3") + end + + it "should pass if target has a collection of items with < n members" do + owner = create_collection_owner_with(3) + owner.should have_at_most(4).items_in_collection_with_length_method + owner.should have_at_most(4).items_in_collection_with_size_method + end + + it "should provide educational negative failure messages" do + #given + owner = create_collection_owner_with(3) + length_matcher = have_at_most(3).items_in_collection_with_length_method + size_matcher = have_at_most(3).items_in_collection_with_size_method + + #when + length_matcher.matches?(owner) + size_matcher.matches?(owner) + + #then + length_matcher.negative_failure_message.should == <<-EOF +Isn't life confusing enough? +Instead of having to figure out the meaning of this: + should_not have_at_most(3).items_in_collection_with_length_method +We recommend that you use this instead: + should have_at_least(4).items_in_collection_with_length_method +EOF + + size_matcher.negative_failure_message.should == <<-EOF +Isn't life confusing enough? +Instead of having to figure out the meaning of this: + should_not have_at_most(3).items_in_collection_with_size_method +We recommend that you use this instead: + should have_at_least(4).items_in_collection_with_size_method +EOF + end +end + +describe "have(n).items(args, block)" do + it "should pass args to target" do + target = mock("target") + target.should_receive(:items).with("arg1","arg2").and_return([1,2,3]) + target.should have(3).items("arg1","arg2") + end + + it "should pass block to target" do + target = mock("target") + block = lambda { 5 } + target.should_receive(:items).with("arg1","arg2", block).and_return([1,2,3]) + target.should have(3).items("arg1","arg2", block) + end +end + +describe "have(n).items where target IS a collection" do + it "should reference the number of items IN the collection" do + [1,2,3].should have(3).items + end + + it "should fail when the number of items IN the collection is not as expected" do + lambda { [1,2,3].should have(7).items }.should fail_with("expected 7 items, got 3") + end +end + +describe "have(n).characters where target IS a String" do + it "should pass if the length is correct" do + "this string".should have(11).characters + end + + it "should fail if the length is incorrect" do + lambda { "this string".should have(12).characters }.should fail_with("expected 12 characters, got 11") + end +end + +describe "have(n).things on an object which is not a collection nor contains one" do + it "should fail" do + lambda { Object.new.should have(2).things }.should raise_error(NoMethodError, /undefined method `things' for #" do + + it "should pass if > passes" do + 4.should > 3 + end + + it "should fail if > fails" do + Spec::Expectations.should_receive(:fail_with).with(%[expected: > 5,\n got: 4], 5, 4) + 4.should > 5 + end + +end + +describe "should >=" do + + it "should pass if >= passes" do + 4.should > 3 + 4.should >= 4 + end + + it "should fail if > fails" do + Spec::Expectations.should_receive(:fail_with).with(%[expected: >= 5,\n got: 4], 5, 4) + 4.should >= 5 + end + +end + +describe "should <" do + + it "should pass if < passes" do + 4.should < 5 + end + + it "should fail if > fails" do + Spec::Expectations.should_receive(:fail_with).with(%[expected: < 3,\n got: 4], 3, 4) + 4.should < 3 + end + +end + +describe "should <=" do + + it "should pass if <= passes" do + 4.should <= 5 + 4.should <= 4 + end + + it "should fail if > fails" do + Spec::Expectations.should_receive(:fail_with).with(%[expected: <= 3,\n got: 4], 3, 4) + 4.should <= 3 + end + +end + diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/matchers/raise_error_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/matchers/raise_error_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/matchers/raise_error_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/matchers/raise_error_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,185 @@ +require File.dirname(__FILE__) + '/../../spec_helper.rb' + +describe "should raise_error" do + it "should pass if anything is raised" do + lambda {raise}.should raise_error + end + + it "should fail if nothing is raised" do + lambda { + lambda {}.should raise_error + }.should fail_with("expected Exception but nothing was raised") + end +end + +describe "should_not raise_error" do + it "should pass if nothing is raised" do + lambda {}.should_not raise_error + end + + it "should fail if anything is raised" do + lambda { + lambda {raise}.should_not raise_error + }.should fail_with("expected no Exception, got RuntimeError") + end +end + +describe "should raise_error(message)" do + it "should pass if RuntimeError is raised with the right message" do + lambda {raise 'blah'}.should raise_error('blah') + end + it "should pass if any other error is raised with the right message" do + lambda {raise NameError.new('blah')}.should raise_error('blah') + end + it "should fail if RuntimeError error is raised with the wrong message" do + lambda do + lambda {raise 'blarg'}.should raise_error('blah') + end.should fail_with("expected Exception with \"blah\", got #") + end + it "should fail if any other error is raised with the wrong message" do + lambda do + lambda {raise NameError.new('blarg')}.should raise_error('blah') + end.should fail_with("expected Exception with \"blah\", got #") + end +end + +describe "should_not raise_error(message)" do + it "should pass if RuntimeError error is raised with the different message" do + lambda {raise 'blarg'}.should_not raise_error('blah') + end + it "should pass if any other error is raised with the wrong message" do + lambda {raise NameError.new('blarg')}.should_not raise_error('blah') + end + it "should fail if RuntimeError is raised with message" do + lambda do + lambda {raise 'blah'}.should_not raise_error('blah') + end.should fail_with(%Q|expected no Exception with "blah", got #|) + end + it "should fail if any other error is raised with message" do + lambda do + lambda {raise NameError.new('blah')}.should_not raise_error('blah') + end.should fail_with(%Q|expected no Exception with "blah", got #|) + end +end + +describe "should raise_error(NamedError)" do + it "should pass if named error is raised" do + lambda { non_existent_method }.should raise_error(NameError) + end + + it "should fail if nothing is raised" do + lambda { + lambda { }.should raise_error(NameError) + }.should fail_with("expected NameError but nothing was raised") + end + + it "should fail if another error is raised" do + lambda { + lambda { raise }.should raise_error(NameError) + }.should fail_with("expected NameError, got RuntimeError") + end +end + +describe "should_not raise_error(NamedError)" do + it "should pass if nothing is raised" do + lambda { }.should_not raise_error(NameError) + end + + it "should pass if another error is raised" do + lambda { raise }.should_not raise_error(NameError) + end + + it "should fail if named error is raised" do + lambda { + lambda { non_existent_method }.should_not raise_error(NameError) + }.should fail_with(/expected no NameError, got #") + end +end + +describe "should raise_error(NamedError, error_message) with Regexp" do + it "should pass if named error is raised with matching message" do + lambda { raise "example message" }.should raise_error(RuntimeError, /ample mess/) + end + + it "should fail if nothing is raised" do + lambda { + lambda {}.should raise_error(RuntimeError, /ample mess/) + }.should fail_with("expected RuntimeError with message matching /ample mess/ but nothing was raised") + end + + it "should fail if incorrect error is raised" do + lambda { + lambda { raise }.should raise_error(NameError, /ample mess/) + }.should fail_with("expected NameError with message matching /ample mess/, got RuntimeError") + end + + it "should fail if correct error is raised with incorrect message" do + lambda { + lambda { raise RuntimeError.new("not the example message") }.should raise_error(RuntimeError, /less than ample mess/) + }.should fail_with("expected RuntimeError with message matching /less than ample mess/, got #") + end +end + +describe "should_not raise_error(NamedError, error_message) with Regexp" do + it "should pass if nothing is raised" do + lambda {}.should_not raise_error(RuntimeError, /ample mess/) + end + + it "should pass if a different error is raised" do + lambda { raise }.should_not raise_error(NameError, /ample mess/) + end + + it "should pass if same error is raised with non-matching message" do + lambda { raise RuntimeError.new("non matching message") }.should_not raise_error(RuntimeError, /ample mess/) + end + + it "should fail if named error is raised with matching message" do + lambda { + lambda { raise "example message" }.should_not raise_error(RuntimeError, /ample mess/) + }.should fail_with("expected no RuntimeError with message matching /ample mess/, got #") + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/matchers/respond_to_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/matchers/respond_to_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/matchers/respond_to_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/matchers/respond_to_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,54 @@ +require File.dirname(__FILE__) + '/../../spec_helper.rb' + +describe "should respond_to(:sym)" do + + it "should pass if target responds to :sym" do + Object.new.should respond_to(:methods) + end + + it "should fail target does not respond to :sym" do + lambda { + Object.new.should respond_to(:some_method) + }.should fail_with("expected target to respond to :some_method") + end + +end + +describe "should respond_to(message1, message2)" do + + it "should pass if target responds to both messages" do + Object.new.should respond_to('methods', 'inspect') + end + + it "should fail target does not respond to first message" do + lambda { + Object.new.should respond_to('method_one', 'inspect') + }.should fail_with('expected target to respond to "method_one"') + end + + it "should fail target does not respond to second message" do + lambda { + Object.new.should respond_to('inspect', 'method_one') + }.should fail_with('expected target to respond to "method_one"') + end + + it "should fail target does not respond to either message" do + lambda { + Object.new.should respond_to('method_one', 'method_two') + }.should fail_with('expected target to respond to "method_one", "method_two"') + end +end + +describe "should_not respond_to(:sym)" do + + it "should pass if target does not respond to :sym" do + Object.new.should_not respond_to(:some_method) + end + + it "should fail target responds to :sym" do + lambda { + Object.new.should_not respond_to(:methods) + }.should fail_with("expected target not to respond to :methods") + end + +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/matchers/satisfy_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/matchers/satisfy_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/matchers/satisfy_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/matchers/satisfy_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,36 @@ +require File.dirname(__FILE__) + '/../../spec_helper.rb' + +describe "should satisfy { block }" do + it "should pass if block returns true" do + true.should satisfy { |val| val } + true.should satisfy do |val| + val + end + end + + it "should fail if block returns false" do + lambda { + false.should satisfy { |val| val } + }.should fail_with("expected false to satisfy block") + lambda do + false.should satisfy do |val| + val + end + end.should fail_with("expected false to satisfy block") + end +end + +describe "should_not satisfy { block }" do + it "should pass if block returns false" do + false.should_not satisfy { |val| val } + false.should_not satisfy do |val| + val + end + end + + it "should fail if block returns true" do + lambda { + true.should_not satisfy { |val| val } + }.should fail_with("expected true not to satisfy block") + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/matchers/simple_matcher_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/matchers/simple_matcher_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/matchers/simple_matcher_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/matchers/simple_matcher_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,31 @@ +require File.dirname(__FILE__) + '/../../spec_helper' + +module Spec + module Matchers + describe SimpleMatcher do + it "should match pass match arg to block" do + actual = nil + matcher = simple_matcher("message") do |given| actual = given end + matcher.matches?("foo") + actual.should == "foo" + end + + it "should provide a stock failure message" do + matcher = simple_matcher("thing") do end + matcher.matches?("other") + matcher.failure_message.should =~ /expected \"thing\" but got \"other\"/ + end + + it "should provide a stock negative failure message" do + matcher = simple_matcher("thing") do end + matcher.matches?("other") + matcher.negative_failure_message.should =~ /expected not to get \"thing\", but got \"other\"/ + end + + it "should provide a description" do + matcher = simple_matcher("thing") do end + matcher.description.should =="thing" + end + end + end +end \ No newline at end of file diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/matchers/throw_symbol_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/matchers/throw_symbol_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/matchers/throw_symbol_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/matchers/throw_symbol_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,54 @@ +require File.dirname(__FILE__) + '/../../spec_helper.rb' + +module Spec + module Matchers + describe ThrowSymbol, "(constructed with no Symbol)" do + before(:each) { @matcher = ThrowSymbol.new } + + it "should match if any Symbol is thrown" do + @matcher.matches?(lambda{ throw :sym }).should be_true + end + it "should not match if no Symbol is thrown" do + @matcher.matches?(lambda{ }).should be_false + end + it "should provide a failure message" do + @matcher.matches?(lambda{}) + @matcher.failure_message.should == "expected a Symbol but nothing was thrown" + end + it "should provide a negative failure message" do + @matcher.matches?(lambda{ throw :sym}) + @matcher.negative_failure_message.should == "expected no Symbol, got :sym" + end + end + + describe ThrowSymbol, "(constructed with a Symbol)" do + before(:each) { @matcher = ThrowSymbol.new(:sym) } + + it "should match if correct Symbol is thrown" do + @matcher.matches?(lambda{ throw :sym }).should be_true + end + it "should not match if no Symbol is thrown" do + @matcher.matches?(lambda{ }).should be_false + end + it "should not match if correct Symbol is thrown" do + @matcher.matches?(lambda{ throw :other_sym }).should be_false + @matcher.failure_message.should == "expected :sym, got :other_sym" + end + it "should provide a failure message when no Symbol is thrown" do + @matcher.matches?(lambda{}) + @matcher.failure_message.should == "expected :sym but nothing was thrown" + end + it "should provide a failure message when wrong Symbol is thrown" do + @matcher.matches?(lambda{ throw :other_sym }) + @matcher.failure_message.should == "expected :sym, got :other_sym" + end + it "should provide a negative failure message" do + @matcher.matches?(lambda{ throw :sym }) + @matcher.negative_failure_message.should == "expected :sym not to be thrown" + end + it "should only match NameErrors raised by uncaught throws" do + @matcher.matches?(lambda{ sym }).should be_false + end + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/mocks/any_number_of_times_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/mocks/any_number_of_times_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/mocks/any_number_of_times_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/mocks/any_number_of_times_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,29 @@ +require File.dirname(__FILE__) + '/../../spec_helper.rb' + +module Spec + module Mocks + + describe "AnyNumberOfTimes" do + before(:each) do + @mock = Mock.new("test mock") + end + + it "should pass if any number of times method is called many times" do + @mock.should_receive(:random_call).any_number_of_times + (1..10).each do + @mock.random_call + end + end + + it "should pass if any number of times method is called once" do + @mock.should_receive(:random_call).any_number_of_times + @mock.random_call + end + + it "should pass if any number of times method is not called" do + @mock.should_receive(:random_call).any_number_of_times + end + end + + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/mocks/argument_expectation_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/mocks/argument_expectation_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/mocks/argument_expectation_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/mocks/argument_expectation_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,23 @@ +require File.dirname(__FILE__) + '/../../spec_helper.rb' + +module Spec + module Mocks + describe ArgumentExpectation do + it "should consider an object that responds to #matches? and #description to be a matcher" do + argument_expecatation = Spec::Mocks::ArgumentExpectation.new([]) + obj = mock("matcher") + obj.should_receive(:respond_to?).with(:matches?).and_return(true) + obj.should_receive(:respond_to?).with(:description).and_return(true) + argument_expecatation.is_matcher?(obj).should be_true + end + + it "should NOT consider an object that only responds to #matches? to be a matcher" do + argument_expecatation = Spec::Mocks::ArgumentExpectation.new([]) + obj = mock("matcher") + obj.should_receive(:respond_to?).with(:matches?).and_return(true) + obj.should_receive(:respond_to?).with(:description).and_return(false) + argument_expecatation.is_matcher?(obj).should be_false + end + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/mocks/at_least_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/mocks/at_least_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/mocks/at_least_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/mocks/at_least_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,97 @@ +require File.dirname(__FILE__) + '/../../spec_helper.rb' + +module Spec + module Mocks + describe "at_least" do + before(:each) do + @mock = Mock.new("test mock") + end + + it "should fail if method is never called" do + @mock.should_receive(:random_call).at_least(4).times + lambda do + @mock.rspec_verify + end.should raise_error(MockExpectationError) + end + + it "should fail when called less than n times" do + @mock.should_receive(:random_call).at_least(4).times + @mock.random_call + @mock.random_call + @mock.random_call + lambda do + @mock.rspec_verify + end.should raise_error(MockExpectationError) + end + + it "should fail when at least once method is never called" do + @mock.should_receive(:random_call).at_least(:once) + lambda do + @mock.rspec_verify + end.should raise_error(MockExpectationError) + end + + it "should fail when at least twice method is called once" do + @mock.should_receive(:random_call).at_least(:twice) + @mock.random_call + lambda do + @mock.rspec_verify + end.should raise_error(MockExpectationError) + end + + it "should fail when at least twice method is never called" do + @mock.should_receive(:random_call).at_least(:twice) + lambda do + @mock.rspec_verify + end.should raise_error(MockExpectationError) + end + + it "should pass when at least n times method is called exactly n times" do + @mock.should_receive(:random_call).at_least(4).times + @mock.random_call + @mock.random_call + @mock.random_call + @mock.random_call + @mock.rspec_verify + end + + it "should pass when at least n times method is called n plus 1 times" do + @mock.should_receive(:random_call).at_least(4).times + @mock.random_call + @mock.random_call + @mock.random_call + @mock.random_call + @mock.random_call + @mock.rspec_verify + end + + it "should pass when at least once method is called once" do + @mock.should_receive(:random_call).at_least(:once) + @mock.random_call + @mock.rspec_verify + end + + it "should pass when at least once method is called twice" do + @mock.should_receive(:random_call).at_least(:once) + @mock.random_call + @mock.random_call + @mock.rspec_verify + end + + it "should pass when at least twice method is called three times" do + @mock.should_receive(:random_call).at_least(:twice) + @mock.random_call + @mock.random_call + @mock.random_call + @mock.rspec_verify + end + + it "should pass when at least twice method is called twice" do + @mock.should_receive(:random_call).at_least(:twice) + @mock.random_call + @mock.random_call + @mock.rspec_verify + end + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/mocks/at_most_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/mocks/at_most_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/mocks/at_most_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/mocks/at_most_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,93 @@ +require File.dirname(__FILE__) + '/../../spec_helper.rb' + +module Spec + module Mocks + describe "at_most" do + before(:each) do + @mock = Mock.new("test mock") + end + + it "should fail when at most n times method is called n plus 1 times" do + @mock.should_receive(:random_call).at_most(4).times + @mock.random_call + @mock.random_call + @mock.random_call + @mock.random_call + @mock.random_call + lambda do + @mock.rspec_verify + end.should raise_error(MockExpectationError) + end + + it "should fail when at most once method is called twice" do + @mock.should_receive(:random_call).at_most(:once) + @mock.random_call + @mock.random_call + lambda do + @mock.rspec_verify + end.should raise_error(MockExpectationError) + end + + it "should fail when at most twice method is called three times" do + @mock.should_receive(:random_call).at_most(:twice) + @mock.random_call + @mock.random_call + @mock.random_call + lambda do + @mock.rspec_verify + end.should raise_error(MockExpectationError) + end + + it "should pass when at most n times method is called exactly n times" do + @mock.should_receive(:random_call).at_most(4).times + @mock.random_call + @mock.random_call + @mock.random_call + @mock.random_call + @mock.rspec_verify + end + + it "should pass when at most n times method is called less than n times" do + @mock.should_receive(:random_call).at_most(4).times + @mock.random_call + @mock.random_call + @mock.random_call + @mock.rspec_verify + end + + it "should pass when at most n times method is never called" do + @mock.should_receive(:random_call).at_most(4).times + @mock.rspec_verify + end + + it "should pass when at most once method is called once" do + @mock.should_receive(:random_call).at_most(:once) + @mock.random_call + @mock.rspec_verify + end + + it "should pass when at most once method is never called" do + @mock.should_receive(:random_call).at_most(:once) + @mock.rspec_verify + end + + it "should pass when at most twice method is called once" do + @mock.should_receive(:random_call).at_most(:twice) + @mock.random_call + @mock.rspec_verify + end + + it "should pass when at most twice method is called twice" do + @mock.should_receive(:random_call).at_most(:twice) + @mock.random_call + @mock.random_call + @mock.rspec_verify + end + + it "should pass when at most twice method is never called" do + @mock.should_receive(:random_call).at_most(:twice) + @mock.rspec_verify + end + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/mocks/bug_report_10260_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/mocks/bug_report_10260_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/mocks/bug_report_10260_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/mocks/bug_report_10260_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,8 @@ +require File.dirname(__FILE__) + '/../../spec_helper.rb' + +describe "An RSpec Mock" do + it "should hide internals in its inspect representation" do + m = mock('cup') + m.inspect.should =~ /#/ + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/mocks/bug_report_10263.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/mocks/bug_report_10263.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/mocks/bug_report_10263.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/mocks/bug_report_10263.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,24 @@ +describe "Mock" do + before do + @mock = mock("test mock") + end + + specify "when one example has an expectation (non-mock) inside the block passed to the mock" do + @mock.should_receive(:msg) do |b| + b.should be_true #this call exposes the problem + end + @mock.msg(false) rescue nil + end + + specify "then the next example should behave as expected instead of saying" do + @mock.should_receive(:foobar) + @mock.foobar + @mock.rspec_verify + begin + @mock.foobar + rescue => e + e.message.should == "Mock 'test mock' received unexpected message :foobar with (no args)" + end + end +end + diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/mocks/bug_report_11545_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/mocks/bug_report_11545_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/mocks/bug_report_11545_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/mocks/bug_report_11545_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,31 @@ +require File.dirname(__FILE__) + '/../../spec_helper.rb' + +class LiarLiarPantsOnFire + def respond_to?(sym) + true + end + + def self.respond_to?(sym) + true + end +end + +describe 'should_receive' do + before(:each) do + @liar = LiarLiarPantsOnFire.new + end + + it "should work when object lies about responding to a method" do + @liar.should_receive(:something) + @liar.something + end + + it 'should work when class lies about responding to a method' do + LiarLiarPantsOnFire.should_receive(:something) + LiarLiarPantsOnFire.something + end + + it 'should cleanup after itself' do + LiarLiarPantsOnFire.metaclass.instance_methods.should_not include("something") + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/mocks/bug_report_15719_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/mocks/bug_report_15719_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/mocks/bug_report_15719_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/mocks/bug_report_15719_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,30 @@ +require File.dirname(__FILE__) + '/../../spec_helper.rb' + +module Spec + module Mocks + describe "mock failure" do + + it "should tell you when it receives the right message with the wrong args" do + m = mock("foo") + m.should_receive(:bar).with("message") + lambda { + m.bar("different message") + }.should raise_error(Spec::Mocks::MockExpectationError, %Q{Mock 'foo' expected :bar with ("message") but received it with ("different message")}) + m.bar("message") # allows the spec to pass + end + + it "should tell you when it receives the right message with the wrong args if you stub the method" do + pending("fix bug 15719") + # NOTE - for whatever reason, if you use a the block style of pending here, + # rcov gets unhappy. Don't know why yet. + m = mock("foo") + m.stub!(:bar) + m.should_receive(:bar).with("message") + lambda { + m.bar("different message") + }.should raise_error(Spec::Mocks::MockExpectationError, %Q{Mock 'foo' expected :bar with ("message") but received it with ("different message")}) + m.bar("message") # allows the spec to pass + end + end + end +end \ No newline at end of file diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/mocks/bug_report_7611_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/mocks/bug_report_7611_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/mocks/bug_report_7611_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/mocks/bug_report_7611_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,19 @@ +require File.dirname(__FILE__) + '/../../spec_helper.rb' + +module Bug7611 + class Foo + end + + class Bar < Foo + end + + describe "A Partial Mock" do + it "should respect subclasses" do + Foo.stub!(:new).and_return(Object.new) + end + + it "should" do + Bar.new.class.should == Bar + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/mocks/bug_report_7805_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/mocks/bug_report_7805_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/mocks/bug_report_7805_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/mocks/bug_report_7805_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,22 @@ +require File.dirname(__FILE__) + '/../../spec_helper.rb' + +module Bug7805 + #This is really a duplicate of 8302 + + describe "Stubs should correctly restore module methods" do + it "1 - stub the open method" do + File.stub!(:open).and_return("something") + File.open.should == "something" + end + it "2 - use File.open to create example.txt" do + filename = "#{File.dirname(__FILE__)}/example-#{Time.new.to_i}.txt" + File.exist?(filename).should be_false + file = File.open(filename,'w') + file.close + File.exist?(filename).should be_true + File.delete(filename) + File.exist?(filename).should be_false + end + end + +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/mocks/bug_report_8165_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/mocks/bug_report_8165_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/mocks/bug_report_8165_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/mocks/bug_report_8165_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,31 @@ +require File.dirname(__FILE__) + '/../../spec_helper.rb' + +describe "An object where respond_to? is true and does not have method" do + # When should_receive(:sym) is sent to any object, the Proxy sends + # respond_to?(:sym) to that object to see if the method should be proxied. + # + # If respond_to? itself is proxied, then when the Proxy sends respond_to? + # to the object, the proxy is invoked and responds yes (if so set in the spec). + # When the object does NOT actually respond to :sym, an exception is thrown + # when trying to proxy it. + # + # The fix was to keep track of whether :respond_to? had been proxied and, if + # so, call the munged copy of :respond_to? on the object. + + it "should not raise an exception for Object" do + obj = Object.new + obj.should_receive(:respond_to?).with(:foobar).and_return(true) + obj.should_receive(:foobar).and_return(:baz) + obj.respond_to?(:foobar).should be_true + obj.foobar.should == :baz + end + + it "should not raise an exception for mock" do + obj = mock("obj") + obj.should_receive(:respond_to?).with(:foobar).and_return(true) + obj.should_receive(:foobar).and_return(:baz) + obj.respond_to?(:foobar).should be_true + obj.foobar.should == :baz + end + +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/mocks/bug_report_8302_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/mocks/bug_report_8302_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/mocks/bug_report_8302_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/mocks/bug_report_8302_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,26 @@ +require File.dirname(__FILE__) + '/../../spec_helper.rb' + +module Bug8302 + class Foo + def Foo.class_method(arg) + end + + def instance_bar(arg) + end + end + + describe "Bug report 8302:" do + it "class method is not restored correctly when proxied" do + Foo.should_not_receive(:class_method).with(Array.new) + Foo.rspec_verify + Foo.class_method(Array.new) + end + + it "instance method is not restored correctly when proxied" do + foo = Foo.new + foo.should_not_receive(:instance_bar).with(Array.new) + foo.rspec_verify + foo.instance_bar(Array.new) + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/mocks/failing_mock_argument_constraints_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/mocks/failing_mock_argument_constraints_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/mocks/failing_mock_argument_constraints_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/mocks/failing_mock_argument_constraints_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,115 @@ +require File.dirname(__FILE__) + '/../../spec_helper.rb' + +module Spec + module Mocks + describe "failing MockArgumentConstraints" do + before(:each) do + @mock = mock("test mock") + @reporter = Mock.new("reporter", :null_object => true) + end + + after(:each) do + @mock.rspec_reset + end + + it "should reject non boolean" do + @mock.should_receive(:random_call).with(boolean()) + lambda do + @mock.random_call("false") + end.should raise_error(MockExpectationError) + end + + it "should reject non numeric" do + @mock.should_receive(:random_call).with(an_instance_of(Numeric)) + lambda do + @mock.random_call("1") + end.should raise_error(MockExpectationError) + end + + it "should reject non string" do + @mock.should_receive(:random_call).with(an_instance_of(String)) + lambda do + @mock.random_call(123) + end.should raise_error(MockExpectationError) + end + + it "should reject goose when expecting a duck" do + @mock.should_receive(:random_call).with(duck_type(:abs, :div)) + lambda { @mock.random_call("I don't respond to :abs or :div") }.should raise_error(MockExpectationError) + end + + it "should fail if regexp does not match submitted string" do + @mock.should_receive(:random_call).with(/bcd/) + lambda { @mock.random_call("abc") }.should raise_error(MockExpectationError) + end + + it "should fail if regexp does not match submitted regexp" do + @mock.should_receive(:random_call).with(/bcd/) + lambda { @mock.random_call(/bcde/) }.should raise_error(MockExpectationError) + end + + it "should fail for a hash w/ wrong values" do + @mock.should_receive(:random_call).with(:a => "b", :c => "d") + lambda do + @mock.random_call(:a => "b", :c => "e") + end.should raise_error(MockExpectationError, /Mock 'test mock' expected :random_call with \(\{(:a=>\"b\", :c=>\"d\"|:c=>\"d\", :a=>\"b\")\}\) but received it with \(\{(:a=>\"b\", :c=>\"e\"|:c=>\"e\", :a=>\"b\")\}\)/) + end + + it "should fail for a hash w/ wrong keys" do + @mock.should_receive(:random_call).with(:a => "b", :c => "d") + lambda do + @mock.random_call("a" => "b", "c" => "d") + end.should raise_error(MockExpectationError, /Mock 'test mock' expected :random_call with \(\{(:a=>\"b\", :c=>\"d\"|:c=>\"d\", :a=>\"b\")\}\) but received it with \(\{(\"a\"=>\"b\", \"c\"=>\"d\"|\"c\"=>\"d\", \"a\"=>\"b\")\}\)/) + end + + it "should match against a Matcher" do + lambda do + @mock.should_receive(:msg).with(equal(3)) + @mock.msg(37) + end.should raise_error(MockExpectationError, "Mock 'test mock' expected :msg with (equal 3) but received it with (37)") + end + + it "should fail no_args with one arg" do + lambda do + @mock.should_receive(:msg).with(no_args) + @mock.msg(37) + end.should raise_error(MockExpectationError, "Mock 'test mock' expected :msg with (no args) but received it with (37)") + end + end + + describe "failing deprecated MockArgumentConstraints" do + before(:each) do + @mock = mock("test mock") + @reporter = Mock.new("reporter", :null_object => true) + Kernel.stub!(:warn) + end + + after(:each) do + @mock.rspec_reset + end + + it "should reject non boolean" do + @mock.should_receive(:random_call).with(:boolean) + lambda do + @mock.random_call("false") + end.should raise_error(MockExpectationError) + end + + it "should reject non numeric" do + @mock.should_receive(:random_call).with(:numeric) + lambda do + @mock.random_call("1") + end.should raise_error(MockExpectationError) + end + + it "should reject non string" do + @mock.should_receive(:random_call).with(:string) + lambda do + @mock.random_call(123) + end.should raise_error(MockExpectationError) + end + + + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/mocks/mock_ordering_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/mocks/mock_ordering_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/mocks/mock_ordering_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/mocks/mock_ordering_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,84 @@ +require File.dirname(__FILE__) + '/../../spec_helper' + +module Spec + module Mocks + + describe "Mock ordering" do + + before do + @mock = mock("test mock") + end + + after do + @mock.rspec_reset + end + + it "should pass two calls in order" do + @mock.should_receive(:one).ordered + @mock.should_receive(:two).ordered + @mock.one + @mock.two + @mock.rspec_verify + end + + it "should pass three calls in order" do + @mock.should_receive(:one).ordered + @mock.should_receive(:two).ordered + @mock.should_receive(:three).ordered + @mock.one + @mock.two + @mock.three + @mock.rspec_verify + end + + it "should fail if second call comes first" do + @mock.should_receive(:one).ordered + @mock.should_receive(:two).ordered + lambda do + @mock.two + end.should raise_error(MockExpectationError, "Mock 'test mock' received :two out of order") + end + + it "should fail if third call comes first" do + @mock.should_receive(:one).ordered + @mock.should_receive(:two).ordered + @mock.should_receive(:three).ordered + @mock.one + lambda do + @mock.three + end.should raise_error(MockExpectationError, "Mock 'test mock' received :three out of order") + end + + it "should fail if third call comes second" do + @mock.should_receive(:one).ordered + @mock.should_receive(:two).ordered + @mock.should_receive(:three).ordered + @mock.one + lambda do + @mock.three + end.should raise_error(MockExpectationError, "Mock 'test mock' received :three out of order") + end + + it "should ignore order of non ordered calls" do + @mock.should_receive(:ignored_0) + @mock.should_receive(:ordered_1).ordered + @mock.should_receive(:ignored_1) + @mock.should_receive(:ordered_2).ordered + @mock.should_receive(:ignored_2) + @mock.should_receive(:ignored_3) + @mock.should_receive(:ordered_3).ordered + @mock.should_receive(:ignored_4) + @mock.ignored_3 + @mock.ordered_1 + @mock.ignored_0 + @mock.ordered_2 + @mock.ignored_4 + @mock.ignored_2 + @mock.ordered_3 + @mock.ignored_1 + @mock.rspec_verify + end + + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/mocks/mock_space_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/mocks/mock_space_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/mocks/mock_space_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/mocks/mock_space_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,54 @@ +require File.dirname(__FILE__) + '/../../spec_helper.rb' +require 'spec/mocks' + +module Spec + module Mocks + describe Space do + before :each do + @space = Space.new + klazz = Class.new do + def rspec_verify + @verified = true + end + def verified? + @verified + end + def rspec_reset + @reset = true + end + def reset? + @reset + end + end + @m1 = klazz.new + @m2 = klazz.new + end + it "should verify all mocks within" do + @space.add(@m1) + @space.add(@m2) + @space.verify_all + @m1.should be_verified + @m2.should be_verified + end + it "should reset all mocks within" do + @space.add(m1 = mock("mock1")) + @space.add(m2 = mock("mock2")) + m1.should_receive(:rspec_reset) + m2.should_receive(:rspec_reset) + @space.reset_all + end + it "should clear internal mocks on reset_all" do + @space.add(m = mock("mock")) + @space.reset_all + @space.instance_eval { mocks.empty? }.should be_true + end + it "should only add an instance once" do + @space.add(m1 = mock("mock1")) + @space.add(m1) + m1.should_receive(:rspec_verify) + @space.verify_all + end + end + end +end + diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/mocks/mock_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/mocks/mock_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/mocks/mock_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/mocks/mock_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,451 @@ +require File.dirname(__FILE__) + '/../../spec_helper' + +module Spec + module Mocks + describe "a Mock expectation" do + + before(:each) do + @mock = mock("test mock") + end + + after(:each) do + @mock.rspec_reset + end + + it "should report line number of expectation of unreceived message" do + expected_error_line = __LINE__; @mock.should_receive(:wont_happen).with("x", 3) + begin + @mock.rspec_verify + violated + rescue MockExpectationError => e + # NOTE - this regexp ended w/ $, but jruby adds extra info at the end of the line + e.backtrace[0].should match(/#{File.basename(__FILE__)}:#{expected_error_line}/) + end + end + + it "should pass when not receiving message specified as not to be received" do + @mock.should_not_receive(:not_expected) + @mock.rspec_verify + end + + it "should pass when receiving message specified as not to be received with different args" do + @mock.should_not_receive(:message).with("unwanted text") + @mock.should_receive(:message).with("other text") + @mock.message "other text" + @mock.rspec_verify + end + + it "should fail when receiving message specified as not to be received" do + @mock.should_not_receive(:not_expected) + @mock.not_expected + lambda { + @mock.rspec_verify + violated + }.should raise_error(MockExpectationError, "Mock 'test mock' expected :not_expected with (any args) 0 times, but received it once") + end + + it "should fail when receiving message specified as not to be received with args" do + @mock.should_not_receive(:not_expected).with("unexpected text") + @mock.not_expected("unexpected text") + lambda { + @mock.rspec_verify + violated + }.should raise_error(MockExpectationError, "Mock 'test mock' expected :not_expected with (\"unexpected text\") 0 times, but received it once") + end + + it "should pass when receiving message specified as not to be received with wrong args" do + @mock.should_not_receive(:not_expected).with("unexpected text") + @mock.not_expected "really unexpected text" + @mock.rspec_verify + end + + it "should allow block to calculate return values" do + @mock.should_receive(:something).with("a","b","c").and_return { |a,b,c| c+b+a } + @mock.something("a","b","c").should == "cba" + @mock.rspec_verify + end + + it "should allow parameter as return value" do + @mock.should_receive(:something).with("a","b","c").and_return("booh") + @mock.something("a","b","c").should == "booh" + @mock.rspec_verify + end + + it "should return nil if no return value set" do + @mock.should_receive(:something).with("a","b","c") + @mock.something("a","b","c").should be_nil + @mock.rspec_verify + end + + it "should raise exception if args dont match when method called" do + @mock.should_receive(:something).with("a","b","c").and_return("booh") + lambda { + @mock.something("a","d","c") + violated + }.should raise_error(MockExpectationError, "Mock 'test mock' expected :something with (\"a\", \"b\", \"c\") but received it with (\"a\", \"d\", \"c\")") + end + + it "should fail if unexpected method called" do + lambda { + @mock.something("a","b","c") + violated + }.should raise_error(MockExpectationError, "Mock 'test mock' received unexpected message :something with (\"a\", \"b\", \"c\")") + end + + it "should use block for expectation if provided" do + @mock.should_receive(:something) do | a, b | + a.should == "a" + b.should == "b" + "booh" + end + @mock.something("a", "b").should == "booh" + @mock.rspec_verify + end + + it "should fail if expectation block fails" do + @mock.should_receive(:something) {| bool | bool.should be_true} + lambda { + @mock.something false + }.should raise_error(MockExpectationError, /Mock 'test mock' received :something but passed block failed with: expected true, got false/) + end + + it "should fail right away when method defined as never is received" do + pending "Used to pass (false positive). Which one is wrong, the spec or the actual behavior?" + + @mock.should_receive(:not_expected).never + lambda { + @mock.not_expected + }.should raise_error(MockExpectationError, "Mock 'test mock' expected :not_expected 0 times, but received it 1 times") + end + + it "should eventually fail when method defined as never is received" do + @mock.should_receive(:not_expected).never + @mock.not_expected + + lambda { + @mock.rspec_verify + }.should raise_error(MockExpectationError, "Mock 'test mock' expected :not_expected with (any args) 0 times, but received it once") + end + + it "should raise when told to" do + @mock.should_receive(:something).and_raise(RuntimeError) + lambda do + @mock.something + end.should raise_error(RuntimeError) + end + + it "should raise passed an Exception instance" do + error = RuntimeError.new("error message") + @mock.should_receive(:something).and_raise(error) + lambda { + @mock.something + }.should raise_error(RuntimeError, "error message") + end + + it "should raise RuntimeError with passed message" do + @mock.should_receive(:something).and_raise("error message") + lambda { + @mock.something + }.should raise_error(RuntimeError, "error message") + end + + it "should not raise when told to if args dont match" do + @mock.should_receive(:something).with(2).and_raise(RuntimeError) + lambda { + @mock.something 1 + }.should raise_error(MockExpectationError) + end + + it "should throw when told to" do + @mock.should_receive(:something).and_throw(:blech) + lambda { + @mock.something + }.should throw_symbol(:blech) + end + + it "should raise when explicit return and block constrained" do + lambda { + @mock.should_receive(:fruit) do |colour| + :strawberry + end.and_return :apple + }.should raise_error(AmbiguousReturnError) + end + + it "should ignore args on any args" do + @mock.should_receive(:something).at_least(:once).with(any_args) + @mock.something + @mock.something 1 + @mock.something "a", 2 + @mock.something [], {}, "joe", 7 + @mock.rspec_verify + end + + it "should fail on no args if any args received" do + @mock.should_receive(:something).with(no_args()) + lambda { + @mock.something 1 + }.should raise_error(MockExpectationError, "Mock 'test mock' expected :something with (no args) but received it with (1)") + end + + it "should fail when args are expected but none are received" do + @mock.should_receive(:something).with(1) + lambda { + @mock.something + }.should raise_error(MockExpectationError, "Mock 'test mock' expected :something with (1) but received it with (no args)") + end + + it "should yield 0 args to blocks that take a variable number of arguments" do + @mock.should_receive(:yield_back).with(no_args()).once.and_yield + a = nil + @mock.yield_back {|*a|} + a.should == [] + @mock.rspec_verify + end + + it "should yield 0 args multiple times to blocks that take a variable number of arguments" do + @mock.should_receive(:yield_back).once.with(no_args()).once.and_yield. + and_yield + a = nil + b = [] + @mock.yield_back {|*a| b << a} + b.should == [ [], [] ] + @mock.rspec_verify + end + + it "should yield one arg to blocks that take a variable number of arguments" do + @mock.should_receive(:yield_back).with(no_args()).once.and_yield(99) + a = nil + @mock.yield_back {|*a|} + a.should == [99] + @mock.rspec_verify + end + + it "should yield one arg 3 times consecutively to blocks that take a variable number of arguments" do + @mock.should_receive(:yield_back).once.with(no_args()).once.and_yield(99). + and_yield(43). + and_yield("something fruity") + a = nil + b = [] + @mock.yield_back {|*a| b << a} + b.should == [[99], [43], ["something fruity"]] + @mock.rspec_verify + end + + it "should yield many args to blocks that take a variable number of arguments" do + @mock.should_receive(:yield_back).with(no_args()).once.and_yield(99, 27, "go") + a = nil + @mock.yield_back {|*a|} + a.should == [99, 27, "go"] + @mock.rspec_verify + end + + it "should yield many args 3 times consecutively to blocks that take a variable number of arguments" do + @mock.should_receive(:yield_back).once.with(no_args()).once.and_yield(99, :green, "go"). + and_yield("wait", :amber). + and_yield("stop", 12, :red) + a = nil + b = [] + @mock.yield_back {|*a| b << a} + b.should == [[99, :green, "go"], ["wait", :amber], ["stop", 12, :red]] + @mock.rspec_verify + end + + it "should yield single value" do + @mock.should_receive(:yield_back).with(no_args()).once.and_yield(99) + a = nil + @mock.yield_back {|a|} + a.should == 99 + @mock.rspec_verify + end + + it "should yield single value 3 times consecutively" do + @mock.should_receive(:yield_back).once.with(no_args()).once.and_yield(99). + and_yield(43). + and_yield("something fruity") + a = nil + b = [] + @mock.yield_back {|a| b << a} + b.should == [99, 43, "something fruity"] + @mock.rspec_verify + end + + it "should yield two values" do + @mock.should_receive(:yield_back).with(no_args()).once.and_yield('wha', 'zup') + a, b = nil + @mock.yield_back {|a,b|} + a.should == 'wha' + b.should == 'zup' + @mock.rspec_verify + end + + it "should yield two values 3 times consecutively" do + @mock.should_receive(:yield_back).once.with(no_args()).once.and_yield('wha', 'zup'). + and_yield('not', 'down'). + and_yield(14, 65) + a, b = nil + c = [] + @mock.yield_back {|a,b| c << [a, b]} + c.should == [['wha', 'zup'], ['not', 'down'], [14, 65]] + @mock.rspec_verify + end + + it "should fail when calling yielding method with wrong arity" do + @mock.should_receive(:yield_back).with(no_args()).once.and_yield('wha', 'zup') + lambda { + @mock.yield_back {|a|} + }.should raise_error(MockExpectationError, "Mock 'test mock' yielded |\"wha\", \"zup\"| to block with arity of 1") + end + + it "should fail when calling yielding method consecutively with wrong arity" do + @mock.should_receive(:yield_back).once.with(no_args()).once.and_yield('wha', 'zup'). + and_yield('down'). + and_yield(14, 65) + lambda { + a, b = nil + c = [] + @mock.yield_back {|a,b| c << [a, b]} + }.should raise_error(MockExpectationError, "Mock 'test mock' yielded |\"down\"| to block with arity of 2") + end + + it "should fail when calling yielding method without block" do + @mock.should_receive(:yield_back).with(no_args()).once.and_yield('wha', 'zup') + lambda { + @mock.yield_back + }.should raise_error(MockExpectationError, "Mock 'test mock' asked to yield |[\"wha\", \"zup\"]| but no block was passed") + end + + it "should be able to mock send" do + @mock.should_receive(:send).with(any_args) + @mock.send 'hi' + @mock.rspec_verify + end + + it "should be able to raise from method calling yielding mock" do + @mock.should_receive(:yield_me).and_yield 44 + + lambda { + @mock.yield_me do |x| + raise "Bang" + end + }.should raise_error(StandardError, "Bang") + + @mock.rspec_verify + end + + it "should clear expectations after verify" do + @mock.should_receive(:foobar) + @mock.foobar + @mock.rspec_verify + lambda { + @mock.foobar + }.should raise_error(MockExpectationError, "Mock 'test mock' received unexpected message :foobar with (no args)") + end + + it "should restore objects to their original state on rspec_reset" do + mock = mock("this is a mock") + mock.should_receive(:blah) + mock.rspec_reset + mock.rspec_verify #should throw if reset didn't work + end + + it "should work even after method_missing starts raising NameErrors instead of NoMethodErrors" do + # Object#method_missing throws either NameErrors or NoMethodErrors. + # + # On a fresh ruby program Object#method_missing: + # * raises a NoMethodError when called directly + # * raises a NameError when called indirectly + # + # Once Object#method_missing has been called at least once (on any object) + # it starts behaving differently: + # * raises a NameError when called directly + # * raises a NameError when called indirectly + # + # There was a bug in Mock#method_missing that relied on the fact + # that calling Object#method_missing directly raises a NoMethodError. + # This example tests that the bug doesn't exist anymore. + + + # Ensures that method_missing always raises NameErrors. + a_method_that_doesnt_exist rescue + + + @mock.should_receive(:foobar) + @mock.foobar + @mock.rspec_verify + + lambda { @mock.foobar }.should_not raise_error(NameError) + lambda { @mock.foobar }.should raise_error(MockExpectationError) + end + end + + describe "a mock message receiving a block" do + before(:each) do + @mock = mock("mock") + @calls = 0 + end + + def add_call + @calls = @calls + 1 + end + + it "should call the block after #should_receive" do + @mock.should_receive(:foo) { add_call } + + @mock.foo + + @calls.should == 1 + end + + it "should call the block after #once" do + @mock.should_receive(:foo).once { add_call } + + @mock.foo + + @calls.should == 1 + end + + it "should call the block after #twice" do + @mock.should_receive(:foo).twice { add_call } + + @mock.foo + @mock.foo + + @calls.should == 2 + end + + it "should call the block after #times" do + @mock.should_receive(:foo).exactly(10).times { add_call } + + (1..10).each { @mock.foo } + + @calls.should == 10 + end + + it "should call the block after #any_number_of_times" do + @mock.should_receive(:foo).any_number_of_times { add_call } + + (1..7).each { @mock.foo } + + @calls.should == 7 + end + + it "should call the block after #with" do + @mock.should_receive(:foo).with(:arg) { add_call } + + @mock.foo(:arg) + + @calls.should == 1 + end + + it "should call the block after #ordered" do + @mock.should_receive(:foo).ordered { add_call } + @mock.should_receive(:bar).ordered { add_call } + + @mock.foo + @mock.bar + + @calls.should == 2 + end + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/mocks/multiple_return_value_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/mocks/multiple_return_value_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/mocks/multiple_return_value_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/mocks/multiple_return_value_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,113 @@ +require File.dirname(__FILE__) + '/../../spec_helper' + +module Spec + module Mocks + describe "a Mock expectation with multiple return values and no specified count" do + before(:each) do + @mock = Mock.new("mock") + @return_values = ["1",2,Object.new] + @mock.should_receive(:message).and_return(@return_values[0],@return_values[1],@return_values[2]) + end + + it "should return values in order to consecutive calls" do + @mock.message.should == @return_values[0] + @mock.message.should == @return_values[1] + @mock.message.should == @return_values[2] + @mock.rspec_verify + end + + it "should complain when there are too few calls" do + third = Object.new + @mock.message.should == @return_values[0] + @mock.message.should == @return_values[1] + lambda { @mock.rspec_verify }.should raise_error(MockExpectationError, "Mock 'mock' expected :message with (any args) 3 times, but received it twice") + end + + it "should complain when there are too many calls" do + third = Object.new + @mock.message.should == @return_values[0] + @mock.message.should == @return_values[1] + @mock.message.should == @return_values[2] + @mock.message.should == @return_values[2] + lambda { @mock.rspec_verify }.should raise_error(MockExpectationError, "Mock 'mock' expected :message with (any args) 3 times, but received it 4 times") + end + end + + describe "a Mock expectation with multiple return values with a specified count equal to the number of values" do + before(:each) do + @mock = Mock.new("mock") + @return_values = ["1",2,Object.new] + @mock.should_receive(:message).exactly(3).times.and_return(@return_values[0],@return_values[1],@return_values[2]) + end + + it "should return values in order to consecutive calls" do + @mock.message.should == @return_values[0] + @mock.message.should == @return_values[1] + @mock.message.should == @return_values[2] + @mock.rspec_verify + end + + it "should complain when there are too few calls" do + third = Object.new + @mock.message.should == @return_values[0] + @mock.message.should == @return_values[1] + lambda { @mock.rspec_verify }.should raise_error(MockExpectationError, "Mock 'mock' expected :message with (any args) 3 times, but received it twice") + end + + it "should complain when there are too many calls" do + third = Object.new + @mock.message.should == @return_values[0] + @mock.message.should == @return_values[1] + @mock.message.should == @return_values[2] + @mock.message.should == @return_values[2] + lambda { @mock.rspec_verify }.should raise_error(MockExpectationError, "Mock 'mock' expected :message with (any args) 3 times, but received it 4 times") + end + end + + describe "a Mock expectation with multiple return values specifying at_least less than the number of values" do + before(:each) do + @mock = Mock.new("mock") + @mock.should_receive(:message).at_least(:twice).with(no_args).and_return(11, 22) + end + + it "should use last return value for subsequent calls" do + @mock.message.should equal(11) + @mock.message.should equal(22) + @mock.message.should equal(22) + @mock.rspec_verify + end + + it "should fail when called less than the specified number" do + @mock.message.should equal(11) + lambda { @mock.rspec_verify }.should raise_error(MockExpectationError, "Mock 'mock' expected :message with (no args) twice, but received it once") + end + end + describe "a Mock expectation with multiple return values with a specified count larger than the number of values" do + before(:each) do + @mock = Mock.new("mock") + @mock.should_receive(:message).exactly(3).times.and_return(11, 22) + end + + it "should use last return value for subsequent calls" do + @mock.message.should equal(11) + @mock.message.should equal(22) + @mock.message.should equal(22) + @mock.rspec_verify + end + + it "should fail when called less than the specified number" do + @mock.message.should equal(11) + lambda { @mock.rspec_verify }.should raise_error(MockExpectationError, "Mock 'mock' expected :message with (any args) 3 times, but received it once") + end + + it "should fail when called greater than the specified number" do + @mock.message.should equal(11) + @mock.message.should equal(22) + @mock.message.should equal(22) + @mock.message.should equal(22) + lambda { @mock.rspec_verify }.should raise_error(MockExpectationError, "Mock 'mock' expected :message with (any args) 3 times, but received it 4 times") + end + end + end +end + diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/mocks/null_object_mock_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/mocks/null_object_mock_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/mocks/null_object_mock_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/mocks/null_object_mock_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,40 @@ +require File.dirname(__FILE__) + '/../../spec_helper.rb' + +module Spec + module Mocks + describe "a mock acting as a NullObject" do + before(:each) do + @mock = Mock.new("null_object", :null_object => true) + end + + it "should allow explicit expectation" do + @mock.should_receive(:something) + @mock.something + end + + it "should fail verification when explicit exception not met" do + lambda do + @mock.should_receive(:something) + @mock.rspec_verify + end.should raise_error(MockExpectationError) + end + + it "should ignore unexpected methods" do + @mock.random_call("a", "d", "c") + @mock.rspec_verify + end + + it "should expected message with different args first" do + @mock.should_receive(:message).with(:expected_arg) + @mock.message(:unexpected_arg) + @mock.message(:expected_arg) + end + + it "should expected message with different args second" do + @mock.should_receive(:message).with(:expected_arg) + @mock.message(:expected_arg) + @mock.message(:unexpected_arg) + end + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/mocks/once_counts_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/mocks/once_counts_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/mocks/once_counts_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/mocks/once_counts_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,53 @@ +require File.dirname(__FILE__) + '/../../spec_helper.rb' + +module Spec + module Mocks + describe "OnceCounts" do + before(:each) do + @mock = mock("test mock") + end + + it "once should fail when called once with wrong args" do + @mock.should_receive(:random_call).once.with("a", "b", "c") + lambda do + @mock.random_call("d", "e", "f") + end.should raise_error(MockExpectationError) + @mock.rspec_reset + end + + it "once should fail when called twice" do + @mock.should_receive(:random_call).once + @mock.random_call + @mock.random_call + lambda do + @mock.rspec_verify + end.should raise_error(MockExpectationError) + end + + it "once should fail when not called" do + @mock.should_receive(:random_call).once + lambda do + @mock.rspec_verify + end.should raise_error(MockExpectationError) + end + + it "once should pass when called once" do + @mock.should_receive(:random_call).once + @mock.random_call + @mock.rspec_verify + end + + it "once should pass when called once with specified args" do + @mock.should_receive(:random_call).once.with("a", "b", "c") + @mock.random_call("a", "b", "c") + @mock.rspec_verify + end + + it "once should pass when called once with unspecified args" do + @mock.should_receive(:random_call).once + @mock.random_call("a", "b", "c") + @mock.rspec_verify + end + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/mocks/options_hash_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/mocks/options_hash_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/mocks/options_hash_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/mocks/options_hash_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,42 @@ +require File.dirname(__FILE__) + '/../../spec_helper.rb' + +module Spec + module Mocks + describe "calling :should_receive with an options hash" do + before do + @options = ::Spec::Runner::Options.new(StringIO.new, StringIO.new) + @reporter = ::Spec::Runner::Reporter.new(@options) + @behaviour = Class.new(::Spec::Example::ExampleGroup).describe("Some Examples") + end + + it "should report the file and line submitted with :expected_from" do + example_definition = @behaviour.it "spec" do + mock = Spec::Mocks::Mock.new("a mock") + mock.should_receive(:message, :expected_from => "/path/to/blah.ext:37") + mock.rspec_verify + end + example = @behaviour.new(example_definition) + proxy = ::Spec::Example::ExampleRunner.new(@options, example) + + @reporter.should_receive(:example_finished) do |spec, error| + error.backtrace.detect {|line| line =~ /\/path\/to\/blah.ext:37/}.should_not be_nil + end + proxy.run + end + + it "should use the message supplied with :message" do + example_definition = @behaviour.it "spec" do + mock = Spec::Mocks::Mock.new("a mock") + mock.should_receive(:message, :message => "recebi nada") + mock.rspec_verify + end + example = @behaviour.new(example_definition) + proxy = ::Spec::Example::ExampleRunner.new(@options, example) + @reporter.should_receive(:example_finished) do |spec, error| + error.message.should == "recebi nada" + end + proxy.run + end + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/mocks/partial_mock_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/mocks/partial_mock_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/mocks/partial_mock_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/mocks/partial_mock_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,106 @@ +require File.dirname(__FILE__) + '/../../spec_helper.rb' + +module Spec + module Mocks + describe "using a Partial Mock," do + before(:each) do + @object = Object.new + end + + it "should name the class in the failure message" do + @object.should_receive(:foo) + lambda do + @object.rspec_verify + end.should raise_error(Spec::Mocks::MockExpectationError, /Object/) + end + + it "should not conflict with @options in the object" do + @object.instance_eval { @options = Object.new } + @object.should_receive(:blah) + @object.blah + end + + it "should_not_receive should mock out the method" do + @object.should_not_receive(:fuhbar) + @object.fuhbar + lambda do + @object.rspec_verify + end.should raise_error(Spec::Mocks::MockExpectationError) + end + + it "should_not_receive should return a negative message expectation" do + @object.should_not_receive(:foobar).should be_kind_of(NegativeMessageExpectation) + end + + it "should_receive should mock out the method" do + @object.should_receive(:foobar).with(:test_param).and_return(1) + @object.foobar(:test_param).should equal(1) + end + + it "should_receive should handle a hash" do + @object.should_receive(:foobar).with(:key => "value").and_return(1) + @object.foobar(:key => "value").should equal(1) + end + + it "should_receive should handle an inner hash" do + hash = {:a => {:key => "value"}} + @object.should_receive(:foobar).with(:key => "value").and_return(1) + @object.foobar(hash[:a]).should equal(1) + end + + it "should_receive should return a message expectation" do + @object.should_receive(:foobar).should be_kind_of(MessageExpectation) + @object.foobar + end + + it "should_receive should verify method was called" do + @object.should_receive(:foobar).with(:test_param).and_return(1) + lambda do + @object.rspec_verify + end.should raise_error(Spec::Mocks::MockExpectationError) + end + + it "should_receive should also take a String argument" do + @object.should_receive('foobar') + @object.foobar + end + + it "should_not_receive should also take a String argument" do + @object.should_not_receive('foobar') + @object.foobar + lambda do + @object.rspec_verify + end.should raise_error(Spec::Mocks::MockExpectationError) + end + + it "should use report nil in the error message" do + @this_will_resolve_to_nil.should_receive(:foobar) + lambda do + @this_will_resolve_to_nil.rspec_verify + end.should raise_error(Spec::Mocks::MockExpectationError, /NilClass.*expected :foobar with/) + end + end + + describe "Partially mocking an object that defines ==, after another mock has been defined" do + before(:each) do + stub("existing mock", :foo => :foo) + end + + class PartiallyMockedEquals + attr_reader :val + def initialize(val) + @val = val + end + + def ==(other) + @val == other.val + end + end + + it "should not raise an error when stubbing the object" do + o = PartiallyMockedEquals.new :foo + lambda { o.stub!(:bar) }.should_not raise_error(NoMethodError) + end + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/mocks/partial_mock_using_mocks_directly_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/mocks/partial_mock_using_mocks_directly_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/mocks/partial_mock_using_mocks_directly_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/mocks/partial_mock_using_mocks_directly_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,66 @@ +require File.dirname(__FILE__) + '/../../spec_helper.rb' + +module Spec +module Mocks +describe "PartialMockUsingMocksDirectly" do + before(:each) do + + klass=Class.new + klass.class_eval do + def existing_method + :original_value + end + end + @obj = klass.new + + end + + # See http://rubyforge.org/tracker/index.php?func=detail&aid=10263&group_id=797&atid=3149 + # specify "should clear expectations on verify" do + # @obj.should_receive(:msg) + # @obj.msg + # @obj.rspec_verify + # lambda do + # @obj.msg + # end.should raise_error(NoMethodError) + # + # end + it "should fail when expected message is not received" do + @obj.should_receive(:msg) + lambda do + @obj.rspec_verify + end.should raise_error(MockExpectationError) + + end + it "should fail when message is received with incorrect args" do + @obj.should_receive(:msg).with(:correct_arg) + lambda do + @obj.msg(:incorrect_arg) + end.should raise_error(MockExpectationError) + @obj.msg(:correct_arg) + + end + it "should pass when expected message is received" do + @obj.should_receive(:msg) + @obj.msg + @obj.rspec_verify + + end + it "should pass when message is received with correct args" do + @obj.should_receive(:msg).with(:correct_arg) + @obj.msg(:correct_arg) + @obj.rspec_verify + + end + it "should revert to original method if existed" do + @obj.existing_method.should equal(:original_value) + @obj.should_receive(:existing_method).and_return(:mock_value) + @obj.existing_method.should equal(:mock_value) + @obj.rspec_verify + @obj.existing_method.should equal(:original_value) + + end + +end +end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/mocks/passing_mock_argument_constraints_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/mocks/passing_mock_argument_constraints_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/mocks/passing_mock_argument_constraints_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/mocks/passing_mock_argument_constraints_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,154 @@ +require File.dirname(__FILE__) + '/../../spec_helper.rb' + +module Spec + module Mocks + describe "mock argument constraints", :shared => true do + before(:each) do + @mock = Mock.new("test mock") + Kernel.stub!(:warn) + end + + after(:each) do + @mock.rspec_verify + end + end + + describe Methods, "handling argument constraints with DEPRECATED symbols" do + it_should_behave_like "mock argument constraints" + + it "should accept true as boolean" do + @mock.should_receive(:random_call).with(:boolean) + @mock.random_call(true) + end + + it "should accept false as boolean" do + @mock.should_receive(:random_call).with(:boolean) + @mock.random_call(false) + end + + it "should accept fixnum as numeric" do + @mock.should_receive(:random_call).with(:numeric) + @mock.random_call(1) + end + + it "should accept float as numeric" do + @mock.should_receive(:random_call).with(:numeric) + @mock.random_call(1.5) + end + + it "should accept string as anything" do + @mock.should_receive(:random_call).with("a", :anything, "c") + @mock.random_call("a", "whatever", "c") + end + + it "should match string" do + @mock.should_receive(:random_call).with(:string) + @mock.random_call("a string") + end + + it "should match no args against any_args" do + @mock.should_receive(:random_call).with(:any_args) + @mock.random_call("a string") + end + + it "should match no args against no_args" do + @mock.should_receive(:random_call).with(:no_args) + @mock.random_call + end + end + + describe Methods, "handling argument constraints" do + it_should_behave_like "mock argument constraints" + + it "should accept true as boolean()" do + @mock.should_receive(:random_call).with(boolean()) + @mock.random_call(true) + end + + it "should accept false as boolean()" do + @mock.should_receive(:random_call).with(boolean()) + @mock.random_call(false) + end + + it "should accept fixnum as an_instance_of(Numeric)" do + @mock.should_receive(:random_call).with(an_instance_of(Numeric)) + @mock.random_call(1) + end + + it "should accept float as an_instance_of(Numeric)" do + @mock.should_receive(:random_call).with(an_instance_of(Numeric)) + @mock.random_call(1.5) + end + + it "should accept string as anything()" do + @mock.should_receive(:random_call).with("a", anything(), "c") + @mock.random_call("a", "whatever", "c") + end + + it "should match duck type with one method" do + @mock.should_receive(:random_call).with(duck_type(:length)) + @mock.random_call([]) + end + + it "should match duck type with two methods" do + @mock.should_receive(:random_call).with(duck_type(:abs, :div)) + @mock.random_call(1) + end + + it "should match no args against any_args()" do + @mock.should_receive(:random_call).with(any_args) + @mock.random_call() + end + + it "should match one arg against any_args()" do + @mock.should_receive(:random_call).with(any_args) + @mock.random_call("a string") + end + + it "should match no args against no_args()" do + @mock.should_receive(:random_call).with(no_args) + @mock.random_call() + end + end + + describe Methods, "handling non-constraint arguments" do + + it "should match non special symbol (can be removed when deprecated symbols are removed)" do + @mock.should_receive(:random_call).with(:some_symbol) + @mock.random_call(:some_symbol) + end + + it "should match string against regexp" do + @mock.should_receive(:random_call).with(/bcd/) + @mock.random_call("abcde") + end + + it "should match regexp against regexp" do + @mock.should_receive(:random_call).with(/bcd/) + @mock.random_call(/bcd/) + end + + it "should match against a hash submitted and received by value" do + @mock.should_receive(:random_call).with(:a => "a", :b => "b") + @mock.random_call(:a => "a", :b => "b") + end + + it "should match against a hash submitted by reference and received by value" do + opts = {:a => "a", :b => "b"} + @mock.should_receive(:random_call).with(opts) + @mock.random_call(:a => "a", :b => "b") + end + + it "should match against a hash submitted by value and received by reference" do + opts = {:a => "a", :b => "b"} + @mock.should_receive(:random_call).with(:a => "a", :b => "b") + @mock.random_call(opts) + end + + it "should match against a Matcher" do + @mock.should_receive(:msg).with(equal(37)) + @mock.msg(37) + end + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/mocks/precise_counts_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/mocks/precise_counts_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/mocks/precise_counts_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/mocks/precise_counts_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,52 @@ +require File.dirname(__FILE__) + '/../../spec_helper.rb' + +module Spec + module Mocks + describe "PreciseCounts" do + before(:each) do + @mock = mock("test mock") + end + + it "should fail when exactly n times method is called less than n times" do + @mock.should_receive(:random_call).exactly(3).times + @mock.random_call + @mock.random_call + lambda do + @mock.rspec_verify + end.should raise_error(MockExpectationError) + end + + it "should fail when exactly n times method is never called" do + @mock.should_receive(:random_call).exactly(3).times + lambda do + @mock.rspec_verify + end.should raise_error(MockExpectationError) + end + + it "should pass if exactly n times method is called exactly n times" do + @mock.should_receive(:random_call).exactly(3).times + @mock.random_call + @mock.random_call + @mock.random_call + @mock.rspec_verify + end + + it "should pass multiple calls with different args and counts" do + @mock.should_receive(:random_call).twice.with(1) + @mock.should_receive(:random_call).once.with(2) + @mock.random_call(1) + @mock.random_call(2) + @mock.random_call(1) + @mock.rspec_verify + end + + it "should pass mutiple calls with different args" do + @mock.should_receive(:random_call).once.with(1) + @mock.should_receive(:random_call).once.with(2) + @mock.random_call(1) + @mock.random_call(2) + @mock.rspec_verify + end + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/mocks/record_messages_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/mocks/record_messages_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/mocks/record_messages_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/mocks/record_messages_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,26 @@ +require File.dirname(__FILE__) + '/../../spec_helper' + +module Spec + module Mocks + describe "a mock" do + before(:each) do + @mock = mock("mock", :null_object => true) + end + it "should answer false for received_message? when no messages received" do + @mock.received_message?(:message).should be_false + end + it "should answer true for received_message? when message received" do + @mock.message + @mock.received_message?(:message).should be_true + end + it "should answer true for received_message? when message received with correct args" do + @mock.message 1,2,3 + @mock.received_message?(:message, 1,2,3).should be_true + end + it "should answer false for received_message? when message received with incorrect args" do + @mock.message 1,2,3 + @mock.received_message?(:message, 1,2).should be_false + end + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/mocks/stub_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/mocks/stub_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/mocks/stub_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/mocks/stub_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,189 @@ +require File.dirname(__FILE__) + '/../../spec_helper.rb' + +module Spec + module Mocks + describe "A method stub" do + before(:each) do + @class = Class.new do + def self.existing_class_method + :original_value + end + + def existing_instance_method + :original_value + end + end + @obj = @class.new + end + + it "should allow for a mock expectation to temporarily replace a method stub on a mock" do + mock = Spec::Mocks::Mock.new("a mock") + mock.stub!(:msg).and_return(:stub_value) + mock.should_receive(:msg).with(:arg).and_return(:mock_value) + mock.msg(:arg).should equal(:mock_value) + mock.msg.should equal(:stub_value) + mock.msg.should equal(:stub_value) + mock.rspec_verify + end + + it "should allow for a mock expectation to temporarily replace a method stub on a non-mock" do + @obj.stub!(:msg).and_return(:stub_value) + @obj.should_receive(:msg).with(:arg).and_return(:mock_value) + @obj.msg(:arg).should equal(:mock_value) + @obj.msg.should equal(:stub_value) + @obj.msg.should equal(:stub_value) + @obj.rspec_verify + end + + it "should ignore when expected message is not received" do + @obj.stub!(:msg) + lambda do + @obj.rspec_verify + end.should_not raise_error + end + + it "should clear itself on rspec_verify" do + @obj.stub!(:this_should_go).and_return(:blah) + @obj.this_should_go.should == :blah + @obj.rspec_verify + lambda do + @obj.this_should_go + end.should raise_error + end + + it "should ignore when expected message is received" do + @obj.stub!(:msg) + @obj.msg + @obj.rspec_verify + end + + it "should ignore when message is received with args" do + @obj.stub!(:msg) + @obj.msg(:an_arg) + @obj.rspec_verify + end + + it "should return expected value when expected message is received" do + @obj.stub!(:msg).and_return(:return_value) + @obj.msg.should equal(:return_value) + @obj.rspec_verify + end + + it "should return values in order to consecutive calls" do + return_values = ["1",2,Object.new] + @obj.stub!(:msg).and_return(return_values[0],return_values[1],return_values[2]) + @obj.msg.should == return_values[0] + @obj.msg.should == return_values[1] + @obj.msg.should == return_values[2] + end + + it "should keep returning last value in consecutive calls" do + return_values = ["1",2,Object.new] + @obj.stub!(:msg).and_return(return_values[0],return_values[1],return_values[2]) + @obj.msg.should == return_values[0] + @obj.msg.should == return_values[1] + @obj.msg.should == return_values[2] + @obj.msg.should == return_values[2] + @obj.msg.should == return_values[2] + end + + it "should revert to original instance method if existed" do + @obj.existing_instance_method.should equal(:original_value) + @obj.stub!(:existing_instance_method).and_return(:mock_value) + @obj.existing_instance_method.should equal(:mock_value) + @obj.rspec_verify + @obj.existing_instance_method.should equal(:original_value) + end + + it "should revert to original class method if existed" do + @class.existing_class_method.should equal(:original_value) + @class.stub!(:existing_class_method).and_return(:mock_value) + @class.existing_class_method.should equal(:mock_value) + @class.rspec_verify + @class.existing_class_method.should equal(:original_value) + end + + it "should support yielding" do + @obj.stub!(:method_that_yields).and_yield(:yielded_value) + current_value = :value_before + @obj.method_that_yields {|val| current_value = val} + current_value.should == :yielded_value + @obj.rspec_verify + end + + it "should support yielding multiple times" do + @obj.stub!(:method_that_yields_multiple_times).and_yield(:yielded_value). + and_yield(:another_value) + current_value = [] + @obj.method_that_yields_multiple_times {|val| current_value << val} + current_value.should == [:yielded_value, :another_value] + @obj.rspec_verify + end + + it "should throw when told to" do + @mock.stub!(:something).and_throw(:blech) + lambda do + @mock.something + end.should throw_symbol(:blech) + end + + it "should support overriding w/ a new stub" do + @stub.stub!(:existing_instance_method).and_return(:updated_stub_value) + @stub.existing_instance_method.should == :updated_stub_value + end + + it "should support stub with" do + @stub.stub!(:foo).with("bar") + @stub.should_receive(:foo).with("baz") + @stub.foo("bar") + @stub.foo("baz") + end + end + + describe "A method stub with args" do + before(:each) do + @stub = Object.new + @stub.stub!(:foo).with("bar") + end + + it "should not complain if not called" do + end + + it "should not complain if called with arg" do + @stub.foo("bar") + end + + it "should complain if called with no arg" do + lambda do + @stub.foo + end.should raise_error + end + + it "should complain if called with other arg" do + lambda do + @stub.foo("other") + end.should raise_error + end + + it "should not complain if also mocked w/ different args" do + @stub.should_receive(:foo).with("baz") + @stub.foo("bar") + @stub.foo("baz") + end + + it "should complain if also mocked w/ different args AND called w/ a 3rd set of args" do + @stub.should_receive(:foo).with("baz") + @stub.foo("bar") + @stub.foo("baz") + lambda do + @stub.foo("other") + end.should raise_error + end + + it "should support options" do + @stub.stub!(:foo, :expected_from => "bar") + end + end + + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/mocks/twice_counts_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/mocks/twice_counts_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/mocks/twice_counts_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/mocks/twice_counts_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,67 @@ +require File.dirname(__FILE__) + '/../../spec_helper.rb' + +module Spec + module Mocks + describe "TwiceCounts" do + before(:each) do + @mock = mock("test mock") + end + + it "twice should fail when call count is higher than expected" do + @mock.should_receive(:random_call).twice + @mock.random_call + @mock.random_call + @mock.random_call + lambda do + @mock.rspec_verify + end.should raise_error(MockExpectationError) + end + + it "twice should fail when call count is lower than expected" do + @mock.should_receive(:random_call).twice + @mock.random_call + lambda do + @mock.rspec_verify + end.should raise_error(MockExpectationError) + end + + it "twice should fail when called twice with wrong args on the first call" do + @mock.should_receive(:random_call).twice.with("1", 1) + lambda do + @mock.random_call(1, "1") + end.should raise_error(MockExpectationError) + @mock.rspec_reset + end + + it "twice should fail when called twice with wrong args on the second call" do + @mock.should_receive(:random_call).twice.with("1", 1) + @mock.random_call("1", 1) + lambda do + @mock.random_call(1, "1") + end.should raise_error(MockExpectationError) + @mock.rspec_reset + end + + it "twice should pass when called twice" do + @mock.should_receive(:random_call).twice + @mock.random_call + @mock.random_call + @mock.rspec_verify + end + + it "twice should pass when called twice with specified args" do + @mock.should_receive(:random_call).twice.with("1", 1) + @mock.random_call("1", 1) + @mock.random_call("1", 1) + @mock.rspec_verify + end + + it "twice should pass when called twice with unspecified args" do + @mock.should_receive(:random_call).twice + @mock.random_call("1") + @mock.random_call(1) + @mock.rspec_verify + end + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/package/bin_spec_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/package/bin_spec_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/package/bin_spec_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/package/bin_spec_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,17 @@ +require "#{File.dirname(__FILE__)}/../../spec_helper" +require 'rbconfig' + +describe "The bin/spec script" do + it "should have no warnings" do + pending "Hangs on JRuby" if PLATFORM =~ /java/ + spec_path = "#{File.dirname(__FILE__)}/../../../bin/spec" + output = nil + + config = ::Config::CONFIG + ruby = File::join(config['bindir'], config['ruby_install_name']) + config['EXEEXT'] + IO.popen("#{ruby} -w #{spec_path} --help 2>&1") do |io| + output = io.read + end + output.should_not =~ /warning/n + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/runner/class_and_argument_parser_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/runner/class_and_argument_parser_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/runner/class_and_argument_parser_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/runner/class_and_argument_parser_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,23 @@ +require File.dirname(__FILE__) + '/../../spec_helper.rb' + +module Spec + module Runner + describe ClassAndArgumentsParser, ".parse" do + + it "should use a single : to separate class names from arguments" do + ClassAndArgumentsParser.parse('Foo').should == ['Foo', nil] + ClassAndArgumentsParser.parse('Foo:arg').should == ['Foo', 'arg'] + ClassAndArgumentsParser.parse('Foo::Bar::Zap:arg').should == ['Foo::Bar::Zap', 'arg'] + ClassAndArgumentsParser.parse('Foo:arg1,arg2').should == ['Foo', 'arg1,arg2'] + ClassAndArgumentsParser.parse('Foo::Bar::Zap:arg1,arg2').should == ['Foo::Bar::Zap', 'arg1,arg2'] + ClassAndArgumentsParser.parse('Foo::Bar::Zap:drb://foo,drb://bar').should == ['Foo::Bar::Zap', 'drb://foo,drb://bar'] + end + + it "should raise an error when passed an empty string" do + lambda do + ClassAndArgumentsParser.parse('') + end.should raise_error("Couldn't parse \"\"") + end + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/runner/command_line_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/runner/command_line_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/runner/command_line_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/runner/command_line_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,148 @@ +require File.dirname(__FILE__) + '/../../spec_helper.rb' + +module Spec + module Runner + describe CommandLine, ".run" do + before do + @err = StringIO.new + @out = StringIO.new + end + + it "should run directory" do + file = File.dirname(__FILE__) + '/../../../examples/pure' + Spec::Runner::CommandLine.run(OptionParser.parse([file], @err, @out)) + + @out.rewind + @out.read.should =~ /\d+ examples, 0 failures, 3 pending/n + end + + it "should run file" do + file = File.dirname(__FILE__) + '/../../../failing_examples/predicate_example.rb' + Spec::Runner::CommandLine.run(OptionParser.parse([file], @err, @out)) + + @out.rewind + @out.read.should =~ /2 examples, 1 failure/n + end + + it "should raise when file does not exist" do + file = File.dirname(__FILE__) + '/doesntexist' + + lambda { + Spec::Runner::CommandLine.run(OptionParser.parse([file], @err, @out)) + }.should raise_error + end + + it "should return true when in --generate-options mode" do + Spec::Runner::CommandLine.run( + OptionParser.parse(['--generate-options', '/dev/null'], @err, @out) + ).should be_true + end + + it "should dump even if Interrupt exception is occurred" do + behaviour = Class.new(::Spec::Example::ExampleGroup) do + describe("behaviour") + it "no error" do + end + + it "should interrupt" do + raise Interrupt + end + end + + options = ::Spec::Runner::Options.new(@err, @out) + ::Spec::Runner::Options.should_receive(:new).with(@err, @out).and_return(options) + options.reporter.should_receive(:dump) + options.add_example_group(behaviour) + + Spec::Runner::CommandLine.run(OptionParser.parse([], @err, @out)) + end + + it "should heckle when options have heckle_runner" do + behaviour = Class.new(::Spec::Example::ExampleGroup).describe("behaviour") do + it "no error" do + end + end + options = ::Spec::Runner::Options.new(@err, @out) + ::Spec::Runner::Options.should_receive(:new).with(@err, @out).and_return(options) + options.add_example_group behaviour + + heckle_runner = mock("heckle_runner") + heckle_runner.should_receive(:heckle_with) + $rspec_mocks.__send__(:mocks).delete(heckle_runner) + + options.heckle_runner = heckle_runner + options.add_example_group(behaviour) + + Spec::Runner::CommandLine.run(OptionParser.parse([], @err, @out)) + heckle_runner.rspec_verify + end + + it "should run examples backwards if options.reverse is true" do + options = ::Spec::Runner::Options.new(@err, @out) + ::Spec::Runner::Options.should_receive(:new).with(@err, @out).and_return(options) + options.reverse = true + + b1 = Class.new(Spec::Example::ExampleGroup) + b2 = Class.new(Spec::Example::ExampleGroup) + + b1_suite = b1.suite + b1.should_receive(:suite).and_return(b1_suite) + b2_suite = b2.suite + b2.should_receive(:suite).and_return(b2_suite) + + b2_suite.should_receive(:run).ordered + b1_suite.should_receive(:run).ordered + + options.add_example_group(b1) + options.add_example_group(b2) + + Spec::Runner::CommandLine.run(OptionParser.parse([], @err, @out)) + end + + it "should pass its Description to the reporter" do + behaviour = Class.new(::Spec::Example::ExampleGroup).describe("behaviour") do + it "should" do + end + end + + options = ::Spec::Runner::Options.new(@err, @out) + ::Spec::Runner::Options.should_receive(:new).with(@err, @out).and_return(options) + options.reporter.should_receive(:add_example_group).with(an_instance_of(Spec::Example::ExampleGroupDescription)) + options.add_example_group(behaviour) + Spec::Runner::CommandLine.run(OptionParser.parse([], @err, @out)) + end + + it "runs only selected Examples when options.examples is set" do + options = ::Spec::Runner::Options.new(@err, @out) + ::Spec::Runner::Options.should_receive(:new).with(@err, @out).and_return(options) + + options.examples << "behaviour should" + should_has_run = false + should_not_has_run = false + behaviour = Class.new(::Spec::Example::ExampleGroup).describe("behaviour") do + it "should" do + should_has_run = true + end + it "should not" do + should_not_has_run = true + end + end + + options.reporter.should_receive(:add_example_group).with(an_instance_of(Spec::Example::ExampleGroupDescription)) + + options.add_example_group behaviour + Spec::Runner::CommandLine.run(OptionParser.parse([], @err, @out)) + + should_has_run.should be_true + should_not_has_run.should be_false + end + + it "sets Spec.run to true" do + ::Spec.run = false + ::Spec.should_not be_run + Spec::Runner::CommandLine.run(OptionParser.parse([], @err, @out)) + ::Spec.should be_run + end + end + end +end \ No newline at end of file diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/runner/drb_command_line_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/runner/drb_command_line_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/runner/drb_command_line_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/runner/drb_command_line_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,92 @@ +require File.dirname(__FILE__) + '/../../spec_helper.rb' + +module Spec + module Runner + describe DrbCommandLine, "without running local server" do + unless Config::CONFIG['ruby_install_name'] == 'jruby' + it "should print error when there is no running local server" do + err = StringIO.new + out = StringIO.new + DrbCommandLine.run(OptionParser.parse(['--version'], err, out)) + + err.rewind + err.read.should =~ /No server is running/ + end + end + end + + class DrbCommandLineSpec < ::Spec::Example::ExampleGroup + describe DrbCommandLine, "with local server" + + class CommandLineForSpec + def self.run(argv, stderr, stdout) + exit Spec::Runner::CommandLine.run(OptionParser.parse(argv, stderr, stdout)) + end + end + + unless Config::CONFIG['ruby_install_name'] == 'jruby' + before(:all) do + DRb.start_service("druby://localhost:8989", CommandLineForSpec) + @@drb_example_file_counter = 0 + end + + before(:each) do + create_dummy_spec_file + @@drb_example_file_counter = @@drb_example_file_counter + 1 + end + + after(:each) do + File.delete(@dummy_spec_filename) + end + + after(:all) do + DRb.stop_service + end + + it "should run against local server" do + out = run_spec_via_druby(['--version']) + out.should =~ /RSpec/n + end + + it "should output green colorized text when running with --colour option" do + out = run_spec_via_druby(["--colour", @dummy_spec_filename]) + out.should =~ /\e\[32m/n + end + + it "should output red colorized text when running with -c option" do + out = run_spec_via_druby(["-c", @dummy_spec_filename]) + out.should =~ /\e\[31m/n + end + + def create_dummy_spec_file + @dummy_spec_filename = File.expand_path(File.dirname(__FILE__)) + "/_dummy_spec#{@@drb_example_file_counter}.rb" + File.open(@dummy_spec_filename, 'w') do |f| + f.write %{ + describe "DUMMY CONTEXT for 'DrbCommandLine with -c option'" do + it "should be output with green bar" do + true.should be_true + end + + it "should be output with red bar" do + violated("I want to see a red bar!") + end + end + } + end + end + + def run_spec_via_druby(argv) + err, out = StringIO.new, StringIO.new + out.instance_eval do + def tty?; true end + end + options = ::Spec::Runner::Options.new(err, out) + options.argv = argv + Spec::Runner::DrbCommandLine.run(options) + out.rewind; out.read + end + end + + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/runner/examples.txt technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/runner/examples.txt --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/runner/examples.txt 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/runner/examples.txt 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,2 @@ +Sir, if you were my husband, I would poison your drink. +Madam, if you were my wife, I would drink it. \ No newline at end of file diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/runner/execution_context_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/runner/execution_context_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/runner/execution_context_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/runner/execution_context_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,31 @@ +require File.dirname(__FILE__) + '/../../spec_helper.rb' + +describe "ExecutionContext" do + + it "should provide duck_type()" do + dt = duck_type(:length) + dt.should be_an_instance_of(Spec::Mocks::DuckTypeArgConstraint) + dt.matches?([]).should be_true + end + + it "should violate when violated()" do + lambda do + violated + end.should raise_error(Spec::Expectations::ExpectationNotMetError) + end + + it "should provide mock()" do + mock("thing").should be_an_instance_of(Spec::Mocks::Mock) + end + + it "should provide stub()" do + thing_stub = stub("thing").should be_an_instance_of(Spec::Mocks::Mock) + end + + it "should add method stubs to stub()" do + thing_stub = stub("thing", :a => "A", :b => "B") + thing_stub.a.should == "A" + thing_stub.b.should == "B" + end + +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/runner/failed.txt technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/runner/failed.txt --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/runner/failed.txt 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/runner/failed.txt 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,3 @@ +heckler_spec.rb +command_line_spec.rb +reporter_spec.rb \ No newline at end of file diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/runner/formatter/failing_behaviours_formatter_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/runner/formatter/failing_behaviours_formatter_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/runner/formatter/failing_behaviours_formatter_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/runner/formatter/failing_behaviours_formatter_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,41 @@ +require File.dirname(__FILE__) + '/../../../spec_helper' + +module Spec + module Runner + module Formatter + describe "FailingBehavioursFormatter" do + before(:each) do + @io = StringIO.new + options = mock('options') + @formatter = FailingBehavioursFormatter.new(options, @io) + end + + def description(s) + Spec::Example::ExampleGroupDescription.new(s) + end + + it "should add example name for each failure" do + @formatter.add_example_group(description("b 1")) + @formatter.example_failed("e 1", nil, Reporter::Failure.new(nil, RuntimeError.new)) + @formatter.add_example_group(description("b 2")) + @formatter.example_failed("e 2", nil, Reporter::Failure.new(nil, RuntimeError.new)) + @formatter.example_failed("e 3", nil, Reporter::Failure.new(nil, RuntimeError.new)) + @io.string.should eql(<<-EOF +b 1 +b 2 +EOF +) + end + + it "should remove druby url, which is used by Spec::Distributed" do + @formatter.add_example_group("something something (druby://99.99.99.99:99)") + @formatter.example_failed("e 1", nil, Reporter::Failure.new(nil, RuntimeError.new)) + @io.string.should eql(<<-EOF +something something +EOF +) + end + end + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/runner/formatter/failing_examples_formatter_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/runner/formatter/failing_examples_formatter_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/runner/formatter/failing_examples_formatter_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/runner/formatter/failing_examples_formatter_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,30 @@ +require File.dirname(__FILE__) + '/../../../spec_helper' + +module Spec + module Runner + module Formatter + describe "FailingExamplesFormatter" do + before(:each) do + @io = StringIO.new + options = mock('options') + @formatter = FailingExamplesFormatter.new(options, @io) + @behaviour = Class.new(::Spec::Example::ExampleGroup).describe("Some Examples") + end + + it "should add example name for each failure" do + @formatter.add_example_group("b 1") + @formatter.example_failed(@behaviour.it("e 1"), nil, Reporter::Failure.new(nil, RuntimeError.new)) + @formatter.add_example_group("b 2") + @formatter.example_failed(@behaviour.it("e 2"), nil, Reporter::Failure.new(nil, RuntimeError.new)) + @formatter.example_failed(@behaviour.it("e 3"), nil, Reporter::Failure.new(nil, RuntimeError.new)) + @io.string.should eql(<<-EOF +b 1 e 1 +b 2 e 2 +b 2 e 3 +EOF +) + end + end + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/runner/formatter/html_formatted-1.8.4.html technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/runner/formatter/html_formatted-1.8.4.html --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/runner/formatter/html_formatted-1.8.4.html 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/runner/formatter/html_formatted-1.8.4.html 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,365 @@ + + + + + RSpec results + + + + + + +
      + + + +
      +

      RSpec Results

      + +
      +

       

      +

       

      +
      +
      + +
      +
      +
      +
      Mocker
      + +
      should be able to call mock()
      + + + +
      + should fail when expected message not received +
      +
      Mock 'poke me' expected :poke with (any args) once, but received it 0 times
      +
      ./failing_examples/mocking_example.rb:13:
      +./spec/spec/runner/formatter/html_formatter_spec.rb:24:
      +./spec/spec/runner/formatter/html_formatter_spec.rb:20:
      +
      11  it "should fail when expected message not received" do
      +12    mock = mock("poke me")
      +13    mock.should_receive(:poke)
      +14  end
      +15  
      +
      +
      + +
      + should fail when messages are received out of order +
      +
      Mock 'one two three' received :three out of order
      +
      ./failing_examples/mocking_example.rb:22:
      +./spec/spec/runner/formatter/html_formatter_spec.rb:24:
      +./spec/spec/runner/formatter/html_formatter_spec.rb:20:
      +
      20    mock.should_receive(:three).ordered
      +21    mock.one
      +22    mock.three
      +23    mock.two
      +24  end
      +
      +
      + +
      + should get yelled at when sending unexpected messages +
      +
      Mock 'don't talk to me' expected :any_message_at_all with (any args) 0 times, but received it once
      +
      ./failing_examples/mocking_example.rb:28:
      +./spec/spec/runner/formatter/html_formatter_spec.rb:24:
      +./spec/spec/runner/formatter/html_formatter_spec.rb:20:
      +
      26  it "should get yelled at when sending unexpected messages" do
      +27    mock = mock("don't talk to me")
      +28    mock.should_not_receive(:any_message_at_all)
      +29    mock.any_message_at_all
      +30  end
      +
      +
      + +
      + has a bug we need to fix +
      +
      Expected pending 'here is the bug' to fail. No Error was raised.
      +
      ./failing_examples/mocking_example.rb:33:
      +./spec/spec/runner/formatter/html_formatter_spec.rb:24:
      +./spec/spec/runner/formatter/html_formatter_spec.rb:20:
      +
      31
      +32  it "has a bug we need to fix" do
      +33    pending "here is the bug" do
      +34      # Actually, no. It's fixed. This will fail because it passes :-)
      +35      mock = mock("Bug")
      +
      +
      +
      +
      +
      +
      +
      Running specs with --diff
      + + +
      + should print diff of different strings +
      +
      expected: "RSpec is a\nbehaviour driven development\nframework for Ruby\n",
      +     got: "RSpec is a\nbehavior driven development\nframework for Ruby\n" (using ==)
      +Diff:
      +@@ -1,4 +1,4 @@
      + RSpec is a
      +-behavior driven development
      ++behaviour driven development
      + framework for Ruby
      +
      +
      ./failing_examples/diffing_spec.rb:13:
      +./spec/spec/runner/formatter/html_formatter_spec.rb:24:
      +./spec/spec/runner/formatter/html_formatter_spec.rb:20:
      +
      11framework for Ruby
      +12EOF
      +13    usa.should == uk
      +14  end
      +
      +
      + +
      + should print diff of different objects' pretty representation +
      +
      expected <Animal
      +name=bob,
      +species=tortoise
      +>
      +, got <Animal
      +name=bob,
      +species=giraffe
      +>
      + (using .eql?)
      +Diff:
      +@@ -1,5 +1,5 @@
      + <Animal
      + name=bob,
      +-species=giraffe
      ++species=tortoise
      + >
      +
      +
      ./failing_examples/diffing_spec.rb:34:
      +./spec/spec/runner/formatter/html_formatter_spec.rb:24:
      +./spec/spec/runner/formatter/html_formatter_spec.rb:20:
      +
      32    expected = Animal.new "bob", "giraffe"
      +33    actual   = Animal.new "bob", "tortoise"
      +34    expected.should eql(actual)
      +35  end
      +36end
      +
      +
      +
      +
      +
      +
      +
      A consumer of a stub
      + +
      should be able to stub methods on any Object
      +
      +
      +
      +
      +
      A stubbed method on a class
      + +
      should return the stubbed value
      + +
      should revert to the original method after each spec
      + +
      can stub! and mock the same message
      +
      +
      +
      +
      +
      A mock
      + +
      can stub!
      + +
      can stub! and mock
      + +
      can stub! and mock the same message
      +
      +
      +
      +
      +
      pending example (using pending method)
      + + +
      should be reported as "PENDING: for some reason" (PENDING: for some reason)
      +
      +
      +
      +
      +
      pending example (with no block)
      + + +
      should be reported as "PENDING: Not Yet Implemented" (PENDING: Not Yet Implemented)
      +
      +
      +
      +
      +
      pending example (with block for pending)
      + + +
      should have a failing block, passed to pending, reported as "PENDING: for some reason" (PENDING: for some reason)
      +
      +
      + + +
      +
      + + diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/runner/formatter/html_formatted-1.8.5-jruby.html technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/runner/formatter/html_formatted-1.8.5-jruby.html --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/runner/formatter/html_formatted-1.8.5-jruby.html 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/runner/formatter/html_formatted-1.8.5-jruby.html 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,387 @@ + + + + + RSpec results + + + + + + +
      + + + +
      +

      RSpec Results

      + +
      +

       

      +

       

      +
      +
      + +
      +
      +
      +
      Mocker
      + +
      should be able to call mock()
      + + + +
      + should fail when expected message not received +
      +
      Mock 'poke me' expected :poke with (any args) once, but received it 0 times
      +
      /Users/david/projects/ruby/jruby/testsuites/rspec/target/rspec/./failing_examples/mocking_example.rb:13:in `should_receive'
      +/Users/david/projects/ruby/jruby/testsuites/rspec/target/rspec/spec/spec/runner/formatter/html_formatter_spec.rb:24:in `run'
      +/Users/david/projects/ruby/jruby/testsuites/rspec/target/rspec/spec/spec/runner/formatter/html_formatter_spec.rb:20:in `chdir'
      +/Users/david/projects/ruby/jruby/testsuites/rspec/target/rspec/spec/spec/runner/formatter/html_formatter_spec.rb:20:in `chdir'
      +/Users/david/projects/ruby/jruby/testsuites/rspec/target/rspec/spec/spec/runner/formatter/html_formatter_spec.rb:20:in `instance_eval'
      +
      11  it "should fail when expected message not received" do
      +12    mock = mock("poke me")
      +13    mock.should_receive(:poke)
      +14  end
      +15  
      +16# gem install syntax to get syntax highlighting
      +
      +
      + +
      + should fail when messages are received out of order +
      +
      Mock 'one two three' received :three out of order
      +
      /Users/david/projects/ruby/jruby/testsuites/rspec/target/rspec/./failing_examples/mocking_example.rb:22:in `three'
      +/Users/david/projects/ruby/jruby/testsuites/rspec/target/rspec/./failing_examples/mocking_example.rb:16:in `instance_eval'
      +/Users/david/projects/ruby/jruby/testsuites/rspec/target/rspec/spec/spec/runner/formatter/html_formatter_spec.rb:24:in `run'
      +/Users/david/projects/ruby/jruby/testsuites/rspec/target/rspec/spec/spec/runner/formatter/html_formatter_spec.rb:20:in `chdir'
      +/Users/david/projects/ruby/jruby/testsuites/rspec/target/rspec/spec/spec/runner/formatter/html_formatter_spec.rb:20:in `chdir'
      +/Users/david/projects/ruby/jruby/testsuites/rspec/target/rspec/spec/spec/runner/formatter/html_formatter_spec.rb:20:in `instance_eval'
      +
      20    mock.should_receive(:three).ordered
      +21    mock.one
      +22    mock.three
      +23    mock.two
      +24  end
      +25# gem install syntax to get syntax highlighting
      +
      +
      + +
      + should get yelled at when sending unexpected messages +
      +
      Mock 'don't talk to me' expected :any_message_at_all with (any args) 0 times, but received it once
      +
      /Users/david/projects/ruby/jruby/testsuites/rspec/target/rspec/./failing_examples/mocking_example.rb:28:in `should_not_receive'
      +/Users/david/projects/ruby/jruby/testsuites/rspec/target/rspec/spec/spec/runner/formatter/html_formatter_spec.rb:24:in `run'
      +/Users/david/projects/ruby/jruby/testsuites/rspec/target/rspec/spec/spec/runner/formatter/html_formatter_spec.rb:20:in `chdir'
      +/Users/david/projects/ruby/jruby/testsuites/rspec/target/rspec/spec/spec/runner/formatter/html_formatter_spec.rb:20:in `chdir'
      +/Users/david/projects/ruby/jruby/testsuites/rspec/target/rspec/spec/spec/runner/formatter/html_formatter_spec.rb:20:in `instance_eval'
      +
      26  it "should get yelled at when sending unexpected messages" do
      +27    mock = mock("don't talk to me")
      +28    mock.should_not_receive(:any_message_at_all)
      +29    mock.any_message_at_all
      +30  end
      +31# gem install syntax to get syntax highlighting
      +
      +
      + +
      + has a bug we need to fix +
      +
      Expected pending 'here is the bug' to fail. No Error was raised.
      +
      /Users/david/projects/ruby/jruby/testsuites/rspec/target/rspec/./failing_examples/mocking_example.rb:33:in `pending'
      +/Users/david/projects/ruby/jruby/testsuites/rspec/target/rspec/./failing_examples/mocking_example.rb:33:in `instance_eval'
      +/Users/david/projects/ruby/jruby/testsuites/rspec/target/rspec/spec/spec/runner/formatter/html_formatter_spec.rb:24:in `run'
      +/Users/david/projects/ruby/jruby/testsuites/rspec/target/rspec/spec/spec/runner/formatter/html_formatter_spec.rb:20:in `chdir'
      +/Users/david/projects/ruby/jruby/testsuites/rspec/target/rspec/spec/spec/runner/formatter/html_formatter_spec.rb:20:in `chdir'
      +/Users/david/projects/ruby/jruby/testsuites/rspec/target/rspec/spec/spec/runner/formatter/html_formatter_spec.rb:20:in `instance_eval'
      +
      31
      +32  it "has a bug we need to fix" do
      +33    pending "here is the bug" do
      +34      # Actually, no. It's fixed. This will fail because it passes :-)
      +35      mock = mock("Bug")
      +36# gem install syntax to get syntax highlighting
      +
      +
      +
      +
      +
      +
      +
      Running specs with --diff
      + + +
      + should print diff of different strings +
      +
      expected: "RSpec is a\nbehaviour driven development\nframework for Ruby\n",
      +     got: "RSpec is a\nbehavior driven development\nframework for Ruby\n" (using ==)
      +Diff:
      +@@ -1,4 +1,4 @@
      + RSpec is a
      +-behavior driven development
      ++behaviour driven development
      + framework for Ruby
      +
      +
      /Users/david/projects/ruby/jruby/testsuites/rspec/target/rspec/./failing_examples/diffing_spec.rb:13:in `=='
      +/Users/david/projects/ruby/jruby/testsuites/rspec/target/rspec/spec/spec/runner/formatter/html_formatter_spec.rb:24:in `run'
      +/Users/david/projects/ruby/jruby/testsuites/rspec/target/rspec/spec/spec/runner/formatter/html_formatter_spec.rb:20:in `chdir'
      +/Users/david/projects/ruby/jruby/testsuites/rspec/target/rspec/spec/spec/runner/formatter/html_formatter_spec.rb:20:in `chdir'
      +/Users/david/projects/ruby/jruby/testsuites/rspec/target/rspec/spec/spec/runner/formatter/html_formatter_spec.rb:20:in `instance_eval'
      +
      11framework for Ruby
      +12EOF
      +13    usa.should == uk
      +14  end
      +15
      +16# gem install syntax to get syntax highlighting
      +
      +
      + +
      + should print diff of different objects' pretty representation +
      +
      expected <Animal
      +name=bob,
      +species=tortoise
      +>
      +, got <Animal
      +name=bob,
      +species=giraffe
      +>
      + (using .eql?)
      +Diff:
      +@@ -1,5 +1,5 @@
      + <Animal
      + name=bob,
      +-species=giraffe
      ++species=tortoise
      + >
      +
      +
      /Users/david/projects/ruby/jruby/testsuites/rspec/target/rspec/./failing_examples/diffing_spec.rb:34:in `should'
      +/Users/david/projects/ruby/jruby/testsuites/rspec/target/rspec/./failing_examples/diffing_spec.rb:31:in `instance_eval'
      +/Users/david/projects/ruby/jruby/testsuites/rspec/target/rspec/spec/spec/runner/formatter/html_formatter_spec.rb:24:in `run'
      +/Users/david/projects/ruby/jruby/testsuites/rspec/target/rspec/spec/spec/runner/formatter/html_formatter_spec.rb:20:in `chdir'
      +/Users/david/projects/ruby/jruby/testsuites/rspec/target/rspec/spec/spec/runner/formatter/html_formatter_spec.rb:20:in `chdir'
      +/Users/david/projects/ruby/jruby/testsuites/rspec/target/rspec/spec/spec/runner/formatter/html_formatter_spec.rb:20:in `instance_eval'
      +
      32    expected = Animal.new "bob", "giraffe"
      +33    actual   = Animal.new "bob", "tortoise"
      +34    expected.should eql(actual)
      +35  end
      +36end
      +37# gem install syntax to get syntax highlighting
      +
      +
      +
      +
      +
      +
      +
      A consumer of a stub
      + +
      should be able to stub methods on any Object
      +
      +
      +
      +
      +
      A stubbed method on a class
      + +
      should return the stubbed value
      + +
      should revert to the original method after each spec
      + +
      can stub! and mock the same message
      +
      +
      +
      +
      +
      A mock
      + +
      can stub!
      + +
      can stub! and mock
      + +
      can stub! and mock the same message
      +
      +
      +
      +
      +
      pending example (using pending method)
      + + +
      should be reported as "PENDING: for some reason" (PENDING: for some reason)
      +
      +
      +
      +
      +
      pending example (with no block)
      + + +
      should be reported as "PENDING: Not Yet Implemented" (PENDING: Not Yet Implemented)
      +
      +
      +
      +
      +
      pending example (with block for pending)
      + + +
      should have a failing block, passed to pending, reported as "PENDING: for some reason" (PENDING: for some reason)
      +
      +
      + + +
      +
      + + diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/runner/formatter/html_formatted-1.8.5.html technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/runner/formatter/html_formatted-1.8.5.html --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/runner/formatter/html_formatted-1.8.5.html 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/runner/formatter/html_formatted-1.8.5.html 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,371 @@ + + + + + RSpec results + + + + + + +
      + + + +
      +

      RSpec Results

      + +
      +

       

      +

       

      +
      +
      + +
      +
      +
      +
      Mocker
      + +
      should be able to call mock()
      + + + +
      + should fail when expected message not received +
      +
      Mock 'poke me' expected :poke with (any args) once, but received it 0 times
      +
      ./failing_examples/mocking_example.rb:13:
      +./spec/spec/runner/formatter/html_formatter_spec.rb:17:
      +./spec/spec/runner/formatter/html_formatter_spec.rb:13:in `chdir'
      +./spec/spec/runner/formatter/html_formatter_spec.rb:13:
      +
      11  it "should fail when expected message not received" do
      +12    mock = mock("poke me")
      +13    mock.should_receive(:poke)
      +14  end
      +15  
      +
      +
      + +
      + should fail when messages are received out of order +
      +
      Mock 'one two three' received :three out of order
      +
      ./failing_examples/mocking_example.rb:22:
      +./spec/spec/runner/formatter/html_formatter_spec.rb:17:
      +./spec/spec/runner/formatter/html_formatter_spec.rb:13:in `chdir'
      +./spec/spec/runner/formatter/html_formatter_spec.rb:13:
      +
      20    mock.should_receive(:three).ordered
      +21    mock.one
      +22    mock.three
      +23    mock.two
      +24  end
      +
      +
      + +
      + should get yelled at when sending unexpected messages +
      +
      Mock 'don't talk to me' expected :any_message_at_all with (any args) 0 times, but received it once
      +
      ./failing_examples/mocking_example.rb:28:
      +./spec/spec/runner/formatter/html_formatter_spec.rb:17:
      +./spec/spec/runner/formatter/html_formatter_spec.rb:13:in `chdir'
      +./spec/spec/runner/formatter/html_formatter_spec.rb:13:
      +
      26  it "should get yelled at when sending unexpected messages" do
      +27    mock = mock("don't talk to me")
      +28    mock.should_not_receive(:any_message_at_all)
      +29    mock.any_message_at_all
      +30  end
      +
      +
      + +
      + has a bug we need to fix +
      +
      Expected pending 'here is the bug' to fail. No Error was raised.
      +
      ./failing_examples/mocking_example.rb:33:
      +./spec/spec/runner/formatter/html_formatter_spec.rb:17:
      +./spec/spec/runner/formatter/html_formatter_spec.rb:13:in `chdir'
      +./spec/spec/runner/formatter/html_formatter_spec.rb:13:
      +
      31
      +32  it "has a bug we need to fix" do
      +33    pending "here is the bug" do
      +34      # Actually, no. It's fixed. This will fail because it passes :-)
      +35      mock = mock("Bug")
      +
      +
      +
      +
      +
      +
      +
      Running specs with --diff
      + + +
      + should print diff of different strings +
      +
      expected: "RSpec is a\nbehaviour driven development\nframework for Ruby\n",
      +     got: "RSpec is a\nbehavior driven development\nframework for Ruby\n" (using ==)
      +Diff:
      +@@ -1,4 +1,4 @@
      + RSpec is a
      +-behavior driven development
      ++behaviour driven development
      + framework for Ruby
      +
      +
      ./failing_examples/diffing_spec.rb:13:
      +./spec/spec/runner/formatter/html_formatter_spec.rb:17:
      +./spec/spec/runner/formatter/html_formatter_spec.rb:13:in `chdir'
      +./spec/spec/runner/formatter/html_formatter_spec.rb:13:
      +
      11framework for Ruby
      +12EOF
      +13    usa.should == uk
      +14  end
      +
      +
      + +
      + should print diff of different objects' pretty representation +
      +
      expected <Animal
      +name=bob,
      +species=tortoise
      +>
      +, got <Animal
      +name=bob,
      +species=giraffe
      +>
      + (using .eql?)
      +Diff:
      +@@ -1,5 +1,5 @@
      + <Animal
      + name=bob,
      +-species=giraffe
      ++species=tortoise
      + >
      +
      +
      ./failing_examples/diffing_spec.rb:34:
      +./spec/spec/runner/formatter/html_formatter_spec.rb:17:
      +./spec/spec/runner/formatter/html_formatter_spec.rb:13:in `chdir'
      +./spec/spec/runner/formatter/html_formatter_spec.rb:13:
      +
      32    expected = Animal.new "bob", "giraffe"
      +33    actual   = Animal.new "bob", "tortoise"
      +34    expected.should eql(actual)
      +35  end
      +36end
      +
      +
      +
      +
      +
      +
      +
      A consumer of a stub
      + +
      should be able to stub methods on any Object
      +
      +
      +
      +
      +
      A stubbed method on a class
      + +
      should return the stubbed value
      + +
      should revert to the original method after each spec
      + +
      can stub! and mock the same message
      +
      +
      +
      +
      +
      A mock
      + +
      can stub!
      + +
      can stub! and mock
      + +
      can stub! and mock the same message
      +
      +
      +
      +
      +
      pending example (using pending method)
      + + +
      should be reported as "PENDING: for some reason" (PENDING: for some reason)
      +
      +
      +
      +
      +
      pending example (with no block)
      + + +
      should be reported as "PENDING: Not Yet Implemented" (PENDING: Not Yet Implemented)
      +
      +
      +
      +
      +
      pending example (with block for pending)
      + + +
      should have a failing block, passed to pending, reported as "PENDING: for some reason" (PENDING: for some reason)
      +
      +
      + + +
      +
      + + diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/runner/formatter/html_formatted-1.8.6.html technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/runner/formatter/html_formatted-1.8.6.html --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/runner/formatter/html_formatted-1.8.6.html 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/runner/formatter/html_formatted-1.8.6.html 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,365 @@ + + + + + RSpec results + + + + + + +
      + + + +
      +

      RSpec Results

      + +
      +

       

      +

       

      +
      +
      + +
      +
      +
      +
      Mocker
      + +
      should be able to call mock()
      + + + +
      + should fail when expected message not received +
      +
      Mock 'poke me' expected :poke with (any args) once, but received it 0 times
      +
      ./failing_examples/mocking_example.rb:13:
      +./spec/spec/runner/formatter/html_formatter_spec.rb:18:
      +./spec/spec/runner/formatter/html_formatter_spec.rb:14:in `chdir'
      +./spec/spec/runner/formatter/html_formatter_spec.rb:14:
      +
      11  it "should fail when expected message not received" do
      +12    mock = mock("poke me")
      +13    mock.should_receive(:poke)
      +14  end
      +15  
      +
      +
      + +
      + should fail when messages are received out of order +
      +
      Mock 'one two three' received :three out of order
      +
      ./failing_examples/mocking_example.rb:22:
      +./spec/spec/runner/formatter/html_formatter_spec.rb:18:
      +./spec/spec/runner/formatter/html_formatter_spec.rb:14:in `chdir'
      +./spec/spec/runner/formatter/html_formatter_spec.rb:14:
      +
      20    mock.should_receive(:three).ordered
      +21    mock.one
      +22    mock.three
      +23    mock.two
      +24  end
      +
      +
      + +
      + should get yelled at when sending unexpected messages +
      +
      Mock 'don't talk to me' expected :any_message_at_all with (any args) 0 times, but received it once
      +
      ./failing_examples/mocking_example.rb:28:
      +./spec/spec/runner/formatter/html_formatter_spec.rb:18:
      +./spec/spec/runner/formatter/html_formatter_spec.rb:14:in `chdir'
      +./spec/spec/runner/formatter/html_formatter_spec.rb:14:
      +
      26  it "should get yelled at when sending unexpected messages" do
      +27    mock = mock("don't talk to me")
      +28    mock.should_not_receive(:any_message_at_all)
      +29    mock.any_message_at_all
      +30  end
      +
      +
      + +
      + has a bug we need to fix +
      +
      Expected pending 'here is the bug' to fail. No Error was raised.
      + +
      31
      +32  it "has a bug we need to fix" do
      +33    pending "here is the bug" do
      +34      # Actually, no. It's fixed. This will fail because it passes :-)
      +35      mock = mock("Bug")
      +
      +
      +
      +
      +
      +
      +
      Running specs with --diff
      + + +
      + should print diff of different strings +
      +
      expected: "RSpec is a\nbehaviour driven development\nframework for Ruby\n",
      +     got: "RSpec is a\nbehavior driven development\nframework for Ruby\n" (using ==)
      +Diff:
      +@@ -1,4 +1,4 @@
      + RSpec is a
      +-behavior driven development
      ++behaviour driven development
      + framework for Ruby
      +
      + +
      11framework for Ruby
      +12EOF
      +13    usa.should == uk
      +14  end
      +
      +
      + +
      + should print diff of different objects' pretty representation +
      +
      expected <Animal
      +name=bob,
      +species=tortoise
      +>
      +, got <Animal
      +name=bob,
      +species=giraffe
      +>
      + (using .eql?)
      +Diff:
      +@@ -1,5 +1,5 @@
      + <Animal
      + name=bob,
      +-species=giraffe
      ++species=tortoise
      + >
      +
      +
      ./failing_examples/mocking_example.rb:33:
      +./spec/spec/runner/formatter/html_formatter_spec.rb:18:
      +./spec/spec/runner/formatter/html_formatter_spec.rb:14:in `chdir'
      +./spec/spec/runner/formatter/html_formatter_spec.rb:14:
      +
      32    expected = Animal.new "bob", "giraffe"
      +33    actual   = Animal.new "bob", "tortoise"
      +34    expected.should eql(actual)
      +35  end
      +36end
      +
      +
      +
      +
      +
      +
      +
      A consumer of a stub
      + +
      should be able to stub methods on any Object
      +
      +
      +
      +
      +
      A stubbed method on a class
      + +
      should return the stubbed value
      + +
      should revert to the original method after each spec
      + +
      can stub! and mock the same message
      +
      +
      +
      +
      +
      A mock
      + +
      can stub!
      + +
      can stub! and mock
      + +
      can stub! and mock the same message
      +
      +
      +
      +
      +
      pending example (using pending method)
      + + +
      should be reported as "PENDING: for some reason" (PENDING: for some reason)
      +
      +
      +
      +
      +
      pending example (with no block)
      + + +
      should be reported as "PENDING: Not Yet Implemented" (PENDING: Not Yet Implemented)
      +
      +
      +
      +
      +
      pending example (with block for pending)
      + + +
      should have a failing block, passed to pending, reported as "PENDING: for some reason" (PENDING: for some reason)
      +
      +
      + + +
      +
      + + diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/runner/formatter/html_formatter_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/runner/formatter/html_formatter_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/runner/formatter/html_formatter_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/runner/formatter/html_formatter_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,60 @@ +require File.dirname(__FILE__) + '/../../../spec_helper' +require 'hpricot' # Needed to compare generated with wanted HTML + +describe "HtmlFormatter" do + ['--diff', '--dry-run'].each do |opt| + def jruby? + PLATFORM == 'java' + end + + it "should produce HTML identical to the one we designed manually with #{opt}" do + root = File.expand_path(File.dirname(__FILE__) + '/../../../..') + suffix = jruby? ? '-jruby' : '' + expected_file = File.dirname(__FILE__) + "/html_formatted-#{VERSION}#{suffix}.html" + raise "There is no HTML file with expected content for this platform: #{expected_file}" unless File.file?(expected_file) + expected_html = File.read(expected_file) + unless jruby? + raise "There should be no absolute paths in html_formatted.html!!" if (expected_html =~ /\/Users/n || expected_html =~ /\/home/n) + end + + Dir.chdir(root) do + args = ['failing_examples/mocking_example.rb', 'failing_examples/diffing_spec.rb', 'examples/pure/stubbing_example.rb', 'examples/pure/pending_example.rb', '--format', 'html', opt] + err = StringIO.new + out = StringIO.new + Spec::Runner::CommandLine.run( + ::Spec::Runner::OptionParser.parse(args, err, out) + ) + + seconds = /\d+\.\d+ seconds/ + html = out.string.gsub seconds, 'x seconds' + expected_html.gsub! seconds, 'x seconds' + + if opt == '--diff' + # Uncomment this line temporarily in order to overwrite the expected with actual. + # Use with care!!! + # File.open(expected_file, 'w') {|io| io.write(html)} + + doc = Hpricot(html) + backtraces = doc.search("div.backtrace").collect {|e| e.at("/pre").inner_html} + doc.search("div.backtrace").remove + + expected_doc = Hpricot(expected_html) + expected_backtraces = expected_doc.search("div.backtrace").collect {|e| e.at("/pre").inner_html} + expected_doc.search("div.backtrace").remove + + doc.inner_html.should == expected_doc.inner_html + + expected_backtraces.each_with_index do |expected_line, i| + expected_path, expected_line_number, expected_suffix = expected_line.split(':') + actual_path, actual_line_number, actual_suffix = backtraces[i].split(':') + File.expand_path(actual_path).should == File.expand_path(expected_path) + actual_line_number.should == expected_line_number + end + else + html.should =~ /This was a dry-run/m + end + end + end + end + +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/runner/formatter/profile_formatter_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/runner/formatter/profile_formatter_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/runner/formatter/profile_formatter_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/runner/formatter/profile_formatter_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,61 @@ +require File.dirname(__FILE__) + '/../../../spec_helper.rb' + +module Spec + module Runner + module Formatter + describe ProfileFormatter do + + before(:each) do + @io = StringIO.new + options = mock('options') + options.stub!(:colour).and_return(true) + @formatter = ProfileFormatter.new(options, @io) + end + + it "should print a heading" do + @formatter.start(0) + @io.string.should eql("Profiling enabled.\n") + end + + it "should set the current behaviour" do + @formatter.add_example_group('Test') + @formatter.instance_variable_get("@behaviour").should == 'Test' + end + + it "should record the current time when starting a new example" do + now = Time.now + Time.stub!(:now).and_return(now) + @formatter.example_started('should foo') + @formatter.instance_variable_get("@time").should == now + end + + it "should correctly record a passed example" do + now = Time.now + Time.stub!(:now).and_return(now) + @formatter.add_example_group('Test') + @formatter.example_started('when foo') + Time.stub!(:now).and_return(now+1) + @formatter.example_passed('when foo') + @formatter.instance_variable_get("@examples").should == [['Test', 'when foo', 1.0]] + end + + it "should sort the results in descending order" do + @formatter.instance_variable_set("@examples", [['a', 'a', 0.1], ['b', 'b', 0.3], ['c', 'c', 0.2]]) + @formatter.start_dump + @formatter.instance_variable_get("@examples").should == [ ['b', 'b', 0.3], ['c', 'c', 0.2], ['a', 'a', 0.1]] + end + + it "should print the top 10 results" do + @formatter.instance_variable_set("@time", Time.now) + + 15.times do + @formatter.example_passed('foo') + end + + @io.should_receive(:print).exactly(10) + @formatter.start_dump + end + end + end + end +end \ No newline at end of file diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/runner/formatter/progress_bar_formatter_dry_run_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/runner/formatter/progress_bar_formatter_dry_run_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/runner/formatter/progress_bar_formatter_dry_run_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/runner/formatter/progress_bar_formatter_dry_run_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,21 @@ +require File.dirname(__FILE__) + '/../../../spec_helper.rb' + +module Spec + module Runner + module Formatter + describe ProgressBarFormatter, "dry run" do + before(:each) do + @io = StringIO.new + options = mock('options') + options.stub!(:dry_run).and_return(true) + @formatter = ProgressBarFormatter.new(options, @io) + end + + it "should not produce summary on dry run" do + @formatter.dump_summary(3, 2, 1, 0) + @io.string.should eql("") + end + end + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/runner/formatter/progress_bar_formatter_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/runner/formatter/progress_bar_formatter_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/runner/formatter/progress_bar_formatter_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/runner/formatter/progress_bar_formatter_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,112 @@ +require File.dirname(__FILE__) + '/../../../spec_helper.rb' + +module Spec + module Runner + module Formatter + describe ProgressBarFormatter do + before(:each) do + @io = StringIO.new + @options = mock('options') + @options.stub!(:dry_run).and_return(false) + @options.stub!(:colour).and_return(false) + @formatter = ProgressBarFormatter.new(@options, @io) + end + + it "should produce line break on start dump" do + @formatter.start_dump + @io.string.should eql("\n") + end + + it "should produce standard summary without pending when pending has a 0 count" do + @formatter.dump_summary(3, 2, 1, 0) + @io.string.should eql("\nFinished in 3 seconds\n\n2 examples, 1 failure\n") + end + + it "should produce standard summary" do + @formatter.example_pending("behaviour", "example", "message") + @io.rewind + @formatter.dump_summary(3, 2, 1, 1) + @io.string.should eql(%Q| +Finished in 3 seconds + +2 examples, 1 failure, 1 pending +|) + end + + it "should push green dot for passing spec" do + @io.should_receive(:tty?).and_return(true) + @options.should_receive(:colour).and_return(true) + @formatter.example_passed("spec") + @io.string.should == "\e[32m.\e[0m" + end + + it "should push red F for failure spec" do + @io.should_receive(:tty?).and_return(true) + @options.should_receive(:colour).and_return(true) + @formatter.example_failed("spec", 98, Reporter::Failure.new("c s", Spec::Expectations::ExpectationNotMetError.new)) + @io.string.should eql("\e[31mF\e[0m") + end + + it "should push magenta F for error spec" do + @io.should_receive(:tty?).and_return(true) + @options.should_receive(:colour).and_return(true) + @formatter.example_failed("spec", 98, Reporter::Failure.new("c s", RuntimeError.new)) + @io.string.should eql("\e[35mF\e[0m") + end + + it "should push blue F for fixed pending spec" do + @io.should_receive(:tty?).and_return(true) + @options.should_receive(:colour).and_return(true) + @formatter.example_failed("spec", 98, Reporter::Failure.new("c s", Spec::Example::PendingExampleFixedError.new)) + @io.string.should eql("\e[34mF\e[0m") + end + + it "should push nothing on start" do + @formatter.start(4) + @io.string.should eql("") + end + + it "should ensure two ':' in the first backtrace" do + backtrace = ["/tmp/x.rb:1", "/tmp/x.rb:2", "/tmp/x.rb:3"] + @formatter.format_backtrace(backtrace).should eql(<<-EOE.rstrip) +/tmp/x.rb:1: +/tmp/x.rb:2: +/tmp/x.rb:3: +EOE + + backtrace = ["/tmp/x.rb:1: message", "/tmp/x.rb:2", "/tmp/x.rb:3"] + @formatter.format_backtrace(backtrace).should eql(<<-EOE.rstrip) +/tmp/x.rb:1: message +/tmp/x.rb:2: +/tmp/x.rb:3: +EOE + end + + it "should dump pending" do + @formatter.example_pending("behaviour", "example", "message") + @formatter.dump_pending + @io.string.should =~ /Pending\:\nbehaviour example \(message\)\n/ + end + end + + describe "ProgressBarFormatter outputting to custom out" do + before(:each) do + @out = mock("out") + @options = mock('options') + @out.stub!(:puts) + @formatter = ProgressBarFormatter.new(@options, @out) + @formatter.class.send :public, :output_to_tty? + end + + after(:each) do + @formatter.class.send :protected, :output_to_tty? + end + + it "should not throw NoMethodError on output_to_tty?" do + @out.should_receive(:tty?).and_raise(NoMethodError) + @formatter.output_to_tty?.should be_false + end + end + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/runner/formatter/snippet_extractor_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/runner/formatter/snippet_extractor_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/runner/formatter/snippet_extractor_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/runner/formatter/snippet_extractor_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,11 @@ +require File.dirname(__FILE__) + '/../../../spec_helper.rb' + +describe Spec::Runner::Formatter::SnippetExtractor do + it "should fall back on a default message when it doesn't understand a line" do + Spec::Runner::Formatter::SnippetExtractor.new.snippet_for("blech").should == ["# Couldn't get snippet for blech", 1] + end + + it "should fall back on a default message when it doesn't find the file" do + Spec::Runner::Formatter::SnippetExtractor.new.lines_around("blech", 8).should == "# Couldn't get snippet for blech" + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/runner/formatter/spec_mate_formatter_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/runner/formatter/spec_mate_formatter_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/runner/formatter/spec_mate_formatter_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/runner/formatter/spec_mate_formatter_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,108 @@ +require File.dirname(__FILE__) + '/../../../spec_helper' +require 'hpricot' # Needed to compare generated with wanted HTML + +module Spec + module Runner + module Formatter + describe TextMateFormatter, "functional spec", :shared => true do + attr_reader :root, :suffix, :expected_file + before do + @root = File.expand_path(File.dirname(__FILE__) + '/../../../..') + @suffix = jruby? ? '-jruby' : '' + @expected_file = File.dirname(__FILE__) + "/text_mate_formatted-#{::VERSION}#{suffix}.html" + end + + def jruby? + PLATFORM == 'java' + end + + def produces_html_identical_to_manually_designed_document(opt) + root = File.expand_path(File.dirname(__FILE__) + '/../../../..') + + Dir.chdir(root) do + args = [ + 'failing_examples/mocking_example.rb', + 'failing_examples/diffing_spec.rb', + 'examples/pure/stubbing_example.rb', + 'examples/pure/pending_example.rb', + '--format', + 'textmate', + opt + ] + err = StringIO.new + out = StringIO.new + options = ::Spec::Runner::OptionParser.parse(args, err, out) + Spec::Runner::CommandLine.run(options) + + yield(out.string) + end + end + end + + # # Uncomment this spec temporarily in order to overwrite the expected with actual. + # # Use with care!!! + # describe TextMateFormatter, "functional spec file generator" do + # it_should_behave_like "Spec::Runner::Formatter::TextMateFormatter functional spec" + # + # it "generates a new comparison file" do + # Dir.chdir(root) do + # args = ['failing_examples/mocking_example.rb', 'failing_examples/diffing_spec.rb', 'examples/pure/stubbing_example.rb', 'examples/pure/pending_example.rb', '--format', 'textmate', '--diff'] + # err = StringIO.new + # out = StringIO.new + # Spec::Runner::CommandLine.run( + # ::Spec::Runner::OptionParser.parse(args, err, out) + # ) + # + # seconds = /\d+\.\d+ seconds/ + # html = out.string.gsub seconds, 'x seconds' + # + # File.open(expected_file, 'w') {|io| io.write(html)} + # end + # end + # end + + describe TextMateFormatter, "functional spec using --diff" do + it_should_behave_like "Spec::Runner::Formatter::TextMateFormatter functional spec" + + it "should produce HTML identical to the one we designed manually with --diff" do + produces_html_identical_to_manually_designed_document("--diff") do |html| + suffix = jruby? ? '-jruby' : '' + expected_file = File.dirname(__FILE__) + "/text_mate_formatted-#{::VERSION}#{suffix}.html" + unless File.file?(expected_file) + raise "There is no HTML file with expected content for this platform: #{expected_file}" + end + expected_html = File.read(expected_file) + + seconds = /\d+\.\d+ seconds/ + html.gsub! seconds, 'x seconds' + expected_html.gsub! seconds, 'x seconds' + + doc = Hpricot(html) + backtraces = doc.search("div.backtrace/a") + doc.search("div.backtrace").remove + + expected_doc = Hpricot(expected_html) + expected_doc.search("div.backtrace").remove + + doc.inner_html.should == expected_doc.inner_html + + backtraces.each do |backtrace_link| + backtrace_link[:href].should include("txmt://open?url=") + end + end + end + + end + + describe TextMateFormatter, "functional spec using --dry-run" do + it_should_behave_like "Spec::Runner::Formatter::TextMateFormatter functional spec" + + it "should produce HTML identical to the one we designed manually with --dry-run" do + produces_html_identical_to_manually_designed_document("--dry-run") do |html, expected_html| + html.should =~ /This was a dry-run/m + end + end + end + end + end +end \ No newline at end of file diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/runner/formatter/specdoc_formatter_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/runner/formatter/specdoc_formatter_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/runner/formatter/specdoc_formatter_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/runner/formatter/specdoc_formatter_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,84 @@ +require File.dirname(__FILE__) + '/../../../spec_helper.rb' + +module Spec + module Runner + module Formatter + describe "SpecdocFormatter" do + before(:each) do + @io = StringIO.new + @options = mock('options') + @options.stub!(:dry_run).and_return(false) + @options.stub!(:colour).and_return(false) + @formatter = SpecdocFormatter.new(@options, @io) + @behaviour = Class.new(::Spec::Example::ExampleGroup).describe("Some Examples") + end + + it "should produce standard summary without pending when pending has a 0 count" do + @formatter.dump_summary(3, 2, 1, 0) + @io.string.should eql("\nFinished in 3 seconds\n\n2 examples, 1 failure\n") + end + + it "should produce standard summary" do + @formatter.dump_summary(3, 2, 1, 4) + @io.string.should eql("\nFinished in 3 seconds\n\n2 examples, 1 failure, 4 pending\n") + end + + it "should push context name" do + @formatter.add_example_group(Spec::Example::ExampleGroupDescription.new("context")) + @io.string.should eql("\ncontext\n") + end + + it "when having an error, should push failing spec name and failure number" do + @formatter.example_failed( + @behaviour.it("spec"), + 98, + Reporter::Failure.new("c s", RuntimeError.new) + ) + @io.string.should eql("- spec (ERROR - 98)\n") + end + + it "when having an expectation failure, should push failing spec name and failure number" do + @formatter.example_failed( + @behaviour.it("spec"), + 98, + Reporter::Failure.new("c s", Spec::Expectations::ExpectationNotMetError.new) + ) + @io.string.should eql("- spec (FAILED - 98)\n") + end + + it "should push nothing on start" do + @formatter.start(5) + @io.string.should eql("") + end + + it "should push nothing on start dump" do + @formatter.start_dump + @io.string.should eql("") + end + + it "should push passing spec name" do + @formatter.example_passed(@behaviour.it("spec")) + @io.string.should eql("- spec\n") + end + + it "should push pending example name and message" do + @formatter.example_pending('behaviour', 'example','reason') + @io.string.should eql("- example (PENDING: reason)\n") + end + + it "should dump pending" do + @formatter.example_pending('behaviour', 'example','reason') + @io.rewind + @formatter.dump_pending + @io.string.should =~ /Pending\:\nbehaviour example \(reason\)\n/ + end + + it "should not produce summary on dry run" do + @options.should_receive(:dry_run).and_return(true) + @formatter.dump_summary(3, 2, 1, 0) + @io.string.should eql("") + end + end + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/runner/formatter/story/html_formatter_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/runner/formatter/story/html_formatter_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/runner/formatter/story/html_formatter_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/runner/formatter/story/html_formatter_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,56 @@ +require File.dirname(__FILE__) + '/../../../../spec_helper.rb' +require File.dirname(__FILE__) + '/../../../story/rspec_adapter.rb' + +module Spec + module Runner + module Formatter + module Story + describe HtmlFormatter do + before :each do + @out = StringIO.new + @options = mock('options') + @reporter = HtmlFormatter.new(@options, @out) + end + + it "should just be poked at" do + @reporter.run_started(1) + @reporter.story_started('story_title', 'narrative') + + @reporter.scenario_started('story_title', 'succeeded_scenario_name') + @reporter.step_succeeded('given', 'succeded_step', 'one', 'two') + @reporter.scenario_succeeded('story_title', 'succeeded_scenario_name') + + @reporter.scenario_started('story_title', 'pending_scenario_name') + @reporter.step_pending('when', 'pending_step', 'un', 'deux') + @reporter.scenario_pending('story_title', 'pending_scenario_name', 'not done') + + @reporter.scenario_started('story_title', 'failed_scenario_name') + @reporter.step_failed('then', 'failed_step', 'en', 'to') + @reporter.scenario_failed('story_title', 'failed_scenario_name', NameError.new('sup')) + + @reporter.scenario_started('story_title', 'scenario_with_given_scenario_name') + @reporter.found_scenario('given scenario', 'succeeded_scenario_name') + + @reporter.story_ended('story_title', 'narrative') + @reporter.run_ended + end + + it "should create spans for params" do + @reporter.step_succeeded('given', 'a $coloured $animal', 'brown', 'dog') + @out.string.should == "
    • Given a brown dog
    • \n" + end + + it "should create a ul for collected_steps" do + @reporter.collected_steps(['Given a $coloured $animal', 'Given a $n legged eel']) + @out.string.should == (<<-EOF) + +EOF + end + end + end + end + end +end \ No newline at end of file diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/runner/formatter/story/plain_text_formatter_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/runner/formatter/story/plain_text_formatter_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/runner/formatter/story/plain_text_formatter_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/runner/formatter/story/plain_text_formatter_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,283 @@ +require File.dirname(__FILE__) + '/../../../../spec_helper.rb' +require File.dirname(__FILE__) + '/../../../story/rspec_adapter.rb' + +module Spec + module Runner + module Formatter + module Story + describe PlainTextFormatter do + before :each do + # given + @out = StringIO.new + @options = mock('options') + @options.stub!(:colour).and_return(false) + @reporter = PlainTextFormatter.new(@options, @out) + end + + it 'should summarize the number of scenarios when the run ends' do + # when + @reporter.run_started(3) + @reporter.scenario_started(nil, nil) + @reporter.scenario_succeeded('story', 'scenario1') + @reporter.scenario_started(nil, nil) + @reporter.scenario_succeeded('story', 'scenario2') + @reporter.scenario_started(nil, nil) + @reporter.scenario_succeeded('story', 'scenario3') + @reporter.run_ended + + # then + @out.string.should include('3 scenarios') + end + + it 'should summarize the number of successful scenarios when the run ends' do + # when + @reporter.run_started(3) + @reporter.scenario_started(nil, nil) + @reporter.scenario_succeeded('story', 'scenario1') + @reporter.scenario_started(nil, nil) + @reporter.scenario_succeeded('story', 'scenario2') + @reporter.scenario_started(nil, nil) + @reporter.scenario_succeeded('story', 'scenario3') + @reporter.run_ended + + # then + @out.string.should include('3 scenarios: 3 succeeded') + end + + it 'should summarize the number of failed scenarios when the run ends' do + # when + @reporter.run_started(3) + @reporter.scenario_started(nil, nil) + @reporter.scenario_succeeded('story', 'scenario1') + @reporter.scenario_started(nil, nil) + @reporter.scenario_failed('story', 'scenario2', exception_from { raise RuntimeError, 'oops' }) + @reporter.scenario_started(nil, nil) + @reporter.scenario_failed('story', 'scenario3', exception_from { raise RuntimeError, 'oops' }) + @reporter.run_ended + + # then + @out.string.should contain("3 scenarios: 1 succeeded, 2 failed") + end + + it 'should summarize the number of pending scenarios when the run ends' do + # when + @reporter.run_started(3) + @reporter.scenario_started(nil, nil) + @reporter.scenario_succeeded('story', 'scenario1') + @reporter.scenario_started(nil, nil) + @reporter.scenario_pending('story', 'scenario2', 'message') + @reporter.scenario_started(nil, nil) + @reporter.scenario_pending('story', 'scenario3', 'message') + @reporter.run_ended + + # then + @out.string.should contain("3 scenarios: 1 succeeded, 0 failed, 2 pending") + end + + it "should only count the first failure in one scenario" do + # when + @reporter.run_started(3) + @reporter.scenario_started(nil, nil) + @reporter.scenario_succeeded('story', 'scenario1') + @reporter.scenario_started(nil, nil) + @reporter.scenario_failed('story', 'scenario2', exception_from { raise RuntimeError, 'oops' }) + @reporter.scenario_failed('story', 'scenario2', exception_from { raise RuntimeError, 'oops again' }) + @reporter.scenario_started(nil, nil) + @reporter.scenario_failed('story', 'scenario3', exception_from { raise RuntimeError, 'oops' }) + @reporter.run_ended + + # then + @out.string.should contain("3 scenarios: 1 succeeded, 2 failed") + end + + it "should only count the first pending in one scenario" do + # when + @reporter.run_started(3) + @reporter.scenario_started(nil, nil) + @reporter.scenario_succeeded('story', 'scenario1') + @reporter.scenario_started(nil, nil) + @reporter.scenario_pending('story', 'scenario2', 'because ...') + @reporter.scenario_pending('story', 'scenario2', 'because ...') + @reporter.scenario_started(nil, nil) + @reporter.scenario_pending('story', 'scenario3', 'because ...') + @reporter.run_ended + + # then + @out.string.should contain("3 scenarios: 1 succeeded, 0 failed, 2 pending") + end + + it "should only count a failure before the first pending in one scenario" do + # when + @reporter.run_started(3) + @reporter.scenario_started(nil, nil) + @reporter.scenario_succeeded('story', 'scenario1') + @reporter.scenario_started(nil, nil) + @reporter.scenario_pending('story', 'scenario2', exception_from { raise RuntimeError, 'oops' }) + @reporter.scenario_failed('story', 'scenario2', exception_from { raise RuntimeError, 'oops again' }) + @reporter.scenario_started(nil, nil) + @reporter.scenario_failed('story', 'scenario3', exception_from { raise RuntimeError, 'oops' }) + @reporter.run_ended + + # then + @out.string.should contain("3 scenarios: 1 succeeded, 1 failed, 1 pending") + end + + it 'should produce details of the first failure each failed scenario when the run ends' do + # when + @reporter.run_started(3) + @reporter.scenario_started(nil, nil) + @reporter.scenario_succeeded('story', 'scenario1') + @reporter.scenario_started(nil, nil) + @reporter.scenario_failed('story', 'scenario2', exception_from { raise RuntimeError, 'oops2' }) + @reporter.scenario_failed('story', 'scenario2', exception_from { raise RuntimeError, 'oops2 - this one should not appear' }) + @reporter.scenario_started(nil, nil) + @reporter.scenario_failed('story', 'scenario3', exception_from { raise RuntimeError, 'oops3' }) + @reporter.run_ended + + # then + @out.string.should contain("FAILURES:\n") + @out.string.should contain("1) story (scenario2) FAILED") + @out.string.should contain("RuntimeError: oops2") + @out.string.should_not contain("RuntimeError: oops2 - this one should not appear") + @out.string.should contain("2) story (scenario3) FAILED") + @out.string.should contain("RuntimeError: oops3") + end + + it 'should produce details of each pending step when the run ends' do + # when + @reporter.run_started(2) + @reporter.scenario_pending('story', 'scenario2', 'todo2') + @reporter.scenario_pending('story', 'scenario3', 'todo3') + @reporter.run_ended + + # then + @out.string.should contain("Pending Steps:\n") + @out.string.should contain("1) story (scenario2): todo2") + @out.string.should contain("2) story (scenario3): todo3") + end + + it 'should document a story title and narrative' do + # when + @reporter.story_started 'story', 'narrative' + + # then + @out.string.should contain("Story: story\n\n narrative") + end + + it 'should document a scenario name' do + # when + @reporter.scenario_started 'story', 'scenario' + + # then + @out.string.should contain("\n\nScenario: scenario") + end + + it 'should document a step by sentence-casing its name' do + # when + @reporter.step_succeeded :given, 'a context' + @reporter.step_succeeded :when, 'an event' + @reporter.step_succeeded :then, 'an outcome' + + # then + @out.string.should contain("\n\n Given a context\n\n When an event\n\n Then an outcome") + end + + it 'should document additional givens using And' do + # when + @reporter.step_succeeded :given, 'step 1' + @reporter.step_succeeded :given, 'step 2' + @reporter.step_succeeded :given, 'step 3' + + # then + @out.string.should contain(" Given step 1\n And step 2\n And step 3") + end + + it 'should document additional events using And' do + # when + @reporter.step_succeeded :when, 'step 1' + @reporter.step_succeeded :when, 'step 2' + @reporter.step_succeeded :when, 'step 3' + + # then + @out.string.should contain(" When step 1\n And step 2\n And step 3") + end + + it 'should document additional outcomes using And' do + # when + @reporter.step_succeeded :then, 'step 1' + @reporter.step_succeeded :then, 'step 2' + @reporter.step_succeeded :then, 'step 3' + + # then + @out.string.should contain(" Then step 1\n And step 2\n And step 3") + end + + it 'should document a GivenScenario followed by a Given using And' do + # when + @reporter.step_succeeded :'given scenario', 'a scenario' + @reporter.step_succeeded :given, 'a context' + + # then + @out.string.should contain(" Given scenario a scenario\n And a context") + end + + it 'should document steps with replaced params' do + @reporter.step_succeeded :given, 'a $coloured dog with $n legs', 'pink', 21 + @out.string.should contain(" Given a pink dog with 21 legs") + end + + it "should append PENDING for the first pending step" do + @reporter.scenario_started('','') + @reporter.step_pending(:given, 'a context') + + @out.string.should contain('Given a context (PENDING)') + end + + it "should append PENDING for pending after already pending" do + @reporter.scenario_started('','') + @reporter.step_pending(:given, 'a context') + @reporter.step_pending(:when, 'I say hey') + + @out.string.should contain('When I say hey (PENDING)') + end + + it "should append FAILED for the first failiure" do + @reporter.scenario_started('','') + @reporter.step_failed(:given, 'a context') + + @out.string.should contain('Given a context (FAILED)') + end + + it "should append SKIPPED for the second failiure" do + @reporter.scenario_started('','') + @reporter.step_failed(:given, 'a context') + @reporter.step_failed(:when, 'I say hey') + + @out.string.should contain('When I say hey (SKIPPED)') + end + + it "should append SKIPPED for the a failiure after PENDING" do + @reporter.scenario_started('','') + @reporter.step_pending(:given, 'a context') + @reporter.step_failed(:when, 'I say hey') + + @out.string.should contain('When I say hey (SKIPPED)') + end + + it 'should print some white space after each story' do + # when + @reporter.story_ended 'title', 'narrative' + + # then + @out.string.should contain("\n\n") + end + + it "should print nothing for collected_steps" do + @reporter.collected_steps(['Given a $coloured $animal', 'Given a $n legged eel']) + @out.string.should == ("") + end + end + end + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/runner/formatter/text_mate_formatted-1.8.4.html technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/runner/formatter/text_mate_formatted-1.8.4.html --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/runner/formatter/text_mate_formatted-1.8.4.html 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/runner/formatter/text_mate_formatted-1.8.4.html 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,365 @@ + + + + + RSpec results + + + + + + +
      + + + +
      +

      RSpec Results

      + +
      +

       

      +

       

      +
      +
      + +
      +
      +
      +
      Mocker
      + +
      should be able to call mock()
      + + + +
      + should fail when expected message not received +
      +
      Mock 'poke me' expected :poke with (any args) once, but received it 0 times
      + +
      11  it "should fail when expected message not received" do
      +12    mock = mock("poke me")
      +13    mock.should_receive(:poke)
      +14  end
      +15  
      +
      +
      + +
      + should fail when messages are received out of order +
      +
      Mock 'one two three' received :three out of order
      + +
      20    mock.should_receive(:three).ordered
      +21    mock.one
      +22    mock.three
      +23    mock.two
      +24  end
      +
      +
      + +
      + should get yelled at when sending unexpected messages +
      +
      Mock 'don't talk to me' expected :any_message_at_all with (any args) 0 times, but received it once
      + +
      26  it "should get yelled at when sending unexpected messages" do
      +27    mock = mock("don't talk to me")
      +28    mock.should_not_receive(:any_message_at_all)
      +29    mock.any_message_at_all
      +30  end
      +
      +
      + +
      + has a bug we need to fix +
      +
      Expected pending 'here is the bug' to fail. No Error was raised.
      + +
      31
      +32  it "has a bug we need to fix" do
      +33    pending "here is the bug" do
      +34      # Actually, no. It's fixed. This will fail because it passes :-)
      +35      mock = mock("Bug")
      +
      +
      +
      +
      +
      +
      +
      Running specs with --diff
      + + +
      + should print diff of different strings +
      +
      expected: "RSpec is a\nbehaviour driven development\nframework for Ruby\n",
      +     got: "RSpec is a\nbehavior driven development\nframework for Ruby\n" (using ==)
      +Diff:
      +@@ -1,4 +1,4 @@
      + RSpec is a
      +-behavior driven development
      ++behaviour driven development
      + framework for Ruby
      +
      + +
      11framework for Ruby
      +12EOF
      +13    usa.should == uk
      +14  end
      +
      +
      + +
      + should print diff of different objects' pretty representation +
      +
      expected <Animal
      +name=bob,
      +species=tortoise
      +>
      +, got <Animal
      +name=bob,
      +species=giraffe
      +>
      + (using .eql?)
      +Diff:
      +@@ -1,5 +1,5 @@
      + <Animal
      + name=bob,
      +-species=giraffe
      ++species=tortoise
      + >
      +
      + +
      32    expected = Animal.new "bob", "giraffe"
      +33    actual   = Animal.new "bob", "tortoise"
      +34    expected.should eql(actual)
      +35  end
      +36end
      +
      +
      +
      +
      +
      +
      +
      A consumer of a stub
      + +
      should be able to stub methods on any Object
      +
      +
      +
      +
      +
      A stubbed method on a class
      + +
      should return the stubbed value
      + +
      should revert to the original method after each spec
      + +
      can stub! and mock the same message
      +
      +
      +
      +
      +
      A mock
      + +
      can stub!
      + +
      can stub! and mock
      + +
      can stub! and mock the same message
      +
      +
      +
      +
      +
      pending example (using pending method)
      + + +
      should be reported as "PENDING: for some reason" (PENDING: for some reason)
      +
      +
      +
      +
      +
      pending example (with no block)
      + + +
      should be reported as "PENDING: Not Yet Implemented" (PENDING: Not Yet Implemented)
      +
      +
      +
      +
      +
      pending example (with block for pending)
      + + +
      should have a failing block, passed to pending, reported as "PENDING: for some reason" (PENDING: for some reason)
      +
      +
      + + +
      +
      + + diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/runner/formatter/text_mate_formatted-1.8.6.html technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/runner/formatter/text_mate_formatted-1.8.6.html --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/runner/formatter/text_mate_formatted-1.8.6.html 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/runner/formatter/text_mate_formatted-1.8.6.html 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,365 @@ + + + + + RSpec results + + + + + + +
      + + + +
      +

      RSpec Results

      + +
      +

       

      +

       

      +
      +
      + +
      +
      +
      +
      Mocker
      + +
      should be able to call mock()
      + + + +
      + should fail when expected message not received +
      +
      Mock 'poke me' expected :poke with (any args) once, but received it 0 times
      +
      ./failing_examples/mocking_example.rb:13:
      +./spec/spec/runner/formatter/html_formatter_spec.rb:18:
      +./spec/spec/runner/formatter/html_formatter_spec.rb:14:in `chdir'
      +./spec/spec/runner/formatter/html_formatter_spec.rb:14:
      +
      11  it "should fail when expected message not received" do
      +12    mock = mock("poke me")
      +13    mock.should_receive(:poke)
      +14  end
      +15  
      +
      +
      + +
      + should fail when messages are received out of order +
      +
      Mock 'one two three' received :three out of order
      +
      ./failing_examples/mocking_example.rb:22:
      +./spec/spec/runner/formatter/html_formatter_spec.rb:18:
      +./spec/spec/runner/formatter/html_formatter_spec.rb:14:in `chdir'
      +./spec/spec/runner/formatter/html_formatter_spec.rb:14:
      +
      20    mock.should_receive(:three).ordered
      +21    mock.one
      +22    mock.three
      +23    mock.two
      +24  end
      +
      +
      + +
      + should get yelled at when sending unexpected messages +
      +
      Mock 'don't talk to me' expected :any_message_at_all with (any args) 0 times, but received it once
      +
      ./failing_examples/mocking_example.rb:28:
      +./spec/spec/runner/formatter/html_formatter_spec.rb:18:
      +./spec/spec/runner/formatter/html_formatter_spec.rb:14:in `chdir'
      +./spec/spec/runner/formatter/html_formatter_spec.rb:14:
      +
      26  it "should get yelled at when sending unexpected messages" do
      +27    mock = mock("don't talk to me")
      +28    mock.should_not_receive(:any_message_at_all)
      +29    mock.any_message_at_all
      +30  end
      +
      +
      + +
      + has a bug we need to fix +
      +
      Expected pending 'here is the bug' to fail. No Error was raised.
      + +
      31
      +32  it "has a bug we need to fix" do
      +33    pending "here is the bug" do
      +34      # Actually, no. It's fixed. This will fail because it passes :-)
      +35      mock = mock("Bug")
      +
      +
      +
      +
      +
      +
      +
      Running specs with --diff
      + + +
      + should print diff of different strings +
      +
      expected: "RSpec is a\nbehaviour driven development\nframework for Ruby\n",
      +     got: "RSpec is a\nbehavior driven development\nframework for Ruby\n" (using ==)
      +Diff:
      +@@ -1,4 +1,4 @@
      + RSpec is a
      +-behavior driven development
      ++behaviour driven development
      + framework for Ruby
      +
      + +
      11framework for Ruby
      +12EOF
      +13    usa.should == uk
      +14  end
      +
      +
      + +
      + should print diff of different objects' pretty representation +
      +
      expected <Animal
      +name=bob,
      +species=tortoise
      +>
      +, got <Animal
      +name=bob,
      +species=giraffe
      +>
      + (using .eql?)
      +Diff:
      +@@ -1,5 +1,5 @@
      + <Animal
      + name=bob,
      +-species=giraffe
      ++species=tortoise
      + >
      +
      +
      ./failing_examples/mocking_example.rb:33:
      +./spec/spec/runner/formatter/html_formatter_spec.rb:18:
      +./spec/spec/runner/formatter/html_formatter_spec.rb:14:in `chdir'
      +./spec/spec/runner/formatter/html_formatter_spec.rb:14:
      +
      32    expected = Animal.new "bob", "giraffe"
      +33    actual   = Animal.new "bob", "tortoise"
      +34    expected.should eql(actual)
      +35  end
      +36end
      +
      +
      +
      +
      +
      +
      +
      A consumer of a stub
      + +
      should be able to stub methods on any Object
      +
      +
      +
      +
      +
      A stubbed method on a class
      + +
      should return the stubbed value
      + +
      should revert to the original method after each spec
      + +
      can stub! and mock the same message
      +
      +
      +
      +
      +
      A mock
      + +
      can stub!
      + +
      can stub! and mock
      + +
      can stub! and mock the same message
      +
      +
      +
      +
      +
      pending example (using pending method)
      + + +
      should be reported as "PENDING: for some reason" (PENDING: for some reason)
      +
      +
      +
      +
      +
      pending example (with no block)
      + + +
      should be reported as "PENDING: Not Yet Implemented" (PENDING: Not Yet Implemented)
      +
      +
      +
      +
      +
      pending example (with block for pending)
      + + +
      should have a failing block, passed to pending, reported as "PENDING: for some reason" (PENDING: for some reason)
      +
      +
      + + +
      +
      + + diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/runner/heckle_runner_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/runner/heckle_runner_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/runner/heckle_runner_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/runner/heckle_runner_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,78 @@ +require File.dirname(__FILE__) + '/../../spec_helper.rb' +unless [/mswin/, /java/].detect{|p| p =~ RUBY_PLATFORM} + require 'spec/runner/heckle_runner' + + module Foo + class Bar + def one; end + def two; end + end + + class Zap + def three; end + def four; end + end + end + + describe "HeckleRunner" do + before(:each) do + @heckle = mock("heckle", :null_object => true) + @heckle_class = mock("heckle_class") + end + + it "should heckle all methods in all classes in a module" do + @heckle_class.should_receive(:new).with("Foo::Bar", "one", rspec_options).and_return(@heckle) + @heckle_class.should_receive(:new).with("Foo::Bar", "two", rspec_options).and_return(@heckle) + @heckle_class.should_receive(:new).with("Foo::Zap", "three", rspec_options).and_return(@heckle) + @heckle_class.should_receive(:new).with("Foo::Zap", "four", rspec_options).and_return(@heckle) + + heckle_runner = Spec::Runner::HeckleRunner.new("Foo", @heckle_class) + heckle_runner.heckle_with + end + + it "should heckle all methods in a class" do + @heckle_class.should_receive(:new).with("Foo::Bar", "one", rspec_options).and_return(@heckle) + @heckle_class.should_receive(:new).with("Foo::Bar", "two", rspec_options).and_return(@heckle) + + heckle_runner = Spec::Runner::HeckleRunner.new("Foo::Bar", @heckle_class) + heckle_runner.heckle_with + end + + it "should fail heckling when the class is not found" do + lambda do + heckle_runner = Spec::Runner::HeckleRunner.new("Foo::Bob", @heckle_class) + heckle_runner.heckle_with + end.should raise_error(StandardError, "Heckling failed - \"Foo::Bob\" is not a known class or module") + end + + it "should heckle specific method in a class (with #)" do + @heckle_class.should_receive(:new).with("Foo::Bar", "two", rspec_options).and_return(@heckle) + + heckle_runner = Spec::Runner::HeckleRunner.new("Foo::Bar#two", @heckle_class) + heckle_runner.heckle_with + end + + it "should heckle specific method in a class (with .)" do + @heckle_class.should_receive(:new).with("Foo::Bar", "two", rspec_options).and_return(@heckle) + + heckle_runner = Spec::Runner::HeckleRunner.new("Foo::Bar.two", @heckle_class) + heckle_runner.heckle_with + end + end + + describe "Heckler" do + it "should say yes to tests_pass? if specs pass" do + options = mock("options", :null_object => true) + options.should_receive(:run_examples).and_return(true) + heckler = Spec::Runner::Heckler.new("Foo", nil, options) + heckler.tests_pass?.should be_true + end + + it "should say no to tests_pass? if specs fail" do + options = mock("options", :null_object => true) + options.should_receive(:run_examples).and_return(false) + heckler = Spec::Runner::Heckler.new("Foo", nil, options) + heckler.tests_pass?.should be_false + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/runner/heckler_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/runner/heckler_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/runner/heckler_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/runner/heckler_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,13 @@ +require File.dirname(__FILE__) + '/../../spec_helper.rb' +unless [/mswin/, /java/].detect{|p| p =~ RUBY_PLATFORM} + require 'spec/runner/heckle_runner' + + describe "Heckler" do + it "should run examples on tests_pass?" do + options = Spec::Runner::Options.new(StringIO.new, StringIO.new) + options.should_receive(:run_examples).with().and_return(&options.method(:run_examples)) + heckler = Spec::Runner::Heckler.new('Array', 'push', options) + heckler.tests_pass? + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/runner/noisy_backtrace_tweaker_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/runner/noisy_backtrace_tweaker_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/runner/noisy_backtrace_tweaker_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/runner/noisy_backtrace_tweaker_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,45 @@ +require File.dirname(__FILE__) + '/../../spec_helper.rb' + +module Spec + module Runner + describe "NoisyBacktraceTweaker" do + before(:each) do + @error = RuntimeError.new + @tweaker = NoisyBacktraceTweaker.new + end + + it "should leave anything in lib spec dir" do + ["expectations", "mocks", "runner", "stubs"].each do |child| + @error.set_backtrace(["/lib/spec/#{child}/anything.rb"]) + @tweaker.tweak_backtrace(@error, "spec name") + @error.backtrace.should_not be_empty + end + end + + it "should leave anything in spec dir" do + @error.set_backtrace(["/lib/spec/expectations/anything.rb"]) + @tweaker.tweak_backtrace(@error, "spec name") + @error.backtrace.should_not be_empty + end + + it "should leave bin spec" do + @error.set_backtrace(["bin/spec:"]) + @tweaker.tweak_backtrace(@error, "spec name") + @error.backtrace.should_not be_empty + end + + it "should not barf on nil backtrace" do + lambda do + @tweaker.tweak_backtrace(@error, "spec name") + end.should_not raise_error + end + + it "should clean up double slashes" do + @error.set_backtrace(["/a//b/c//d.rb"]) + @tweaker.tweak_backtrace(@error, "spec name") + @error.backtrace.should include("/a/b/c/d.rb") + end + + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/runner/object_ext_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/runner/object_ext_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/runner/object_ext_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/runner/object_ext_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,11 @@ +require File.dirname(__FILE__) + '/../../spec_helper.rb' + +module Spec + module Runner + describe "ObjectExt" do + it "should add copy_instance_variables_from to object" do + Object.new.should respond_to(:copy_instance_variables_from) + end + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/runner/option_parser_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/runner/option_parser_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/runner/option_parser_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/runner/option_parser_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,366 @@ +require File.dirname(__FILE__) + '/../../spec_helper.rb' + +describe "OptionParser" do + before(:each) do + @out = StringIO.new + @err = StringIO.new + @parser = Spec::Runner::OptionParser.new(@err, @out) + end + + def parse(args) + @parser.parse(args) + @parser.options + end + + it "should accept dry run option" do + options = parse(["--dry-run"]) + options.dry_run.should be_true + end + + it "should eval and use custom formatter when none of the builtins" do + options = parse(["--format", "Custom::Formatter"]) + options.formatters[0].class.should be(Custom::Formatter) + end + + it "should support formatters with relative and absolute paths, even on windows" do + options = parse([ + "--format", "Custom::Formatter:C:\\foo\\bar", + "--format", "Custom::Formatter:foo/bar", + "--format", "Custom::Formatter:foo\\bar", + "--format", "Custom::Formatter:/foo/bar" + ]) + options.formatters[0].where.should eql("C:\\foo\\bar") + options.formatters[1].where.should eql("foo/bar") + options.formatters[2].where.should eql("foo\\bar") + options.formatters[3].where.should eql("/foo/bar") + end + + it "should not be verbose by default" do + options = parse([]) + options.verbose.should be_nil + end + + it "should not use colour by default" do + options = parse([]) + options.colour.should == false + end + + it "should print help to stdout if no args" do + pending 'A regression since 1.0.8' do + options = parse([]) + @out.rewind + @out.read.should match(/Usage: spec \(FILE\|DIRECTORY\|GLOB\)\+ \[options\]/m) + end + end + + it "should print help to stdout" do + options = parse(["--help"]) + @out.rewind + @out.read.should match(/Usage: spec \(FILE\|DIRECTORY\|GLOB\)\+ \[options\]/m) + end + + it "should print instructions about how to require missing formatter" do + lambda do + options = parse(["--format", "Custom::MissingFormatter"]) + options.formatters + end.should raise_error(NameError) + @err.string.should match(/Couldn't find formatter class Custom::MissingFormatter/n) + end + + it "should print version to stdout" do + options = parse(["--version"]) + @out.rewind + @out.read.should match(/RSpec-\d+\.\d+\.\d+.*\(r\d+\) - BDD for Ruby\nhttp:\/\/rspec.rubyforge.org\/\n/n) + end + + it "should require file when require specified" do + lambda do + parse(["--require", "whatever"]) + end.should raise_error(LoadError) + end + + it "should support c option" do + options = parse(["-c"]) + options.colour.should be_true + end + + it "should support queens colour option" do + options = parse(["--colour"]) + options.colour.should be_true + end + + it "should support us color option" do + options = parse(["--color"]) + options.colour.should be_true + end + + it "should support single example with -e option" do + options = parse(["-e", "something or other"]) + options.examples.should eql(["something or other"]) + end + + it "should support single example with -s option (will be removed when autotest supports -e)" do + options = parse(["-s", "something or other"]) + options.examples.should eql(["something or other"]) + end + + it "should support single example with --example option" do + options = parse(["--example", "something or other"]) + options.examples.should eql(["something or other"]) + end + + it "should read several example names from file if --example is given an existing file name" do + options = parse(["--example", File.dirname(__FILE__) + '/examples.txt']) + options.examples.should eql([ + "Sir, if you were my husband, I would poison your drink.", + "Madam, if you were my wife, I would drink it."]) + end + + it "should read no examples if given an empty file" do + options = parse(["--example", File.dirname(__FILE__) + '/empty_file.txt']) + options.examples.should eql([]) + end + + it "should use html formatter when format is h" do + options = parse(["--format", "h"]) + options.formatters[0].class.should equal(Spec::Runner::Formatter::HtmlFormatter) + end + + it "should use html formatter when format is html" do + options = parse(["--format", "html"]) + options.formatters[0].class.should equal(Spec::Runner::Formatter::HtmlFormatter) + end + + it "should use html formatter with explicit output when format is html:test.html" do + FileUtils.rm 'test.html' if File.exist?('test.html') + options = parse(["--format", "html:test.html"]) + options.formatters # creates the file + File.should be_exist('test.html') + options.formatters[0].class.should equal(Spec::Runner::Formatter::HtmlFormatter) + options.formatters[0].close + FileUtils.rm 'test.html' + end + + it "should use noisy backtrace tweaker with b option" do + options = parse(["-b"]) + options.backtrace_tweaker.should be_instance_of(Spec::Runner::NoisyBacktraceTweaker) + end + + it "should use noisy backtrace tweaker with backtrace option" do + options = parse(["--backtrace"]) + options.backtrace_tweaker.should be_instance_of(Spec::Runner::NoisyBacktraceTweaker) + end + + it "should use quiet backtrace tweaker by default" do + options = parse([]) + options.backtrace_tweaker.should be_instance_of(Spec::Runner::QuietBacktraceTweaker) + end + + it "should use progress bar formatter by default" do + options = parse([]) + options.formatters[0].class.should equal(Spec::Runner::Formatter::ProgressBarFormatter) + end + + it "should use specdoc formatter when format is s" do + options = parse(["--format", "s"]) + options.formatters[0].class.should equal(Spec::Runner::Formatter::SpecdocFormatter) + end + + it "should use specdoc formatter when format is specdoc" do + options = parse(["--format", "specdoc"]) + options.formatters[0].class.should equal(Spec::Runner::Formatter::SpecdocFormatter) + end + + it "should support diff option when format is not specified" do + options = parse(["--diff"]) + options.diff_format.should == :unified + end + + it "should use unified diff format option when format is unified" do + options = parse(["--diff", "unified"]) + options.diff_format.should == :unified + options.differ_class.should equal(Spec::Expectations::Differs::Default) + end + + it "should use context diff format option when format is context" do + options = parse(["--diff", "context"]) + options.diff_format.should == :context + options.differ_class.should == Spec::Expectations::Differs::Default + end + + it "should use custom diff format option when format is a custom format" do + Spec::Expectations.differ.should_not be_instance_of(Custom::Differ) + + options = parse(["--diff", "Custom::Differ"]) + options.parse_diff "Custom::Differ" + options.diff_format.should == :custom + options.differ_class.should == Custom::Differ + Spec::Expectations.differ.should be_instance_of(Custom::Differ) + end + + it "should print instructions about how to fix missing differ" do + lambda { parse(["--diff", "Custom::MissingFormatter"]) }.should raise_error(NameError) + @err.string.should match(/Couldn't find differ class Custom::MissingFormatter/n) + end + + it "should support --line to identify spec" do + spec_parser = mock("spec_parser") + @parser.instance_variable_set('@spec_parser', spec_parser) + + file_factory = mock("File") + file_factory.should_receive(:file?).and_return(true) + file_factory.should_receive(:open).and_return("fake_io") + @parser.instance_variable_set('@file_factory', file_factory) + + spec_parser.should_receive(:spec_name_for).with("fake_io", 169).and_return("some spec") + + options = parse(["some file", "--line", "169"]) + options.examples.should eql(["some spec"]) + File.rspec_verify + end + + it "should fail with error message if file is dir along with --line" do + spec_parser = mock("spec_parser") + @parser.instance_variable_set('@spec_parser', spec_parser) + + file_factory = mock("File") + file_factory.should_receive(:file?).and_return(false) + file_factory.should_receive(:directory?).and_return(true) + @parser.instance_variable_set('@file_factory', file_factory) + + options = parse(["some file", "--line", "169"]) + @err.string.should match(/You must specify one file, not a directory when using the --line option/n) + end + + it "should fail with error message if file does not exist along with --line" do + spec_parser = mock("spec_parser") + @parser.instance_variable_set('@spec_parser', spec_parser) + + file_factory = mock("File") + file_factory.should_receive(:file?).and_return(false) + file_factory.should_receive(:directory?).and_return(false) + @parser.instance_variable_set('@file_factory', file_factory) + + options = parse(["some file", "--line", "169"]) + @err.string.should match(/some file does not exist/n) + end + + it "should fail with error message if more than one files are specified along with --line" do + spec_parser = mock("spec_parser") + @parser.instance_variable_set('@spec_parser', spec_parser) + + options = parse(["some file", "some other file", "--line", "169"]) + @err.string.should match(/Only one file can be specified when using the --line option/n) + end + + it "should fail with error message if --example and --line are used simultaneously" do + spec_parser = mock("spec_parser") + @parser.instance_variable_set('@spec_parser', spec_parser) + + options = parse(["some file", "--example", "some example", "--line", "169"]) + @err.string.should match(/You cannot use both --line and --example/n) + end + + if [/mswin/, /java/].detect{|p| p =~ RUBY_PLATFORM} + it "should barf when --heckle is specified (and platform is windows)" do + lambda do + options = parse(["--heckle", "Spec"]) + end.should raise_error(StandardError, "Heckle not supported on Windows") + end + else + it "should heckle when --heckle is specified (and platform is not windows)" do + options = parse(["--heckle", "Spec"]) + options.heckle_runner.should be_instance_of(Spec::Runner::HeckleRunner) + end + end + + it "should read options from file when --options is specified" do + options = parse(["--options", File.dirname(__FILE__) + "/spec.opts"]) + options.diff_format.should_not be_nil + options.colour.should be_true + end + + it "should default the formatter to ProgressBarFormatter when using options file" do + options = parse(["--options", File.dirname(__FILE__) + "/spec.opts"]) + options.formatters.first.should be_instance_of(::Spec::Runner::Formatter::ProgressBarFormatter) + end + + it "should read spaced and multi-line options from file when --options is specified" do + options = parse(["--options", File.dirname(__FILE__) + "/spec_spaced.opts"]) + options.diff_format.should_not be_nil + options.colour.should be_true + options.formatters.first.should be_instance_of(::Spec::Runner::Formatter::SpecdocFormatter) + end + + it "should save config to file when --generate-options is specified" do + FileUtils.rm 'test.spec.opts' if File.exist?('test.spec.opts') + options = parse(["--colour", "--generate-options", "test.spec.opts", "--diff"]) + IO.read('test.spec.opts').should == "--colour\n--diff\n" + FileUtils.rm 'test.spec.opts' + end + + it "should save config to file when -G is specified" do + FileUtils.rm 'test.spec.opts' if File.exist?('test.spec.opts') + options = parse(["--colour", "-G", "test.spec.opts", "--diff"]) + IO.read('test.spec.opts').should == "--colour\n--diff\n" + FileUtils.rm 'test.spec.opts' + end + + it "when --drb is specified, calls DrbCommandLine all of the other ARGV arguments" do + options = Spec::Runner::OptionParser.parse([ + "some/spec.rb", "--diff", "--colour" + ], @err, @out) + Spec::Runner::DrbCommandLine.should_receive(:run).and_return do |options| + options.argv.should == ["some/spec.rb", "--diff", "--colour"] + end + parse(["some/spec.rb", "--diff", "--drb", "--colour"]) + end + + it "should reverse spec order when --reverse is specified" do + options = parse(["some/spec.rb", "--reverse"]) + end + + it "should set an mtime comparator when --loadby mtime" do + options = parse(["--loadby", 'mtime']) + runner = Spec::Runner::ExampleGroupRunner.new(options) + Spec::Runner::ExampleGroupRunner.should_receive(:new). + with(options). + and_return(runner) + runner.should_receive(:load_files).with(["most_recent_spec.rb", "command_line_spec.rb"]) + + Dir.chdir(File.dirname(__FILE__)) do + options.files << 'command_line_spec.rb' + options.files << 'most_recent_spec.rb' + FileUtils.touch "most_recent_spec.rb" + options.run_examples + FileUtils.rm "most_recent_spec.rb" + end + end + + it "should use the standard runner by default" do + runner = ::Spec::Runner::ExampleGroupRunner.new(@parser.options) + ::Spec::Runner::ExampleGroupRunner.should_receive(:new). + with(@parser.options). + and_return(runner) + options = parse([]) + options.run_examples + end + + it "should use a custom runner when given" do + runner = Custom::ExampleGroupRunner.new(@parser.options, nil) + Custom::ExampleGroupRunner.should_receive(:new). + with(@parser.options, nil). + and_return(runner) + options = parse(["--runner", "Custom::ExampleGroupRunner"]) + options.run_examples + end + + it "should use a custom runner with extra options" do + runner = Custom::ExampleGroupRunner.new(@parser.options, 'something') + Custom::ExampleGroupRunner.should_receive(:new). + with(@parser.options, 'something'). + and_return(runner) + options = parse(["--runner", "Custom::ExampleGroupRunner:something"]) + options.run_examples + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/runner/options_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/runner/options_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/runner/options_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/runner/options_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,294 @@ +require File.dirname(__FILE__) + '/../../spec_helper.rb' + +module Spec + module Runner + describe Options do + before(:each) do + @err = StringIO.new('') + @out = StringIO.new('') + @options = Options.new(@err, @out) + end + + after(:each) do + Spec::Expectations.differ = nil + end + + describe Options, "#examples" do + it "defaults to empty array" do + @options.examples.should == [] + end + end + + describe Options, "#backtrace_tweaker" do + it "defaults to QuietBacktraceTweaker" do + @options.backtrace_tweaker.class.should == QuietBacktraceTweaker + end + end + + describe Options, "#dry_run" do + it "defaults to false" do + @options.dry_run.should == false + end + end + + describe Options, "#context_lines" do + it "defaults to 3" do + @options.context_lines.should == 3 + end + end + + describe Options, "#parse_diff with nil" do + before do + @options.parse_diff nil + end + + it "should make diff_format unified" do + @options.diff_format.should == :unified + end + + it "should set Spec::Expectations.differ to be a default differ" do + Spec::Expectations.differ.class.should == + ::Spec::Expectations::Differs::Default + end + end + + describe Options, "#parse_diff with 'unified'" do + before do + @options.parse_diff 'unified' + end + + it "should make diff_format unified and uses default differ_class" do + @options.diff_format.should == :unified + @options.differ_class.should equal(Spec::Expectations::Differs::Default) + end + + it "should set Spec::Expectations.differ to be a default differ" do + Spec::Expectations.differ.class.should == + ::Spec::Expectations::Differs::Default + end + end + + describe Options, "#parse_diff with 'context'" do + before do + @options.parse_diff 'context' + end + + it "should make diff_format context and uses default differ_class" do + @options.diff_format.should == :context + @options.differ_class.should == Spec::Expectations::Differs::Default + end + + it "should set Spec::Expectations.differ to be a default differ" do + Spec::Expectations.differ.class.should == + ::Spec::Expectations::Differs::Default + end + end + + describe Options, "#parse_diff with Custom::Differ" do + before do + @options.parse_diff 'Custom::Differ' + end + + it "should use custom differ_class" do + @options.diff_format.should == :custom + @options.differ_class.should == Custom::Differ + Spec::Expectations.differ.should be_instance_of(Custom::Differ) + end + + it "should set Spec::Expectations.differ to be a default differ" do + Spec::Expectations.differ.class.should == + ::Custom::Differ + end + end + + describe Options, "#parse_diff with missing class name" do + it "should raise error" do + lambda { @options.parse_diff "Custom::MissingDiffer" }.should raise_error(NameError) + @err.string.should match(/Couldn't find differ class Custom::MissingDiffer/n) + end + end + + describe Options, "#parse_example" do + it "with argument thats not a file path, sets argument as the example" do + example = "something or other" + File.file?(example).should == false + @options.parse_example example + @options.examples.should eql(["something or other"]) + end + + it "with argument that is a file path, sets examples to contents of the file" do + example = "#{File.dirname(__FILE__)}/examples.txt" + File.should_receive(:file?).with(example).and_return(true) + file = StringIO.new("Sir, if you were my husband, I would poison your drink.\nMadam, if you were my wife, I would drink it.") + File.should_receive(:open).with(example).and_return(file) + + @options.parse_example example + @options.examples.should eql([ + "Sir, if you were my husband, I would poison your drink.", + "Madam, if you were my wife, I would drink it." + ]) + end + end + + describe Options, "#examples_should_not_be_run" do + it "should cause #run_examples to return true and do nothing" do + @options.examples_should_not_be_run + ExampleGroupRunner.should_not_receive(:new) + + @options.run_examples.should be_true + end + end + + describe Options, "#load_class" do + it "should raise error when not class name" do + lambda do + @options.send(:load_class, 'foo', 'fruit', '--food') + end.should raise_error('"foo" is not a valid class name') + end + end + + describe Options, "#reporter" do + it "returns a Reporter" do + @options.reporter.should be_instance_of(Reporter) + @options.reporter.options.should === @options + end + end + + describe Options, "#add_example_group affecting passed in behaviour" do + it "runs all examples when options.examples is nil" do + example_1_has_run = false + example_2_has_run = false + @behaviour = Class.new(::Spec::Example::ExampleGroup).describe("Some Examples") do + it "runs 1" do + example_1_has_run = true + end + it "runs 2" do + example_2_has_run = true + end + end + + @options.examples = nil + + @options.add_example_group @behaviour + @options.run_examples + example_1_has_run.should be_true + example_2_has_run.should be_true + end + + it "keeps all example_definitions when options.examples is empty" do + example_1_has_run = false + example_2_has_run = false + @behaviour = Class.new(::Spec::Example::ExampleGroup).describe("Some Examples") do + it "runs 1" do + example_1_has_run = true + end + it "runs 2" do + example_2_has_run = true + end + end + + @options.examples = [] + + @options.add_example_group @behaviour + @options.run_examples + example_1_has_run.should be_true + example_2_has_run.should be_true + end + end + + describe Options, "#add_example_group affecting behaviours" do + it "adds behaviour when behaviour has example_definitions and is not shared" do + @behaviour = Class.new(::Spec::Example::ExampleGroup).describe("Some Examples") do + it "uses this behaviour" do + end + end + + @options.number_of_examples.should == 0 + @options.add_example_group @behaviour + @options.number_of_examples.should == 1 + @options.example_groups.length.should == 1 + end + end + + describe Options, "#remove_example_group" do + it "should remove the ExampleGroup from the list of ExampleGroups" do + @example_group = Class.new(::Spec::Example::ExampleGroup).describe("Some Examples") do + end + @options.add_example_group @example_group + @options.example_groups.should include(@example_group) + + @options.remove_example_group @example_group + @options.example_groups.should_not include(@example_group) + end + end + + describe Options, "#run_examples" do + it "should use the standard runner by default" do + runner = ::Spec::Runner::ExampleGroupRunner.new(@options) + ::Spec::Runner::ExampleGroupRunner.should_receive(:new). + with(@options). + and_return(runner) + @options.user_input_for_runner = nil + + @options.run_examples + end + + it "should use a custom runner when given" do + runner = Custom::ExampleGroupRunner.new(@options, nil) + Custom::ExampleGroupRunner.should_receive(:new). + with(@options, nil). + and_return(runner) + @options.user_input_for_runner = "Custom::ExampleGroupRunner" + + @options.run_examples + end + + it "should use a custom runner with extra options" do + runner = Custom::ExampleGroupRunner.new(@options, 'something') + Custom::ExampleGroupRunner.should_receive(:new). + with(@options, 'something'). + and_return(runner) + @options.user_input_for_runner = "Custom::ExampleGroupRunner:something" + + @options.run_examples + end + + describe Options, "#run_examples when there are behaviours" do + before do + @options.add_example_group Class.new(::Spec::Example::ExampleGroup) + @options.formatters << Formatter::BaseTextFormatter.new(@options, @out) + end + + it "runs the Examples and outputs the result" do + @options.run_examples + @out.string.should include("0 examples, 0 failures") + end + + it "sets #examples_run? to true" do + @options.examples_run?.should be_false + @options.run_examples + @options.examples_run?.should be_true + end + end + + describe Options, "#run_examples when there are no behaviours" do + before do + @options.formatters << Formatter::BaseTextFormatter.new(@options, @out) + end + + it "does not run Examples and does not output a result" do + @options.run_examples + @out.string.should_not include("examples") + @out.string.should_not include("failures") + end + + it "sets #examples_run? to false" do + @options.examples_run?.should be_false + @options.run_examples + @options.examples_run?.should be_false + end + end + end + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/runner/output_one_time_fixture.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/runner/output_one_time_fixture.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/runner/output_one_time_fixture.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/runner/output_one_time_fixture.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,7 @@ +require File.dirname(__FILE__) + '/../../spec_helper.rb' + +describe "Running an Example" do + it "should not output twice" do + true.should be_true + end +end \ No newline at end of file diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/runner/output_one_time_fixture_runner.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/runner/output_one_time_fixture_runner.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/runner/output_one_time_fixture_runner.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/runner/output_one_time_fixture_runner.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,8 @@ +dir = File.dirname(__FILE__) +require "#{dir}/../../spec_helper" + +triggering_double_output = rspec_options +options = Spec::Runner::OptionParser.parse( + ["#{dir}/output_one_time_fixture.rb"], $stderr, $stdout +) +Spec::Runner::CommandLine.run(options) diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/runner/output_one_time_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/runner/output_one_time_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/runner/output_one_time_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/runner/output_one_time_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,16 @@ +require File.dirname(__FILE__) + '/../../spec_helper.rb' + +module Spec + module Runner + describe CommandLine do + it "should not output twice" do + dir = File.dirname(__FILE__) + Dir.chdir("#{dir}/../../..") do + output =`ruby #{dir}/output_one_time_fixture_runner.rb` + output.should include("1 example, 0 failures") + output.should_not include("0 examples, 0 failures") + end + end + end + end +end \ No newline at end of file diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/runner/quiet_backtrace_tweaker_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/runner/quiet_backtrace_tweaker_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/runner/quiet_backtrace_tweaker_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/runner/quiet_backtrace_tweaker_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,56 @@ +require File.dirname(__FILE__) + '/../../spec_helper.rb' + +module Spec + module Runner + describe "QuietBacktraceTweaker" do + before(:each) do + @error = RuntimeError.new + @tweaker = QuietBacktraceTweaker.new + end + + it "should not barf on nil backtrace" do + lambda do + @tweaker.tweak_backtrace(@error, "spec name") + end.should_not raise_error + end + + it "should remove anything from textmate ruby bundle" do + @error.set_backtrace(["/Applications/TextMate.app/Contents/SharedSupport/Bundles/Ruby.tmbundle/Support/tmruby.rb:147"]) + @tweaker.tweak_backtrace(@error, "spec name") + @error.backtrace.should be_empty + end + + it "should remove anything in lib spec dir" do + ["expectations", "mocks", "runner"].each do |child| + element="/lib/spec/#{child}/anything.rb" + @error.set_backtrace([element]) + @tweaker.tweak_backtrace(@error, "spec name") + unless (@error.backtrace.empty?) + raise("Should have tweaked away '#{element}'") + end + end + end + + it "should remove mock_frameworks/rspec" do + element = "mock_frameworks/rspec" + @error.set_backtrace([element]) + @tweaker.tweak_backtrace(@error, "spec name") + unless (@error.backtrace.empty?) + raise("Should have tweaked away '#{element}'") + end + end + + it "should remove bin spec" do + @error.set_backtrace(["bin/spec:"]) + @tweaker.tweak_backtrace(@error, "spec name") + @error.backtrace.should be_empty + end + + it "should clean up double slashes" do + @error.set_backtrace(["/a//b/c//d.rb"]) + @tweaker.tweak_backtrace(@error, "spec name") + @error.backtrace.should include("/a/b/c/d.rb") + end + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/runner/reporter_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/runner/reporter_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/runner/reporter_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/runner/reporter_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,191 @@ +require File.dirname(__FILE__) + '/../../spec_helper.rb' + +module Spec + module Runner + + ReporterSpecHelper = describe "reporter spec helpers", :shared => true do + before(:each) do + @io = StringIO.new + @options = Options.new(StringIO.new, @io) + @backtrace_tweaker = stub("backtrace tweaker", :tweak_backtrace => nil) + @options.backtrace_tweaker = @backtrace_tweaker + @formatter = mock("formatter") + @options.formatters << @formatter + @reporter = Reporter.new(@options) + end + + def failure + Mocks::DuckTypeArgConstraint.new(:header, :exception) + end + + def description(s) + Spec::Example::ExampleGroupDescription.new(s) + end + end + + describe Reporter do + include ReporterSpecHelper + + it "should assign itself as the reporter to options" do + @options.reporter.should equal(@reporter) + end + + it "should tell formatter when behaviour is added" do + @formatter.should_receive(:add_example_group).with(description("behaviour")) + @reporter.add_example_group(description("behaviour")) + end + + it "should handle multiple behaviours with same name" do + @formatter.should_receive(:add_example_group).exactly(3).times + @formatter.should_receive(:example_started).exactly(3).times + @formatter.should_receive(:example_passed).exactly(3).times + @formatter.should_receive(:start_dump) + @formatter.should_receive(:dump_pending) + @formatter.should_receive(:close).with(no_args) + @formatter.should_receive(:dump_summary).with(anything(), 3, 0, 0) + @reporter.add_example_group(description("behaviour")) + @reporter.example_started("spec 1") + @reporter.example_finished("spec 1") + @reporter.add_example_group(description("behaviour")) + @reporter.example_started("spec 2") + @reporter.example_finished("spec 2") + @reporter.add_example_group(description("behaviour")) + @reporter.example_started("spec 3") + @reporter.example_finished("spec 3") + @reporter.dump + end + + it "should handle multiple examples with the same name" do + error=RuntimeError.new + @formatter.should_receive(:add_example_group).exactly(2).times + @formatter.should_receive(:example_passed).with("example").exactly(2).times + @formatter.should_receive(:example_failed).with("example", 1, failure) + @formatter.should_receive(:example_failed).with("example", 2, failure) + @formatter.should_receive(:dump_failure).exactly(2).times + @formatter.should_receive(:start_dump) + @formatter.should_receive(:dump_pending) + @formatter.should_receive(:close).with(no_args) + @formatter.should_receive(:dump_summary).with(anything(), 4, 2, 0) + @backtrace_tweaker.should_receive(:tweak_backtrace).twice + @reporter.add_example_group(description("behaviour")) + @reporter.example_finished("example") + @reporter.example_finished("example", error) + @reporter.add_example_group(description("behaviour")) + @reporter.example_finished("example") + @reporter.example_finished("example", error) + @reporter.dump + end + + it "should push stats to formatter even with no data" do + @formatter.should_receive(:start_dump) + @formatter.should_receive(:dump_pending) + @formatter.should_receive(:dump_summary).with(anything(), 0, 0, 0) + @formatter.should_receive(:close).with(no_args) + @reporter.dump + end + + it "should push time to formatter" do + @formatter.should_receive(:start).with(5) + @formatter.should_receive(:start_dump) + @formatter.should_receive(:dump_pending) + @formatter.should_receive(:close).with(no_args) + @formatter.should_receive(:dump_summary) do |time, a, b| + time.to_s.should match(/[0-9].[0-9|e|-]+/) + end + @reporter.start(5) + @reporter.end + @reporter.dump + end + end + + describe Reporter, "reporting one passing example" do + include ReporterSpecHelper + + it "should tell formatter example passed" do + @formatter.should_receive(:example_passed) + @reporter.example_finished("example") + end + + it "should not delegate to backtrace tweaker" do + @formatter.should_receive(:example_passed) + @backtrace_tweaker.should_not_receive(:tweak_backtrace) + @reporter.example_finished("example") + end + + it "should account for passing example in stats" do + @formatter.should_receive(:example_passed) + @formatter.should_receive(:start_dump) + @formatter.should_receive(:dump_pending) + @formatter.should_receive(:dump_summary).with(anything(), 1, 0, 0) + @formatter.should_receive(:close).with(no_args) + @reporter.example_finished("example") + @reporter.dump + end + end + + describe Reporter, "reporting one failing example" do + include ReporterSpecHelper + + it "should tell formatter that example failed" do + @formatter.should_receive(:example_failed) + @reporter.example_finished("example", RuntimeError.new) + end + + it "should delegate to backtrace tweaker" do + @formatter.should_receive(:example_failed) + @backtrace_tweaker.should_receive(:tweak_backtrace) + @reporter.example_finished("spec", RuntimeError.new) + end + + it "should account for failing example in stats" do + @formatter.should_receive(:add_example_group) + @formatter.should_receive(:example_failed).with("example", 1, failure) + @formatter.should_receive(:start_dump) + @formatter.should_receive(:dump_pending) + @formatter.should_receive(:dump_failure).with(1, anything()) + @formatter.should_receive(:dump_summary).with(anything(), 1, 1, 0) + @formatter.should_receive(:close).with(no_args) + @reporter.add_example_group(description("behaviour")) + @reporter.example_finished("example", RuntimeError.new) + @reporter.dump + end + + end + + describe Reporter, "reporting one pending example (ExamplePendingError)" do + include ReporterSpecHelper + + it "should tell formatter example is pending" do + @formatter.should_receive(:example_pending).with(description("behaviour"), "example", "reason") + @formatter.should_receive(:add_example_group).with(description("behaviour")) + @reporter.add_example_group(description('behaviour')) + @reporter.example_finished("example", Spec::Example::ExamplePendingError.new("reason"), nil, false) + end + + it "should account for pending example in stats" do + @formatter.should_receive(:example_pending).with(description("behaviour"), "example", "reason") + @formatter.should_receive(:start_dump) + @formatter.should_receive(:dump_pending) + @formatter.should_receive(:dump_summary).with(anything(), 1, 0, 1) + @formatter.should_receive(:close).with(no_args) + @formatter.should_receive(:add_example_group).with(description("behaviour")) + @reporter.add_example_group(description('behaviour')) + @reporter.example_finished("example", Spec::Example::ExamplePendingError.new("reason"), nil, false) + @reporter.dump + end + end + + describe Reporter, "reporting one pending example (PendingExampleFixedError)" do + include ReporterSpecHelper + + it "should tell formatter pending example is fixed" do + @formatter.should_receive(:example_failed) do |name, counter, failure| + failure.header.should == "'behaviour example' FIXED" + end + @formatter.should_receive(:add_example_group).with(description("behaviour")) + @reporter.add_example_group(description('behaviour')) + @reporter.example_finished("example", Spec::Example::PendingExampleFixedError.new("reason"), nil, false) + end + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/runner/spec.opts technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/runner/spec.opts --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/runner/spec.opts 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/runner/spec.opts 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,2 @@ +--diff +--colour \ No newline at end of file diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/runner/spec_parser_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/runner/spec_parser_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/runner/spec_parser_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/runner/spec_parser_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,124 @@ +require File.dirname(__FILE__) + '/../../spec_helper.rb' + +describe "c" do + + it "1" do + end + + it "2" do + end + +end + +describe "d" do + + it "3" do + end + + it "4" do + end + +end + +class SpecParserSubject +end + +describe SpecParserSubject do + + it "5" do + end + +end + +describe SpecParserSubject, "described" do + + it "6" do + end + +end + +describe SpecParserSubject, "described", :something => :something_else do + + it "7" do + end + +end + +describe "described", :something => :something_else do + + it "8" do + end + +end + + +describe "SpecParser" do + before(:each) do + @p = Spec::Runner::SpecParser.new + end + + it "should find spec name for 'specify' at same line" do + @p.spec_name_for(File.open(__FILE__), 5).should == "c 1" + end + + it "should find spec name for 'specify' at end of spec line" do + @p.spec_name_for(File.open(__FILE__), 6).should == "c 1" + end + + it "should find context for 'context' above all specs" do + @p.spec_name_for(File.open(__FILE__), 4).should == "c" + end + + it "should find spec name for 'it' at same line" do + @p.spec_name_for(File.open(__FILE__), 15).should == "d 3" + end + + it "should find spec name for 'it' at end of spec line" do + @p.spec_name_for(File.open(__FILE__), 16).should == "d 3" + end + + it "should find context for 'describe' above all specs" do + @p.spec_name_for(File.open(__FILE__), 14).should == "d" + end + + it "should find nearest example name between examples" do + @p.spec_name_for(File.open(__FILE__), 7).should == "c 1" + end + + it "should find nothing outside a context" do + @p.spec_name_for(File.open(__FILE__), 2).should be_nil + end + + it "should find context name for type" do + @p.spec_name_for(File.open(__FILE__), 26).should == "SpecParserSubject" + end + + it "should find context and spec name for type" do + @p.spec_name_for(File.open(__FILE__), 28).should == "SpecParserSubject 5" + end + + it "should find context and description for type" do + @p.spec_name_for(File.open(__FILE__), 33).should == "SpecParserSubject described" + end + + it "should find context and description and example for type" do + @p.spec_name_for(File.open(__FILE__), 36).should == "SpecParserSubject described 6" + end + + it "should find context and description for type with modifications" do + @p.spec_name_for(File.open(__FILE__), 40).should == "SpecParserSubject described" + end + + it "should find context and described and example for type with modifications" do + @p.spec_name_for(File.open(__FILE__), 43).should == "SpecParserSubject described 7" + end + + it "should find example group" do + @p.spec_name_for(File.open(__FILE__), 47).should == "described" + end + + it "should find example" do + @p.spec_name_for(File.open(__FILE__), 50).should == "described 8" + end + +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/runner/spec_spaced.opts technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/runner/spec_spaced.opts --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/runner/spec_spaced.opts 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/runner/spec_spaced.opts 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,2 @@ +--diff --colour +--format s \ No newline at end of file diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/runner_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/runner_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/runner_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/runner_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,11 @@ +require File.dirname(__FILE__) + '/../spec_helper.rb' + +module Spec + describe Runner, ".configure" do + it "should yield global configuration" do + Spec::Runner.configure do |config| + config.should equal(Spec::Runner.configuration) + end + end + end +end \ No newline at end of file diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/spec_classes.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/spec_classes.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/spec_classes.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/spec_classes.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,129 @@ +# This file contains various classes used by the specs. +module Spec + module Expectations + class Person + attr_reader :name + def initialize name + @name = name + end + def == other + return @name == other.name + end + end + + class ClassWithMultiWordPredicate + def multi_word_predicate? + true + end + end + + module Helper + class CollectionWithSizeMethod + def initialize; @list = []; end + def size; @list.size; end + def push(item); @list.push(item); end + end + + class CollectionWithLengthMethod + def initialize; @list = []; end + def length; @list.size; end + def push(item); @list.push(item); end + end + + class CollectionOwner + attr_reader :items_in_collection_with_size_method, :items_in_collection_with_length_method + + def initialize + @items_in_collection_with_size_method = CollectionWithSizeMethod.new + @items_in_collection_with_length_method = CollectionWithLengthMethod.new + end + + def add_to_collection_with_size_method(item) + @items_in_collection_with_size_method.push(item) + end + + def add_to_collection_with_length_method(item) + @items_in_collection_with_length_method.push(item) + end + + def items_for(arg) + return [1, 2, 3] if arg == 'a' + [1] + end + + end + + class HandCodedMock + include Spec::Matchers + def initialize(return_val) + @return_val = return_val + @funny_called = false + end + + def funny? + @funny_called = true + @return_val + end + + def hungry?(a, b, c) + a.should equal(1) + b.should equal(2) + c.should equal(3) + @funny_called = true + @return_val + end + + def exists? + @return_val + end + + def multi_word_predicate? + @return_val + end + + def rspec_verify + @funny_called.should be_true + end + end + class ClassWithUnqueriedPredicate + attr_accessor :foo + def initialize(foo) + @foo = foo + end + end + end + end +end + +module Custom + class Formatter < Spec::Runner::Formatter::BaseTextFormatter + attr_reader :options, :where + + def initialize(options, where) + @options = options + @where = where + end + end + + class BadFormatter < Spec::Runner::Formatter::BaseTextFormatter + attr_reader :where + + def initialize(options, where) + bad_method + end + end + + class Differ + attr_reader :options + def initialize(options) + @options = options + end + end +end + +class FakeReporter < Spec::Runner::Reporter + attr_reader :added_behaviour + def add_example_group(description) + @added_behaviour = description + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/story/builders.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/story/builders.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/story/builders.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/story/builders.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,46 @@ +module Spec + module Story + class StoryBuilder + def initialize + @title = 'a story' + @narrative = 'narrative' + end + + def title(value) + @title = value + self + end + + def narrative(value) + @narrative = value + self + end + + def to_story(&block) + block = lambda {} unless block_given? + Story.new @title, @narrative, &block + end + end + + class ScenarioBuilder + def initialize + @name = 'a scenario' + @story = StoryBuilder.new.to_story + end + + def name(value) + @name = value + self + end + + def story(value) + @story = value + self + end + + def to_scenario(&block) + Scenario.new @story, @name, &block + end + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/story/extensions/main_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/story/extensions/main_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/story/extensions/main_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/story/extensions/main_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,161 @@ +require File.dirname(__FILE__) + '/../../../spec_helper' + +module Spec + module Story + module Extensions + describe "the main object extended with Main", :shared => true do + before(:each) do + @main = Class.new do; include Main; end + @original_rspec_story_steps, $rspec_story_steps = $rspec_story_steps, nil + end + + after(:each) do + $rspec_story_steps = @original_rspec_story_steps + end + + def have_step(type, name) + return simple_matcher(%[step group containing a #{type} named #{name.inspect}]) do |actual| + Spec::Story::Step === actual.find(type, name) + end + end + end + + describe Main, "#run_story" do + it_should_behave_like "the main object extended with Main" + + it "should create a PlainTextStoryRunner with run_story" do + Spec::Story::Runner::PlainTextStoryRunner.should_receive(:new).and_return(mock("runner", :null_object => true)) + @main.run_story + end + + it "should yield the runner if arity == 1" do + File.should_receive(:read).with("some/path").and_return("Story: foo") + $main_spec_runner = nil + @main.run_story("some/path") do |runner| + $main_spec_runner = runner + end + $main_spec_runner.should be_an_instance_of(Spec::Story::Runner::PlainTextStoryRunner) + end + + it "should run in the runner if arity == 0" do + File.should_receive(:read).with("some/path").and_return("Story: foo") + $main_spec_runner = nil + @main.run_story("some/path") do + $main_spec_runner = self + end + $main_spec_runner.should be_an_instance_of(Spec::Story::Runner::PlainTextStoryRunner) + end + + it "should tell the PlainTextStoryRunner to run with run_story" do + runner = mock("runner") + Spec::Story::Runner::PlainTextStoryRunner.should_receive(:new).and_return(runner) + runner.should_receive(:run) + @main.run_story + end + end + + describe Main, "#steps_for" do + it_should_behave_like "the main object extended with Main" + + it "should have no steps for a non existent key" do + @main.steps_for(:key).find(:given, "foo").should be_nil + end + + it "should create steps for a key" do + $main_spec_invoked = false + @main.steps_for(:key) do + Given("foo") { + $main_spec_invoked = true + } + end + @main.steps_for(:key).find(:given, "foo").perform(Object.new, "foo") + $main_spec_invoked.should be_true + end + + it "should append steps to steps_for a given key" do + @main.steps_for(:key) do + Given("first") {} + end + @main.steps_for(:key) do + Given("second") {} + end + @main.steps_for(:key).should have_step(:given, "first") + @main.steps_for(:key).should have_step(:given, "second") + end + end + + describe Main, "#with_steps_for adding new steps" do + it_should_behave_like "the main object extended with Main" + + it "should result in a group containing pre-existing steps and newly defined steps" do + first_group = @main.steps_for(:key) do + Given("first") {} + end + second_group = @main.with_steps_for(:key) do + Given("second") {} + end + + second_group.should have_step(:given, "first") + second_group.should have_step(:given, "second") + end + + it "should not add its steps to the existing group" do + first_group = @main.steps_for(:key) do + Given("first") {} + end + second_group = @main.with_steps_for(:key) do + Given("second") {} + end + + first_group.should have_step(:given, "first") + first_group.should_not have_step(:given, "second") + end + end + + describe Main, "#with_steps_for running a story" do + it_should_behave_like "the main object extended with Main" + + before(:each) do + @runner = mock("runner") + @runner_step_group = StepGroup.new + @runner.stub!(:steps).and_return(@runner_step_group) + @runner.stub!(:run) + Spec::Story::Runner::PlainTextStoryRunner.stub!(:new).and_return(@runner) + end + + it "should create a PlainTextStoryRunner with a path" do + Spec::Story::Runner::PlainTextStoryRunner.should_receive(:new).with('path/to/file',{}).and_return(@runner) + @main.with_steps_for(:foo) do + run 'path/to/file' + end + end + + it "should create a PlainTextStoryRunner with a path and options" do + Spec::Story::Runner::PlainTextStoryRunner.should_receive(:new).with(anything,{:bar => :baz}).and_return(@runner) + @main.with_steps_for(:foo) do + run 'path/to/file', :bar => :baz + end + end + + it "should pass the group it creates to the runner's steps" do + steps = @main.steps_for(:ice_cream) do + Given("vanilla") {} + end + @main.with_steps_for(:ice_cream) do + run 'foo' + end + @runner_step_group.should have_step(:given, "vanilla") + end + + it "should run a story" do + @runner.should_receive(:run) + Spec::Story::Runner::PlainTextStoryRunner.should_receive(:new).and_return(@runner) + @main.with_steps_for(:foo) do + run 'path/to/file' + end + end + + end + end + end +end \ No newline at end of file diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/story/extensions_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/story/extensions_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/story/extensions_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/story/extensions_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,14 @@ +require File.dirname(__FILE__) + '/story_helper' + +require 'spec/story' + +describe Kernel, "#Story" do + before(:each) do + Kernel.stub!(:at_exit) + end + + it "should delegate to ::Spec::Story::Runner.story_runner" do + ::Spec::Story::Runner.story_runner.should_receive(:Story) + story = Story("title","narrative"){} + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/story/given_scenario_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/story/given_scenario_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/story/given_scenario_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/story/given_scenario_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,27 @@ +require File.dirname(__FILE__) + '/story_helper' + +module Spec + module Story + describe GivenScenario do + it 'should execute a scenario from the current story in its world' do + # given + class MyWorld + attr :scenario_ran + end + instance = World.create(MyWorld) + scenario = ScenarioBuilder.new.to_scenario do + @scenario_ran = true + end + Runner::StoryRunner.should_receive(:scenario_from_current_story).with('scenario name').and_return(scenario) + + step = GivenScenario.new 'scenario name' + + # when + step.perform(instance, nil) + + # then + ensure_that instance.scenario_ran, is(true) + end + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/story/rspec_adapter.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/story/rspec_adapter.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/story/rspec_adapter.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/story/rspec_adapter.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,51 @@ +# TODO: get rid of this file. It breaks with the style in the rest of our code. (AH) + +# add ensure_that(..) +module Spec::Expectations::ObjectExpectations + def ensure_that(obj, expr) + obj.should expr + end +end + +def exception_from(&block) + exception = nil + begin + yield + rescue StandardError => e + exception = e + end + exception +end + +# simplify matchers + + +# custom matchers + +def contain(string) + return simple_matcher(%[string containing "#{string}"]) do |actual| + actual.include? string + end +end + +alias :contains :contain + +def is(expected) + return simple_matcher("equal to #{expected}") do |actual| actual == expected end +end + +alias :are :is + +def is_a(type) + return simple_matcher("object of type #{type}") do |actual| + actual.is_a? type + end +end + +alias :is_an :is_a + +def matches(pattern) + return simple_matcher("string matching #{pattern}") do |actual| + actual =~ pattern + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/story/runner/plain_text_story_runner_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/story/runner/plain_text_story_runner_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/story/runner/plain_text_story_runner_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/story/runner/plain_text_story_runner_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,92 @@ +require File.dirname(__FILE__) + '/../story_helper' + +module Spec + module Story + module Runner + describe PlainTextStoryRunner do + before(:each) do + StoryParser.stub!(:new).and_return(@parser = mock("parser")) + @parser.stub!(:parse).and_return([]) + File.stub!(:read).with("path").and_return("this\nand that") + end + + it "should provide access to steps" do + runner = PlainTextStoryRunner.new("path") + + runner.steps do |add| + add.given("baz") {} + end + + runner.steps.find(:given, "baz").should_not be_nil + end + + it "should parse a story file" do + runner = PlainTextStoryRunner.new("path") + + during { + runner.run + }.expect { + @parser.should_receive(:parse).with(["this", "and that"]) + } + end + + it "should build up a mediator with its own steps and the singleton story_runner" do + runner = PlainTextStoryRunner.new("path") + Spec::Story::Runner.should_receive(:story_runner).and_return(story_runner = mock("story runner")) + Spec::Story::Runner::StoryMediator.should_receive(:new).with(runner.steps, story_runner, {}). + and_return(mediator = stub("mediator", :run_stories => nil)) + runner.run + end + + it "should build up a parser with the mediator" do + runner = PlainTextStoryRunner.new("path") + Spec::Story::Runner.should_receive(:story_runner).and_return(story_runner = mock("story runner")) + Spec::Story::Runner::StoryMediator.should_receive(:new).and_return(mediator = stub("mediator", :run_stories => nil)) + Spec::Story::Runner::StoryParser.should_receive(:new).with(mediator).and_return(@parser) + runner.run + end + + it "should tell the mediator to run the stories" do + runner = PlainTextStoryRunner.new("path") + mediator = mock("mediator") + Spec::Story::Runner::StoryMediator.should_receive(:new).and_return(mediator) + mediator.should_receive(:run_stories) + runner.run + end + + it "should accept a block instead of a path" do + runner = PlainTextStoryRunner.new do |runner| + runner.load("path/to/story") + end + File.should_receive(:read).with("path/to/story").and_return("this\nand that") + runner.run + end + + it "should tell you if you try to run with no path set" do + runner = PlainTextStoryRunner.new + lambda { + runner.run + }.should raise_error(RuntimeError, "You must set a path to the file with the story. See the RDoc.") + end + + it "should pass options to the mediator" do + runner = PlainTextStoryRunner.new("path", :foo => :bar) + Spec::Story::Runner::StoryMediator.should_receive(:new). + with(anything, anything, :foo => :bar). + and_return(mediator = stub("mediator", :run_stories => nil)) + runner.run + end + + it "should provide access to its options" do + runner = PlainTextStoryRunner.new("path") + runner[:foo] = :bar + Spec::Story::Runner::StoryMediator.should_receive(:new). + with(anything, anything, :foo => :bar). + and_return(mediator = stub("mediator", :run_stories => nil)) + runner.run + end + + end + end + end +end \ No newline at end of file diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/story/runner/scenario_collector_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/story/runner/scenario_collector_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/story/runner/scenario_collector_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/story/runner/scenario_collector_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,27 @@ +require File.dirname(__FILE__) + '/../story_helper' + +module Spec + module Story + module Runner + describe ScenarioCollector do + it 'should construct scenarios with the supplied story' do + # given + story = stub_everything('story') + scenario_collector = ScenarioCollector.new(story) + + # when + scenario_collector.Scenario 'scenario1' do end + scenario_collector.Scenario 'scenario2' do end + scenarios = scenario_collector.scenarios + + # then + ensure_that scenarios.size, is(2) + ensure_that scenarios[0].name, is('scenario1') + ensure_that scenarios[0].story, is(story) + ensure_that scenarios[1].name, is('scenario2') + ensure_that scenarios[1].story, is(story) + end + end + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/story/runner/scenario_runner_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/story/runner/scenario_runner_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/story/runner/scenario_runner_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/story/runner/scenario_runner_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,146 @@ +require File.dirname(__FILE__) + '/../story_helper' + +module Spec + module Story + module Runner + describe ScenarioRunner do + it 'should run a scenario in its story' do + # given + world = stub_everything + scenario_runner = ScenarioRunner.new + $answer = nil + story = Story.new 'story', 'narrative' do + @answer = 42 # this should be available to the scenario + end + scenario = Scenario.new story, 'scenario' do + $answer = @answer + end + + # when + scenario_runner.run(scenario, world) + + # then + ensure_that $answer, is(42) + end + + it 'should allow scenarios to share methods' do + # given + world = stub_everything + $shared_invoked = 0 + story = Story.new 'story', 'narrative' do + def shared + $shared_invoked += 1 + end + end + scenario1 = Scenario.new story, 'scenario1' do + shared() + end + scenario2 = Scenario.new story, 'scenario2' do + shared() + end + scenario_runner = ScenarioRunner.new + + # when + scenario_runner.run(scenario1, world) + scenario_runner.run(scenario2, world) + + # then + $shared_invoked.should == 2 + end + + it 'should notify listeners when a scenario starts' do + # given + world = stub_everything + story = Story.new 'story', 'narrative' do end + scenario = Scenario.new story, 'scenario1' do + # succeeds + end + scenario_runner = ScenarioRunner.new + mock_listener1 = stub_everything('listener1') + mock_listener2 = stub_everything('listener2') + scenario_runner.add_listener(mock_listener1) + scenario_runner.add_listener(mock_listener2) + + # expect + mock_listener1.should_receive(:scenario_started).with('story', 'scenario1') + mock_listener2.should_receive(:scenario_started).with('story', 'scenario1') + + # when + scenario_runner.run(scenario, world) + + # then + # TODO verify_all + end + + it 'should notify listeners when a scenario succeeds' do + # given + world = stub_everything('world') + story = Story.new 'story', 'narrative' do end + scenario = Scenario.new story, 'scenario1' do + # succeeds + end + scenario_runner = ScenarioRunner.new + mock_listener1 = stub_everything('listener1') + mock_listener2 = stub_everything('listener2') + scenario_runner.add_listener(mock_listener1) + scenario_runner.add_listener(mock_listener2) + + # expect + mock_listener1.should_receive(:scenario_succeeded).with('story', 'scenario1') + mock_listener2.should_receive(:scenario_succeeded).with('story', 'scenario1') + + # when + scenario_runner.run(scenario, world) + + # then + # TODO verify_all + end + + it 'should notify listeners when a scenario raises an error' do + # given + error = RuntimeError.new('oops') + story = Story.new 'title', 'narrative' do end + scenario = Scenario.new story, 'scenario1' do + end + scenario_runner = ScenarioRunner.new + mock_listener = stub_everything('listener') + scenario_runner.add_listener(mock_listener) + world = stub_everything + + # expect + world.should_receive(:errors).twice.and_return([error]) + mock_listener.should_receive(:scenario_failed).with('title', 'scenario1', error) + + # when + scenario_runner.run scenario, world + + # then + # TODO verify_all + end + + it 'should notify listeners when a scenario is pending' do + # given + pending_error = Spec::Example::ExamplePendingError.new('todo') + story = Story.new 'title', 'narrative' do end + scenario = Scenario.new story, 'scenario1' do + end + scenario_runner = ScenarioRunner.new + mock_listener = mock('listener') + scenario_runner.add_listener(mock_listener) + world = stub_everything + + # expect + world.should_receive(:errors).twice.and_return([pending_error]) + mock_listener.should_receive(:scenario_started).with('title', 'scenario1') + mock_listener.should_receive(:scenario_pending).with('title', 'scenario1', 'todo') + + # when + scenario_runner.run scenario, world + + # then + # TODO verify_all + end + end + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/story/runner/story_mediator_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/story/runner/story_mediator_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/story/runner/story_mediator_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/story/runner/story_mediator_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,133 @@ +require File.dirname(__FILE__) + '/../story_helper' + +module Spec + module Story + module Runner + + describe StoryMediator do + before(:each) do + $story_mediator_spec_value = nil + @step_group = StepGroup.new + @step_group.create_matcher(:given, "given") { $story_mediator_spec_value = "given matched" } + @step_group.create_matcher(:when, "when") { $story_mediator_spec_value = "when matched" } + @step_group.create_matcher(:then, "then") { $story_mediator_spec_value = "then matched" } + + @scenario_runner = ScenarioRunner.new + @runner = StoryRunner.new @scenario_runner + @mediator = StoryMediator.new @step_group, @runner + end + + def run_stories + @mediator.run_stories + @runner.run_stories + end + + it "should have no stories" do + @mediator.stories.should be_empty + end + + it "should create two stories" do + @mediator.create_story "story title", "story narrative" + @mediator.create_story "story title 2", "story narrative 2" + run_stories + + @runner.should have(2).stories + @runner.stories.first.title.should == "story title" + @runner.stories.first.narrative.should == "story narrative" + @runner.stories.last.title.should == "story title 2" + @runner.stories.last.narrative.should == "story narrative 2" + end + + it "should create a scenario" do + @mediator.create_story "title", "narrative" + @mediator.create_scenario "scenario name" + run_stories + + @runner.should have(1).scenarios + @runner.scenarios.first.name.should == "scenario name" + @runner.scenarios.first.story.should == @runner.stories.first + end + + it "should create a given scenario step if one matches" do + pending("need to untangle the dark mysteries of the story runner - something needs to get stubbed here") do + story = @mediator.create_story "title", "narrative" + @mediator.create_scenario "previous scenario" + @mediator.create_scenario "current scenario" + @mediator.create_given_scenario "previous scenario" + run_stories + + $story_mediator_spec_value.should == "previous scenario matched" + end + end + + it "should create a given step if one matches" do + @mediator.create_story "title", "narrative" + @mediator.create_scenario "scenario" + @mediator.create_given "given" + run_stories + + $story_mediator_spec_value.should == "given matched" + end + + it "should create a pending step if no given step matches" do + @mediator.create_story "title", "narrative" + @mediator.create_scenario "scenario" + @mediator.create_given "no match" + mock_listener = stub_everything("listener") + mock_listener.should_receive(:scenario_pending).with("title", "scenario", "Unimplemented step: no match") + @scenario_runner.add_listener mock_listener + run_stories + end + + it "should create a when step if one matches" do + @mediator.create_story "title", "narrative" + @mediator.create_scenario "scenario" + @mediator.create_when "when" + run_stories + + $story_mediator_spec_value.should == "when matched" + end + + it "should create a pending step if no when step matches" do + @mediator.create_story "title", "narrative" + @mediator.create_scenario "scenario" + @mediator.create_when "no match" + mock_listener = stub_everything("listener") + mock_listener.should_receive(:scenario_pending).with("title", "scenario", "Unimplemented step: no match") + @scenario_runner.add_listener mock_listener + run_stories + end + + it "should create a then step if one matches" do + @mediator.create_story "title", "narrative" + @mediator.create_scenario "scenario" + @mediator.create_then "then" + run_stories + + $story_mediator_spec_value.should == "then matched" + end + + it "should create a pending step if no 'then' step matches" do + @mediator.create_story "title", "narrative" + @mediator.create_scenario "scenario" + @mediator.create_then "no match" + mock_listener = stub_everything("listener") + mock_listener.should_receive(:scenario_pending).with("title", "scenario", "Unimplemented step: no match") + @scenario_runner.add_listener mock_listener + run_stories + end + + it "should pass options to the stories it creates" do + @mediator = StoryMediator.new @step_group, @runner, :foo => :bar + @mediator.create_story "story title", "story narrative" + + run_stories + + @runner.stories.first[:foo].should == :bar + end + + end + + end + end +end \ No newline at end of file diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/story/runner/story_parser_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/story/runner/story_parser_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/story/runner/story_parser_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/story/runner/story_parser_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,384 @@ +require File.dirname(__FILE__) + '/../story_helper' + +module Spec + module Story + module Runner + + describe StoryParser do + before(:each) do + @story_mediator = mock("story_mediator") + @parser = StoryParser.new(@story_mediator) + end + + it "should parse no lines" do + @parser.parse([]) + end + + it "should ignore text before the first Story: begins" do + @story_mediator.should_not_receive(:create_scenario) + @story_mediator.should_not_receive(:create_given) + @story_mediator.should_not_receive(:create_when) + @story_mediator.should_not_receive(:create_then) + @story_mediator.should_receive(:create_story).with("simple addition", "") + @parser.parse(["Here is a bunch of text", "about a calculator and all the things", "that it will do", "Story: simple addition"]) + end + + it "should create a story" do + @story_mediator.should_receive(:create_story).with("simple addition", "") + @parser.parse(["Story: simple addition"]) + end + + it "should create a story when line has leading spaces" do + @story_mediator.should_receive(:create_story).with("simple addition", "") + @parser.parse([" Story: simple addition"]) + end + + it "should add a one line narrative to the story" do + @story_mediator.should_receive(:create_story).with("simple addition","narrative") + @parser.parse(["Story: simple addition","narrative"]) + end + + it "should add a multi line narrative to the story" do + @story_mediator.should_receive(:create_story).with("simple addition","narrative line 1\nline 2\nline 3") + @parser.parse(["Story: simple addition","narrative line 1", "line 2", "line 3"]) + end + + it "should exclude blank lines from the narrative" do + @story_mediator.should_receive(:create_story).with("simple addition","narrative line 1\nline 2") + @parser.parse(["Story: simple addition","narrative line 1", "", "line 2"]) + end + + it "should exclude Scenario from the narrative" do + @story_mediator.should_receive(:create_story).with("simple addition","narrative line 1\nline 2") + @story_mediator.should_receive(:create_scenario) + @parser.parse(["Story: simple addition","narrative line 1", "line 2", "Scenario: add one plus one"]) + end + + end + + describe StoryParser, "in Story state" do + before(:each) do + @story_mediator = mock("story_mediator") + @parser = StoryParser.new(@story_mediator) + @story_mediator.stub!(:create_story) + end + + it "should create a second Story for Story" do + @story_mediator.should_receive(:create_story).with("number two","") + @parser.parse(["Story: s", "Story: number two"]) + end + + it "should include And in the narrative" do + @story_mediator.should_receive(:create_story).with("s","And foo") + @story_mediator.should_receive(:create_scenario).with("bar") + @parser.parse(["Story: s", "And foo", "Scenario: bar"]) + end + + it "should create a Scenario for Scenario" do + @story_mediator.should_receive(:create_scenario).with("number two") + @parser.parse(["Story: s", "Scenario: number two"]) + end + + it "should include Given in the narrative" do + @story_mediator.should_receive(:create_story).with("s","Given foo") + @story_mediator.should_receive(:create_scenario).with("bar") + @parser.parse(["Story: s", "Given foo", "Scenario: bar"]) + end + + it "should include Given: in the narrative" do + @story_mediator.should_receive(:create_story).with("s","Given: foo") + @story_mediator.should_receive(:create_scenario).with("bar") + @parser.parse(["Story: s", "Given: foo", "Scenario: bar"]) + end + + it "should include When in the narrative" do + @story_mediator.should_receive(:create_story).with("s","When foo") + @story_mediator.should_receive(:create_scenario).with("bar") + @parser.parse(["Story: s", "When foo", "Scenario: bar"]) + end + + it "should include Then in the narrative" do + @story_mediator.should_receive(:create_story).with("s","Then foo") + @story_mediator.should_receive(:create_scenario).with("bar") + @parser.parse(["Story: s", "Then foo", "Scenario: bar"]) + end + + it "should include other in the story" do + @story_mediator.should_receive(:create_story).with("s","narrative") + @parser.parse(["Story: s", "narrative"]) + end + end + + describe StoryParser, "in Scenario state" do + before(:each) do + @story_mediator = mock("story_mediator") + @parser = StoryParser.new(@story_mediator) + @story_mediator.stub!(:create_story) + @story_mediator.stub!(:create_scenario) + end + + it "should create a Story for Story" do + @story_mediator.should_receive(:create_story).with("number two","") + @parser.parse(["Story: s", "Scenario: s", "Story: number two"]) + end + + it "should create a Scenario for Scenario" do + @story_mediator.should_receive(:create_scenario).with("number two") + @parser.parse(["Story: s", "Scenario: s", "Scenario: number two"]) + end + + it "should raise for And" do + lambda { + @parser.parse(["Story: s", "Scenario: s", "And second"]) + }.should raise_error(IllegalStepError, /^Illegal attempt to create a And after a Scenario/) + end + + it "should create a Given for Given" do + @story_mediator.should_receive(:create_given).with("gift") + @parser.parse(["Story: s", "Scenario: s", "Given gift"]) + end + + it "should create a Given for Given:" do + @story_mediator.should_receive(:create_given).with("gift") + @parser.parse(["Story: s", "Scenario: s", "Given: gift"]) + end + + it "should create a GivenScenario for GivenScenario" do + @story_mediator.should_receive(:create_given_scenario).with("previous") + @parser.parse(["Story: s", "Scenario: s", "GivenScenario previous"]) + end + + it "should create a GivenScenario for GivenScenario:" do + @story_mediator.should_receive(:create_given_scenario).with("previous") + @parser.parse(["Story: s", "Scenario: s", "GivenScenario: previous"]) + end + + it "should transition to Given state after GivenScenario" do + @story_mediator.stub!(:create_given_scenario) + @parser.parse(["Story: s", "Scenario: s", "GivenScenario previous"]) + @parser.instance_eval{@state}.should be_an_instance_of(StoryParser::GivenState) + end + + it "should transition to Given state after GivenScenario:" do + @story_mediator.stub!(:create_given_scenario) + @parser.parse(["Story: s", "Scenario: s", "GivenScenario: previous"]) + @parser.instance_eval{@state}.should be_an_instance_of(StoryParser::GivenState) + end + + it "should create a When for When" do + @story_mediator.should_receive(:create_when).with("ever") + @parser.parse(["Story: s", "Scenario: s", "When ever"]) + end + + it "should create a When for When:" do + @story_mediator.should_receive(:create_when).with("ever") + @parser.parse(["Story: s", "Scenario: s", "When: ever"]) + end + + it "should create a Then for Then" do + @story_mediator.should_receive(:create_then).with("and there") + @parser.parse(["Story: s", "Scenario: s", "Then and there"]) + end + + it "should create a Then for Then:" do + @story_mediator.should_receive(:create_then).with("and there") + @parser.parse(["Story: s", "Scenario: s", "Then: and there"]) + end + + it "should ignore other" do + @parser.parse(["Story: s", "Scenario: s", "this is ignored"]) + end + end + + describe StoryParser, "in Given state" do + before(:each) do + @story_mediator = mock("story_mediator") + @parser = StoryParser.new(@story_mediator) + @story_mediator.stub!(:create_story) + @story_mediator.stub!(:create_scenario) + @story_mediator.should_receive(:create_given).with("first") + end + + it "should create a Story for Story" do + @story_mediator.should_receive(:create_story).with("number two","") + @parser.parse(["Story: s", "Scenario: s", "Given first", "Story: number two"]) + end + + it "should create a Scenario for Scenario" do + @story_mediator.should_receive(:create_scenario).with("number two") + @parser.parse(["Story: s", "Scenario: s", "Given first", "Scenario: number two"]) + end + + it "should create a second Given for Given" do + @story_mediator.should_receive(:create_given).with("second") + @parser.parse(["Story: s", "Scenario: s", "Given first", "Given second"]) + end + + it "should create a second Given for And" do + @story_mediator.should_receive(:create_given).with("second") + @parser.parse(["Story: s", "Scenario: s", "Given: first", "And second"]) + end + + it "should create a second Given for And:" do + @story_mediator.should_receive(:create_given).with("second") + @parser.parse(["Story: s", "Scenario: s", "Given first", "And: second"]) + end + + it "should create a When for When" do + @story_mediator.should_receive(:create_when).with("ever") + @parser.parse(["Story: s", "Scenario: s", "Given first", "When ever"]) + end + + it "should create a When for When:" do + @story_mediator.should_receive(:create_when).with("ever") + @parser.parse(["Story: s", "Scenario: s", "Given first", "When: ever"]) + end + + it "should create a Then for Then" do + @story_mediator.should_receive(:create_then).with("and there") + @parser.parse(["Story: s", "Scenario: s", "Given first", "Then and there"]) + end + + it "should create a Then for Then:" do + @story_mediator.should_receive(:create_then).with("and there") + @parser.parse(["Story: s", "Scenario: s", "Given first", "Then: and there"]) + end + + it "should ignore other" do + @parser.parse(["Story: s", "Scenario: s", "Given first", "this is ignored"]) + end + end + + describe StoryParser, "in When state" do + before(:each) do + @story_mediator = mock("story_mediator") + @parser = StoryParser.new(@story_mediator) + @story_mediator.stub!(:create_story) + @story_mediator.stub!(:create_scenario) + @story_mediator.should_receive(:create_given).with("first") + @story_mediator.should_receive(:create_when).with("else") + end + + it "should create a Story for Story" do + @story_mediator.should_receive(:create_story).with("number two","") + @parser.parse(["Story: s", "Scenario: s", "Given first", "When: else", "Story: number two"]) + end + + it "should create a Scenario for Scenario" do + @story_mediator.should_receive(:create_scenario).with("number two") + @parser.parse(["Story: s", "Scenario: s", "Given first", "When else", "Scenario: number two"]) + end + + it "should create Given for Given" do + @story_mediator.should_receive(:create_given).with("second") + @parser.parse(["Story: s", "Scenario: s", "Given first", "When else", "Given second"]) + end + + it "should create Given for Given:" do + @story_mediator.should_receive(:create_given).with("second") + @parser.parse(["Story: s", "Scenario: s", "Given first", "When else", "Given: second"]) + end + + it "should create a second When for When" do + @story_mediator.should_receive(:create_when).with("ever") + @parser.parse(["Story: s", "Scenario: s", "Given first", "When else", "When ever"]) + end + + it "should create a second When for When:" do + @story_mediator.should_receive(:create_when).with("ever") + @parser.parse(["Story: s", "Scenario: s", "Given: first", "When: else", "When: ever"]) + end + + it "should create a second When for And" do + @story_mediator.should_receive(:create_when).with("ever") + @parser.parse(["Story: s", "Scenario: s", "Given first", "When else", "And ever"]) + end + + it "should create a second When for And:" do + @story_mediator.should_receive(:create_when).with("ever") + @parser.parse(["Story: s", "Scenario: s", "Given: first", "When: else", "And: ever"]) + end + + it "should create a Then for Then" do + @story_mediator.should_receive(:create_then).with("and there") + @parser.parse(["Story: s", "Scenario: s", "Given first", "When else", "Then and there"]) + end + + it "should create a Then for Then:" do + @story_mediator.should_receive(:create_then).with("and there") + @parser.parse(["Story: s", "Scenario: s", "Given: first", "When: else", "Then: and there"]) + end + + it "should ignore other" do + @parser.parse(["Story: s", "Scenario: s", "Given first", "When else", "this is ignored"]) + end + end + + describe StoryParser, "in Then state" do + before(:each) do + @story_mediator = mock("story_mediator") + @parser = StoryParser.new(@story_mediator) + @story_mediator.stub!(:create_story) + @story_mediator.stub!(:create_scenario) + @story_mediator.should_receive(:create_given).with("first") + @story_mediator.should_receive(:create_when).with("else") + @story_mediator.should_receive(:create_then).with("what") + end + + it "should create a Story for Story" do + @story_mediator.should_receive(:create_story).with("number two","") + @parser.parse(["Story: s", "Scenario: s", "Given first", "When else", "Then what", "Story: number two"]) + end + + it "should create a Scenario for Scenario" do + @story_mediator.should_receive(:create_scenario).with("number two") + @parser.parse(["Story: s", "Scenario: s", "Given first", "When else", "Then what", "Scenario: number two"]) + end + + it "should create Given for Given" do + @story_mediator.should_receive(:create_given).with("second") + @parser.parse(["Story: s", "Scenario: s", "Given first", "When else", "Then what", "Given second"]) + end + + it "should create Given for Given:" do + @story_mediator.should_receive(:create_given).with("second") + @parser.parse(["Story: s", "Scenario: s", "Given: first", "When: else", "Then: what", "Given: second"]) + end + + it "should create When for When" do + @story_mediator.should_receive(:create_when).with("ever") + @parser.parse(["Story: s", "Scenario: s", "Given first", "When else", "Then what", "When ever"]) + end + + it "should create When for When:" do + @story_mediator.should_receive(:create_when).with("ever") + @parser.parse(["Story: s", "Scenario: s", "Given: first", "When: else", "Then: what", "When: ever"]) + end + + it "should create a Then for Then" do + @story_mediator.should_receive(:create_then).with("and there") + @parser.parse(["Story: s", "Scenario: s", "Given first", "When else", "Then what", "Then and there"]) + end + + it "should create a Then for Then:" do + @story_mediator.should_receive(:create_then).with("and there") + @parser.parse(["Story: s", "Scenario: s", "Given: first", "When: else", "Then: what", "Then: and there"]) + end + + it "should create a second Then for And" do + @story_mediator.should_receive(:create_then).with("ever") + @parser.parse(["Story: s", "Scenario: s", "Given first", "When else", "Then what", "And ever"]) + end + + it "should create a second Then for And:" do + @story_mediator.should_receive(:create_then).with("ever") + @parser.parse(["Story: s", "Scenario: s", "Given: first", "When: else", "Then: what", "And: ever"]) + end + + it "should ignore other" do + @parser.parse(["Story: s", "Scenario: s", "Given first", "When else", "Then what", "this is ignored"]) + end + end + end + end +end \ No newline at end of file diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/story/runner/story_runner_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/story/runner/story_runner_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/story/runner/story_runner_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/story/runner/story_runner_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,223 @@ +require File.dirname(__FILE__) + '/../story_helper' + +module Spec + module Story + module Runner + describe StoryRunner do + it 'should collect all the stories' do + # given + story_runner = StoryRunner.new(stub('scenario_runner')) + + # when + story_runner.Story 'title1', 'narrative1' do end + story_runner.Story 'title2', 'narrative2' do end + stories = story_runner.stories + + # then + ensure_that stories.size, is(2) + ensure_that stories[0].title, is('title1') + ensure_that stories[0].narrative, is('narrative1') + ensure_that stories[1].title, is('title2') + ensure_that stories[1].narrative, is('narrative2') + end + + it 'should gather all the scenarios in the stories' do + # given + story_runner = StoryRunner.new(stub('scenario_runner')) + + # when + story_runner.Story "story1", "narrative1" do + Scenario "scenario1" do end + Scenario "scenario2" do end + end + story_runner.Story "story2", "narrative2" do + Scenario "scenario3" do end + end + scenarios = story_runner.scenarios + + # then + ensure_that scenarios.size, is(3) + ensure_that scenarios[0].name, is('scenario1') + ensure_that scenarios[1].name, is('scenario2') + ensure_that scenarios[2].name, is('scenario3') + end + + # captures worlds passed into a ScenarioRunner + class ScenarioWorldCatcher + attr_accessor :worlds + def run(scenario, world) + (@worlds ||= []) << world + end + end + + it 'should run each scenario in a separate object' do + # given + scenario_world_catcher = ScenarioWorldCatcher.new + story_runner = StoryRunner.new(scenario_world_catcher) + story_runner.Story 'story', 'narrative' do + Scenario 'scenario1' do end + Scenario 'scenario2' do end + end + + # when + story_runner.run_stories + + # then + worlds = scenario_world_catcher.worlds + ensure_that worlds.size, is(2) + worlds[0].should_not == worlds[1] + end + + it 'should use the provided world creator to create worlds' do + # given + stub_scenario_runner = stub_everything + mock_world_creator = mock('world creator') + story_runner = StoryRunner.new(stub_scenario_runner, mock_world_creator) + story_runner.Story 'story', 'narrative' do + Scenario 'scenario1' do end + Scenario 'scenario2' do end + end + + # expect + mock_world_creator.should_receive(:create).twice + + # when + story_runner.run_stories + + # then + # TODO verify_all + end + + it 'should notify listeners of the scenario count when the run starts' do + # given + story_runner = StoryRunner.new(stub_everything) + mock_listener1 = stub_everything('listener1') + mock_listener2 = stub_everything('listener2') + story_runner.add_listener(mock_listener1) + story_runner.add_listener(mock_listener2) + + story_runner.Story 'story1', 'narrative1' do + Scenario 'scenario1' do end + end + story_runner.Story 'story2', 'narrative2' do + Scenario 'scenario2' do end + Scenario 'scenario3' do end + end + + # expect + mock_listener1.should_receive(:run_started).with(3) + mock_listener2.should_receive(:run_started).with(3) + + # when + story_runner.run_stories + + # then + # TODO verify_all + end + + it 'should notify listeners when a story starts' do + # given + story_runner = StoryRunner.new(stub_everything) + mock_listener1 = stub_everything('listener1') + mock_listener2 = stub_everything('listener2') + story_runner.add_listener(mock_listener1) + story_runner.add_listener(mock_listener2) + + story_runner.Story 'story1', 'narrative1' do + Scenario 'scenario1' do end + end + story_runner.Story 'story2', 'narrative2' do + Scenario 'scenario2' do end + Scenario 'scenario3' do end + end + + # expect + mock_listener1.should_receive(:story_started).with('story1', 'narrative1') + mock_listener1.should_receive(:story_ended).with('story1', 'narrative1') + mock_listener2.should_receive(:story_started).with('story2', 'narrative2') + mock_listener2.should_receive(:story_ended).with('story2', 'narrative2') + + # when + story_runner.run_stories + + # then + # TODO verify_all + end + + it 'should notify listeners when the run ends' do + # given + story_runner = StoryRunner.new(stub_everything) + mock_listener1 = stub_everything('listener1') + mock_listener2 = stub_everything('listener2') + story_runner.add_listener mock_listener1 + story_runner.add_listener mock_listener2 + story_runner.Story 'story1', 'narrative1' do + Scenario 'scenario1' do end + end + + # expect + mock_listener1.should_receive(:run_ended) + mock_listener2.should_receive(:run_ended) + + # when + story_runner.run_stories + + # then + # TODO verify_all + end + + it 'should run a story in an instance of a specified class' do + # given + scenario_world_catcher = ScenarioWorldCatcher.new + story_runner = StoryRunner.new(scenario_world_catcher) + story_runner.Story 'title', 'narrative', :type => String do + Scenario 'scenario' do end + end + + # when + story_runner.run_stories + + # then + scenario_world_catcher.worlds[0].should be_kind_of(String) + scenario_world_catcher.worlds[0].should be_kind_of(World) + end + + it 'should pass initialization params through to the constructed instance' do + # given + scenario_world_catcher = ScenarioWorldCatcher.new + story_runner = StoryRunner.new(scenario_world_catcher) + story_runner.Story 'title', 'narrative', :type => Array, :args => [3] do + Scenario 'scenario' do end + end + + # when + story_runner.run_stories + + # then + scenario_world_catcher.worlds[0].should be_kind_of(Array) + scenario_world_catcher.worlds[0].size.should == 3 + end + + it 'should find a scenario in the current story by name' do + # given + story_runner = StoryRunner.new(ScenarioRunner.new) + $scenario = nil + + story_runner.Story 'title', 'narrative' do + Scenario 'first scenario' do + end + Scenario 'second scenario' do + $scenario = StoryRunner.scenario_from_current_story 'first scenario' + end + end + + # when + story_runner.run_stories + + # then + $scenario.name.should == 'first scenario' + end + end + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/story/runner_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/story/runner_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/story/runner_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/story/runner_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,106 @@ +require File.dirname(__FILE__) + '/story_helper' + +module Spec + module Story + describe Runner, "module" do + def dev_null + io = StringIO.new + def io.write(str) + str.to_s.size + end + return io + end + + before :each do + Kernel.stub!(:at_exit) + @stdout, $stdout = $stdout, dev_null + @argv = Array.new(ARGV) + @runner_module = Runner.dup + @world_creator = World.dup + @runner_module.module_eval { @run_options = @story_runner = @scenario_runner = @world_creator = nil } + end + + after :each do + $stdout = @stdout + ARGV.replace @argv + @runner_module.module_eval { @run_options = @story_runner = @scenario_runner = @world_creator = nil } + end + + it 'should wire up a singleton StoryRunner' do + @runner_module.story_runner.should_not be_nil + end + + it 'should set its options based on ARGV' do + # given + ARGV << '--dry-run' + + # when + options = @runner_module.run_options + + # then + ensure_that options.dry_run, is(true) + end + + it 'should add a reporter to the runner classes' do + # given + story_runner = mock('story runner', :null_object => true) + scenario_runner = mock('scenario runner', :null_object => true) + world_creator = mock('world', :null_object => true) + + @runner_module::class_eval { @world_creator = world_creator } + @runner_module::StoryRunner.stub!(:new).and_return(story_runner) + @runner_module::ScenarioRunner.stub!(:new).and_return(scenario_runner) + + # expect + world_creator.should_receive(:add_listener).with(an_instance_of(Spec::Runner::Formatter::Story::PlainTextFormatter)) + story_runner.should_receive(:add_listener).with(an_instance_of(Spec::Runner::Formatter::Story::PlainTextFormatter)) + scenario_runner.should_receive(:add_listener).with(an_instance_of(Spec::Runner::Formatter::Story::PlainTextFormatter)) + + # when + @runner_module.story_runner + end + + it 'should add a documenter to the runner classes if one is specified' do + # given + ARGV << "--format" << "html" + story_runner = mock('story runner', :null_object => true) + scenario_runner = mock('scenario runner', :null_object => true) + world_creator = mock('world', :null_object => true) + + @runner_module::class_eval { @world_creator = world_creator } + @runner_module::StoryRunner.stub!(:new).and_return(story_runner) + @runner_module::ScenarioRunner.stub!(:new).and_return(scenario_runner) + + # expect + world_creator.should_receive(:add_listener).with(an_instance_of(Spec::Runner::Formatter::Story::HtmlFormatter)) + story_runner.should_receive(:add_listener).with(an_instance_of(Spec::Runner::Formatter::Story::HtmlFormatter)) + scenario_runner.should_receive(:add_listener).with(an_instance_of(Spec::Runner::Formatter::Story::HtmlFormatter)) + + # when + @runner_module.story_runner + end + + it 'should add any registered listener to the runner classes' do + # given + ARGV << "--format" << "html" + story_runner = mock('story runner', :null_object => true) + scenario_runner = mock('scenario runner', :null_object => true) + world_creator = mock('world', :null_object => true) + + @runner_module::class_eval { @world_creator = world_creator } + @runner_module::StoryRunner.stub!(:new).and_return(story_runner) + @runner_module::ScenarioRunner.stub!(:new).and_return(scenario_runner) + + listener = Object.new + + # expect + world_creator.should_receive(:add_listener).with(listener) + story_runner.should_receive(:add_listener).with(listener) + scenario_runner.should_receive(:add_listener).with(listener) + + # when + @runner_module.register_listener listener + end + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/story/scenario_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/story/scenario_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/story/scenario_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/story/scenario_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,20 @@ +require File.dirname(__FILE__) + '/story_helper' + +module Spec + module Story + describe Scenario do + it 'should not raise an error if no body is supplied' do + # given + story = StoryBuilder.new.to_story + + # when + error = exception_from do + Scenario.new story, 'name' + end + + # then + error.should be_nil + end + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/story/step_group_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/story/step_group_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/story/step_group_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/story/step_group_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,157 @@ +require File.dirname(__FILE__) + '/story_helper' + +module Spec + module Story + describe StepGroup do + before(:each) do + @step_group = StepGroup.new + end + + it "should not find a matcher if empty" do + @step_group.find(:given, "this and that").should be_nil + end + + it "should create a given_scenario matcher" do + step = @step_group.given_scenario("this and that") {} + @step_group.find(:given_scenario, "this and that").should_not be_nil + @step_group.find(:given_scenario, "this and that").should equal(step) + end + + it "should create a given matcher" do + step = @step_group.given("this and that") {} + @step_group.find(:given, "this and that").should equal(step) + end + + it "should create a when matcher" do + step = @step_group.when("this and that") {} + @step_group.find(:when, "this and that").should equal(step) + end + + it "should create a them matcher" do + step = @step_group.then("this and that") {} + @step_group.find(:then, "this and that").should equal(step) + end + + it "should add a matcher object" do + step = Step.new("this and that") {} + @step_group.add(:given, step) + @step_group.find(:given, "this and that").should equal(step) + end + + it "should add it matchers to another StepGroup (with one given)" do + source = StepGroup.new + target = StepGroup.new + step = source.given("this and that") {} + source.add_to target + target.find(:given, "this and that").should equal(step) + end + + it "should add it matchers to another StepGroup (with some of each type)" do + source = StepGroup.new + target = StepGroup.new + given_scenario = source.given_scenario("1") {} + given = source.given("1") {} + when1 = source.when("1") {} + when2 = source.when("2") {} + then1 = source.then("1") {} + then2 = source.then("2") {} + then3 = source.then("3") {} + source.add_to target + target.find(:given_scenario, "1").should equal(given_scenario) + target.find(:given, "1").should equal(given) + target.find(:when, "1").should equal(when1) + target.find(:when, "2").should equal(when2) + target.find(:then, "1").should equal(then1) + target.find(:then, "2").should equal(then2) + target.find(:then, "3").should equal(then3) + end + + it "should append another collection" do + matchers_to_append = StepGroup.new + step = matchers_to_append.given("this and that") {} + @step_group << matchers_to_append + @step_group.find(:given, "this and that").should equal(step) + end + + it "should append several other collections" do + matchers_to_append = StepGroup.new + more_matchers_to_append = StepGroup.new + first_matcher = matchers_to_append.given("this and that") {} + second_matcher = more_matchers_to_append.given("and the other") {} + @step_group << matchers_to_append + @step_group << more_matchers_to_append + @step_group.find(:given, "this and that").should equal(first_matcher) + @step_group.find(:given, "and the other").should equal(second_matcher) + end + + it "should yield itself on initialization" do + begin + $step_group_spec_step = nil + matchers = StepGroup.new do |matchers| + $step_group_spec_step = matchers.given("foo") {} + end + $step_group_spec_step.matches?("foo").should be_true + ensure + $step_group_spec_step = nil + end + end + + it "should support defaults" do + class StepGroupSubclass < StepGroup + steps do |add| + add.given("foo") {} + end + end + StepGroupSubclass.new.find(:given, "foo").should_not be_nil + end + + it "should create a Given" do + sub = Class.new(StepGroup).new + step = sub.Given("foo") {} + sub.find(:given, "foo").should == step + end + + it "should create a When" do + sub = Class.new(StepGroup).new + step = sub.When("foo") {} + sub.find(:when, "foo").should == step + end + + it "should create a Then" do + sub = Class.new(StepGroup).new + step = sub.Then("foo") {} + sub.find(:then, "foo").should == step + end + + it "should create steps in a block" do + sub = Class.new(StepGroup).new do + Given("a given") {} + When("a when") {} + Then("a then") {} + end + sub.find(:given, "a given").should_not be_nil + sub.find(:when, "a when").should_not be_nil + sub.find(:then, "a then").should_not be_nil + end + + it "should clear itself" do + step = @step_group.given("this and that") {} + @step_group.clear + @step_group.find(:given, "this and that").should be_nil + end + + it "should tell you when it is empty" do + @step_group.should be_empty + end + + it "should tell you when it is not empty" do + @step_group.given("this and that") {} + @step_group.should_not be_empty + end + + it "should handle << nil" do + @step_group << nil + end + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/story/step_mother_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/story/step_mother_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/story/step_mother_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/story/step_mother_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,72 @@ +require File.dirname(__FILE__) + '/story_helper' + +module Spec + module Story + describe StepMother do + it 'should store a step by name and type' do + # given + step_mother = StepMother.new + step = Step.new("a given", &lambda {}) + step_mother.store(:given, step) + + # when + found = step_mother.find(:given, "a given") + + # then + found.should == step + end + + it 'should NOT raise an error if a step is missing' do + # given + step_mother = StepMother.new + + # then + lambda do + # when + step_mother.find(:given, "doesn't exist") + end.should_not raise_error + end + + it "should create a default step which raises a pending error" do + # given + step_mother = StepMother.new + + # when + step = step_mother.find(:given, "doesn't exist") + + # then + step.should be_an_instance_of(Step) + + lambda do + step.perform(Object.new, "doesn't exist") + end.should raise_error(Spec::Example::ExamplePendingError, /Unimplemented/) + end + + it 'should clear itself' do + # given + step_mother = StepMother.new + step = Step.new("a given") do end + step_mother.store(:given, step) + + # when + step_mother.clear + + # then + step_mother.should be_empty + end + + it "should use assigned steps" do + step_mother = StepMother.new + + step = Step.new('step') {} + step_group = StepGroup.new + step_group.add(:given, step) + + step_mother.use(step_group) + + step_mother.find(:given, "step").should equal(step) + end + + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/story/step_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/story/step_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/story/step_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/story/step_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,142 @@ +require File.dirname(__FILE__) + '/story_helper' + +module Spec + module Story + describe Step, "matching" do + it "should match a text string" do + step_matcher = Step.new("this text") {} + step_matcher.matches?("this text").should be_true + end + + it "should not match a text string that does not start the same" do + step_matcher = Step.new("this text") {} + step_matcher.matches?("Xthis text").should be_false + end + + it "should not match a text string that does not end the same" do + step_matcher = Step.new("this text") {} + step_matcher.matches?("this textX").should be_false + end + + it "should match a text string with a param" do + step_matcher = Step.new("this $param text") {} + step_matcher.matches?("this anything text").should be_true + end + + it "should match a text string with 3 params" do + step_matcher = Step.new("1 $one 2 $two 3 $three 4") {} + step_matcher.matches?("1 a 2 b 3 c 4").should be_true + end + + it "should match a text string with a param at the beginning" do + step_matcher = Step.new("$one 2 3") {} + step_matcher.matches?("a 2 3").should be_true + end + + it "should match a text string with a param at the end" do + step_matcher = Step.new("1 2 $three") {} + step_matcher.matches?("1 2 c").should be_true + end + + it "should not match a different string" do + step_matcher = Step.new("this text") {} + step_matcher.matches?("other text").should be_false + end + + it "should match a regexp" do + step_matcher = Step.new(/this text/) {} + step_matcher.matches?("this text").should be_true + end + + it "should match a regexp with a match group" do + step_matcher = Step.new(/this (.*) text/) {} + step_matcher.matches?("this anything text").should be_true + end + + it "should not match a non matching regexp" do + step_matcher = Step.new(/this (.*) text/) {} + step_matcher.matches?("other anything text").should be_false + end + + it "should not get bogged down by parens in strings" do + step_matcher = Step.new("before () after") {} + step_matcher.matches?("before () after").should be_true + end + + end + + describe Step do + it "should make complain with no block" do + lambda { + step_matcher = Step.new("foo") + }.should raise_error + end + + it "should perform itself on an object" do + # given + $instance = nil + step = Step.new 'step' do + $instance = self + end + instance = Object.new + + # when + step.perform(instance, "step") + + # then + $instance.should == instance + end + + it "should perform itself with one parameter with match expression" do + # given + $result = nil + step = Step.new 'an account with $count dollars' do |count| + $result = count + end + instance = Object.new + + # when + args = step.parse_args("an account with 3 dollars") + step.perform(instance, *args) + + # then + $result.should == "3" + end + + it "should perform itself with one parameter without a match expression" do + # given + $result = nil + step = Step.new 'an account with a balance of' do |amount| + $result = amount + end + instance = Object.new + + # when + step.perform(instance, 20) + + # then + $result.should == 20 + end + + it "should perform itself with 2 parameters" do + # given + $account_type = nil + $amount = nil + step = Step.new 'a $account_type account with $amount dollars' do |account_type, amount| + $account_type = account_type + $amount = amount + end + instance = Object.new + + # when + args = step.parse_args("a savings account with 3 dollars") + step.perform(instance, *args) + + # then + $account_type.should == "savings" + $amount.should == "3" + end + + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/story/story_helper.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/story/story_helper.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/story/story_helper.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/story/story_helper.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,3 @@ +require File.dirname(__FILE__) + '/../../spec_helper' +require File.dirname(__FILE__) + '/rspec_adapter' +require File.dirname(__FILE__) + '/builders' diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/story/story_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/story/story_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/story/story_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/story/story_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,86 @@ +require File.dirname(__FILE__) + '/story_helper' + +module Spec + module Story + describe Story do + it 'should run itself in a given object' do + # given + $instance = nil + story = Story.new 'title', 'narrative' do + $instance = self + end + object = Object.new + + # when + story.run_in(object) + + # then + $instance.should be(object) + end + + it 'should not raise an error if no block is supplied' do + # when + error = exception_from do + Story.new 'title', 'narrative' + end + + # then + error.should be_nil + end + + it "should raise when error raised running in another object" do + #given + story = Story.new 'title', 'narrative' do + raise "this is raised in the story" + end + object = Object.new + + # when/then + lambda do + story.run_in(object) + end.should raise_error + end + + it "should use the steps it is told to using a StepGroup" do + story = Story.new("title", "narrative", :steps => steps = StepGroup.new) do end + assignee = mock("assignee") + assignee.should_receive(:use).with(steps) + story.assign_steps_to(assignee) + end + + it "should use the steps it is told to using a key" do + begin + orig_rspec_story_steps = $rspec_story_steps + $rspec_story_steps = StepGroupHash.new + $rspec_story_steps[:foo] = steps = Object.new + + story = Story.new("title", "narrative", :steps_for => :foo) do end + assignee = mock("assignee") + + assignee.should_receive(:use).with(steps) + story.assign_steps_to(assignee) + ensure + $rspec_story_steps = orig_rspec_story_steps + end + end + + it "should use the steps it is told to using multiple keys" do + begin + orig_rspec_story_steps = $rspec_story_steps + $rspec_story_steps = StepGroupHash.new + $rspec_story_steps[:foo] = foo_steps = Object.new + $rspec_story_steps[:bar] = bar_steps = Object.new + + story = Story.new("title", "narrative", :steps_for => [:foo, :bar]) do end + assignee = mock("assignee") + + assignee.should_receive(:use).with(foo_steps) + assignee.should_receive(:use).with(bar_steps) + story.assign_steps_to(assignee) + ensure + $rspec_story_steps = orig_rspec_story_steps + end + end + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/story/world_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/story/world_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/story/world_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/story/world_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,419 @@ +require File.dirname(__FILE__) + '/story_helper' + +require 'spec/story' + +module Spec + module Story + describe World do + before :each do + World.listeners.clear + end + + after :each do + World.listeners.clear + World.step_mother.clear + end + + it 'should create an object that mixes in a World' do + # when + obj = World::create + + # then + obj.should be_kind_of(World) + end + + it 'should create a World from any object type' do + # when + obj = World::create String + + # then + obj.should be_kind_of(String) + obj.should be_kind_of(World) + end + + it 'should pass arguments to #new when creating an object of a specified type that mixes in a world' do + # given + Thing = Struct.new(:name, :age) + + # when + obj = World::create Thing, "David", "I'm not telling" + + # then + obj.should be_an_instance_of(Thing) + obj.name.should == "David" + obj.age.should == "I'm not telling" + obj.should be_kind_of(World) + end + + def ensure_world_executes_step(&block) + # given + obj = World::create + $step_ran = false + + # when + obj.instance_eval(&block) + + # then + $step_ran.should be_true + end + + it 'should execute a Given, When or Then step' do + ensure_world_executes_step do + Given 'a given' do + $step_ran = true + end + end + + ensure_world_executes_step do + When 'an event' do + $step_ran = true + end + end + + ensure_world_executes_step do + Then 'an outcome' do + $step_ran = true + end + end + end + + it 'should interpret Given... And... as multiple givens' do + # given + world = World.create + $steps = [] + + # when + world.instance_eval do + Given 'step 1' do + $steps << 1 + end + And 'step 2' do + $steps << 2 + end + end + + # then + $steps.should == [1,2] + World.step_mother.find(:given, 'step 1').should_not be_nil + World.step_mother.find(:given, 'step 2').should_not be_nil + end + + it 'should interpret When... And... as multiple events' do + # given + world = World.create + $steps = [] + + # when + world.instance_eval do + When 'step 1' do + $steps << 1 + end + And 'step 2' do + $steps << 2 + end + end + + # then + $steps.should == [1,2] + World.step_mother.find(:when, 'step 1').should_not be_nil + World.step_mother.find(:when, 'step 2').should_not be_nil + end + + it 'should interpret Then... And... as multiple outcomes' do + # given + world = World.create + $steps = [] + + # when + world.instance_eval do + Then 'step 1' do + $steps << 1 + end + And 'step 2' do + $steps << 2 + end + end + + # then + $steps.should == [1,2] + World.step_mother.find(:then, 'step 1').should_not be_nil + World.step_mother.find(:then, 'step 2').should_not be_nil + end + + it 'should reuse a given across scenarios' do + # given + $num_invoked = 0 + a_world = World::create + a_world.instance_eval do + Given 'a given' do + $num_invoked += 1 + end + end + another_world = World::create + + # when + another_world.instance_eval do + Given 'a given' # without a body + end + + # then + $num_invoked.should == 2 + end + + it 'should reuse an event across scenarios' do + # given + $num_invoked = 0 + a_world = World::create + a_world.instance_eval do + When 'an event' do + $num_invoked += 1 + end + end + + another_world = World::create + + # when + another_world.instance_eval do + When 'an event' # without a body + end + + # then + $num_invoked.should == 2 + end + + it 'should reuse an outcome across scenarios' do + # given + $num_invoked = 0 + a_world = World::create + a_world.instance_eval do + Then 'an outcome' do + $num_invoked += 1 + end + end + + another_world = World::create + + # when + another_world.instance_eval do + Then 'an outcome' # without a body + end + + # then + $num_invoked.should == 2 + end + + it 'should preserve instance variables between steps within a scenario' do + # given + world = World::create + $first = nil + $second = nil + + # when + world.instance_eval do + Given 'given' do + @first = 'first' + end + When 'event' do + @second = @first # from given + end + Then 'outcome' do + $first = @first # from given + $second = @second # from event + end + end + + # then + ensure_that $first, is('first') + ensure_that $second, is('first') + end + + it 'should invoke a reused step in the new object instance' do + # given + $instances = [] + $debug = true + world1 = World.create + world1.instance_eval do + Given 'a given' do + $instances << self.__id__ + end + end + world2 = World.create + + # when + world2.instance_eval do + Given 'a given' # reused + Then 'an outcome' do + $instances << __id__ + end + end + $debug = false + # then + $instances.should == [ world1.__id__, world2.__id__, world2.__id__ ] + end + + def ensure_world_collects_error(expected_error, &block) + # given + world = World.create + # $error = nil + + # when + world.start_collecting_errors + world.instance_eval(&block) + + # then + world.should have(1).errors + world.errors[0].should be_kind_of(expected_error) + end + + it 'should collect a failure from a Given step' do + ensure_world_collects_error RuntimeError do + Given 'a given' do + raise RuntimeError, "oops" + end + end + end + + it 'should collect a failure from a When step' do + ensure_world_collects_error RuntimeError do + When 'an event' do + raise RuntimeError, "oops" + end + end + end + + it 'should collect a failure from a Then step' do + ensure_world_collects_error RuntimeError do + Then 'an outcome' do + raise RuntimeError, "oops" + end + end + end + + it 'should inform listeners when it runs a Given, When or Then step' do + # given + world = World.create + mock_listener1 = mock('listener1') + mock_listener2 = mock('listener2') + World.add_listener(mock_listener1) + World.add_listener(mock_listener2) + + # expect + mock_listener1.should_receive(:step_succeeded).with(:given, 'a context') + mock_listener1.should_receive(:step_succeeded).with(:when, 'an event') + mock_listener1.should_receive(:step_succeeded).with(:then, 'an outcome') + + mock_listener2.should_receive(:step_succeeded).with(:given, 'a context') + mock_listener2.should_receive(:step_succeeded).with(:when, 'an event') + mock_listener2.should_receive(:step_succeeded).with(:then, 'an outcome') + + # when + world.instance_eval do + Given 'a context' do end + When 'an event' do end + Then 'an outcome' do end + end + + # then + # TODO verify_all + end + + it 'should tell listeners but not execute the step in dry-run mode' do + # given + Runner.stub!(:dry_run).and_return(true) + mock_listener = mock('listener') + World.add_listener(mock_listener) + $step_invoked = false + world = World.create + + # expect + mock_listener.should_receive(:step_succeeded).with(:given, 'a context') + + # when + world.instance_eval do + Given 'a context' do + $step_invoked = true + end + end + + # then + # TODO verify_all + $step_invoked.should be(false) + end + + it 'should suppress listeners while it runs a GivenScenario' do + # given + $scenario_ran = false + + scenario = ScenarioBuilder.new.name('a scenario').to_scenario do + $scenario_ran = true + Given 'given' do end + When 'event' do end + Then 'outcome' do end + end + + given_scenario = GivenScenario.new('a scenario') + Runner::StoryRunner.should_receive(:scenario_from_current_story). + with('a scenario').and_return(scenario) + + world = World.create + listener = mock('listener') + World.add_listener(listener) + + # expect + listener.should_receive(:found_scenario).with(:'given scenario', 'a scenario') + listener.should_receive(:step_succeeded).never.with(:given, 'given') + listener.should_receive(:step_succeeded).never.with(:when, 'event') + listener.should_receive(:step_succeeded).never.with(:then, 'outcome') + + # when + world.GivenScenario 'a scenario' + + # then + # TODO verify_all + $scenario_ran.should be_true + end + + it 'should interpret GivenScenario... And... as multiple givens' do + # given + world = World.create + $steps = [] + + scenario = ScenarioBuilder.new.name('a scenario').to_scenario do + $steps << 1 + end + Runner::StoryRunner.should_receive(:scenario_from_current_story). + with('a scenario').and_return(scenario) + + # when + world.instance_eval do + GivenScenario 'a scenario' + And 'step 2' do + $steps << 2 + end + end + + # then + $steps.should == [1,2] + World.step_mother.find(:given, 'step 2').should_not be_nil + end + + it 'should provide rspec matchers' do + # given + world = World.create + + # then + world.instance_eval do + 'hello'.should match(/^hello$/) + end + end + + it "should use assigned matchers" do + world = World.create + + World.should_receive(:use).with(steps = Object.new) + + World.use(steps) + end + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec/translator_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/translator_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec/translator_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec/translator_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,264 @@ +require File.dirname(__FILE__) + '/../spec_helper.rb' + +describe "Translator" do + before do + @t = Spec::Translator.new + end + + it "should translate files" do + from = File.dirname(__FILE__) + '/..' + to = "#{Dir.tmpdir}/translated_specs" + @t.translate_dir(from, to) + end + + it "should translate context_setup do" do + @t.translate_line( + "context_setup do\n" + ).should eql( + "before(:all) do\n" + ) + end + + it "should translate context_setup {foo}" do + @t.translate_line( + "context_setup {foo}\n" + ).should eql( + "before(:all) {foo}\n" + ) + end + + it "should translate context ' to describe '" do + @t.translate_line( + "context 'Translator' do\n" + ).should eql( + "describe 'Translator' do\n" + ) + end + + it 'should translate context " to describe "' do + @t.translate_line( + 'context "Translator"' + ).should eql( + 'describe "Translator"' + ) + end + + it 'should translate spaces then context " to describe "' do + @t.translate_line( + ' context "Translator"' + ).should eql( + ' describe "Translator"' + ) + end + + it "should not translate context=foo" do + @t.translate_line(' context=foo').should eql(' context=foo') + end + + it "should not translate context = foo" do + @t.translate_line(' context = foo').should eql(' context = foo') + end + + it "should not translate context = foo" do + @t.translate_line(' context = foo').should eql(' context = foo') + end + + it "should translate should_be_close" do + @t.translate_line('5.0.should_be_close(5.0, 0.5)').should eql('5.0.should be_close(5.0, 0.5)') + end + + it "should translate should_not_raise" do + @t.translate_line('lambda { self.call }.should_not_raise').should eql('lambda { self.call }.should_not raise_error') + end + + it "should translate should_throw" do + @t.translate_line('lambda { self.call }.should_throw').should eql('lambda { self.call }.should throw_symbol') + end + + it "should not translate 0.9 should_not" do + @t.translate_line('@target.should_not @matcher').should eql('@target.should_not @matcher') + end + + it "should leave should_not_receive" do + @t.translate_line('@mock.should_not_receive(:not_expected).with("unexpected text")').should eql('@mock.should_not_receive(:not_expected).with("unexpected text")') + end + + it "should leave should_receive" do + @t.translate_line('@mock.should_receive(:not_expected).with("unexpected text")').should eql('@mock.should_receive(:not_expected).with("unexpected text")') + end + + it "should translate multi word predicates" do + @t.translate_line('foo.should_multi_word_predicate').should eql('foo.should be_multi_word_predicate') + end + + it "should translate multi word predicates prefixed with be" do + @t.translate_line('foo.should_be_multi_word_predicate').should eql('foo.should be_multi_word_predicate') + end + + it "should translate be(expected) to equal(expected)" do + @t.translate_line('foo.should_be :cool').should eql('foo.should equal :cool') + end + + it "should translate instance_of" do + @t.translate_line('5.should_be_an_instance_of(Integer)').should eql('5.should be_an_instance_of(Integer)') + end + + it "should translate should_be <" do + @t.translate_line('3.should_be < 4').should eql('3.should be < 4') + end + + it "should translate should_be <=" do + @t.translate_line('3.should_be <= 4').should eql('3.should be <= 4') + end + + it "should translate should_be >=" do + @t.translate_line('4.should_be >= 3').should eql('4.should be >= 3') + end + + it "should translate should_be >" do + @t.translate_line('4.should_be > 3').should eql('4.should be > 3') + end + + it "should translate should_be_happy" do + @t.translate_line("4.should_be_happy").should eql("4.should be_happy") + end + + it "should translate custom method taking regexp with parenthesis" do + @t.translate_line("@browser.should_contain_text(/Sn.rrunger og annet rusk/)").should eql("@browser.should be_contain_text(/Sn.rrunger og annet rusk/)") + end + + it "should translate custom method taking regexp without parenthesis" do + @t.translate_line("@browser.should_contain_text /Sn.rrunger og annet rusk/\n").should eql("@browser.should be_contain_text(/Sn.rrunger og annet rusk/)\n") + end + + it "should translate should_not_be_nil" do + @t.translate_line("foo.should_not_be_nil\n").should eql("foo.should_not be_nil\n") + end + + it "should translate kind of" do + @t.translate_line('@object.should_be_kind_of(MessageExpectation)').should( + eql('@object.should be_kind_of(MessageExpectation)')) + end + + it "should translate should_be_true" do + @t.translate_line("foo.should_be_true\n").should eql("foo.should be_true\n") + end + + # [#9674] spec_translate incorrectly handling shoud_match, when regexp in a var, in a block + # http://rubyforge.org/tracker/?func=detail&atid=3149&aid=9674&group_id=797 + it "should translate should_match on a regexp, in a var, in a block" do + @t.translate_line("collection.each { |c| c.should_match a_regexp_in_a_var }\n").should eql("collection.each { |c| c.should match(a_regexp_in_a_var) }\n") + @t.translate_line("collection.each{|c| c.should_match a_regexp_in_a_var}\n").should eql("collection.each{|c| c.should match(a_regexp_in_a_var) }\n") + end + + # From Rubinius specs + it "should translate close_to without parens" do + @t.translate_line("end.should_be_close 3.14159_26535_89793_23846, TOLERANCE\n").should eql("end.should be_close(3.14159_26535_89793_23846, TOLERANCE)\n") + end + + # [#9882] 0.9 Beta 1 - translator bugs + # http://rubyforge.org/tracker/index.php?func=detail&aid=9882&group_id=797&atid=3149 + it "should support symbol arguments" do + @t.translate_line( + "lambda { sequence.parse('bar') }.should_throw :ZeroWidthParseSuccess\n" + ).should eql( + "lambda { sequence.parse('bar') }.should throw_symbol(:ZeroWidthParseSuccess)\n" + ) + end + + # [#9882] 0.9 Beta 1 - translator bugs + # http://rubyforge.org/tracker/index.php?func=detail&aid=9882&group_id=797&atid=3149 + it "should support instance var arguments" do + @t.translate_line( + "a.should_eql @local" + ).should eql( + "a.should eql(@local)" + ) + end + + # [#9882] 0.9 Beta 1 - translator bugs + # http://rubyforge.org/tracker/index.php?func=detail&aid=9882&group_id=797&atid=3149 + it "should support lambdas as expecteds" do + @t.translate_line( + "@parslet.should_not_eql lambda { nil }.to_parseable" + ).should eql( + "@parslet.should_not eql(lambda { nil }.to_parseable)" + ) + end + + # [#9882] 0.9 Beta 1 - translator bugs + # http://rubyforge.org/tracker/index.php?func=detail&aid=9882&group_id=797&atid=3149 + it "should support fully qualified names" do + @t.translate_line( + "results.should_be_kind_of SimpleASTLanguage::Identifier" + ).should eql( + "results.should be_kind_of(SimpleASTLanguage::Identifier)" + ) + end + + # [#9882] 0.9 Beta 1 - translator bugs + # http://rubyforge.org/tracker/index.php?func=detail&aid=9882&group_id=797&atid=3149 + # it "should leave whitespace between expression and comments" do + # @t.translate_line( + # "lambda { @instance.foo = foo }.should_raise NoMethodError # no writer defined" + # ).should eql( + # "lambda { @instance.foo = foo }.should raise_error(NoMethodError) # no writer defined" + # ) + # end + + it "should translate redirects" do + @t.translate_line( + "controller.should_redirect_to 'http://not_existing_domain_for_novalis.test.host/404.html'" + ).should eql( + "controller.should redirect_to('http://not_existing_domain_for_novalis.test.host/404.html')" + ) + end + + it "should translate :any_args" do + @t.translate_line( + "mock.should_receive(:foo).with(:any_args)" + ).should eql( + "mock.should_receive(:foo).with(any_args)" + ) + end + + it "should translate :anything" do + @t.translate_line( + "mock.should_receive(:foo).with(:anything)" + ).should eql( + "mock.should_receive(:foo).with(anything)" + ) + end + + it "should translate :boolean" do + @t.translate_line( + "mock.should_receive(:foo).with(:boolean)" + ).should eql( + "mock.should_receive(:foo).with(boolean)" + ) + end + + it "should translate :no_args" do + @t.translate_line( + "mock.should_receive(:foo).with(:no_args)" + ).should eql( + "mock.should_receive(:foo).with(no_args)" + ) + end + + it "should translate :numeric" do + @t.translate_line( + "mock.should_receive(:foo).with(:numeric)" + ).should eql( + "mock.should_receive(:foo).with(an_instance_of(Numeric))" + ) + end + + it "should translate :string" do + @t.translate_line( + "mock.should_receive(:foo).with(:string)" + ).should eql( + "mock.should_receive(:foo).with(an_instance_of(String))" + ) + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec/spec_helper.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec_helper.rb --- mephisto-0.7.3/vendor/plugins/rspec/spec/spec_helper.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec/spec_helper.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,77 @@ +require 'stringio' +require 'rbconfig' +require 'tmpdir' + +dir = File.dirname(__FILE__) +lib_path = File.expand_path("#{dir}/../lib") +$LOAD_PATH.unshift lib_path unless $LOAD_PATH.include?(lib_path) +$_spec_spec = true # Prevents Kernel.exit in various places + +require 'spec' +require 'spec/mocks' +spec_classes_path = File.expand_path("#{dir}/../spec/spec/spec_classes") +require spec_classes_path unless $LOAD_PATH.include?(spec_classes_path) +require File.dirname(__FILE__) + '/../lib/spec/expectations/differs/default' + +module Spec + module Matchers + def fail + raise_error(Spec::Expectations::ExpectationNotMetError) + end + + def fail_with(message) + raise_error(Spec::Expectations::ExpectationNotMetError, message) + end + + class Pass + def matches?(proc, &block) + begin + proc.call + true + rescue Exception => @error + false + end + end + + def failure_message + @error.message + "\n" + @error.backtrace.join("\n") + end + end + + def pass + Pass.new + end + + class CorrectlyOrderedMockExpectation + def initialize(&event) + @event = event + end + + def expect(&expectations) + expectations.call + @event.call + end + end + + def during(&block) + CorrectlyOrderedMockExpectation.new(&block) + end + end +end + +class NonStandardError < Exception; end + +module Custom + class ExampleGroupRunner + attr_reader :options, :arg + def initialize(options, arg) + @options, @arg = options, arg + end + + def load_files(files) + end + + def run + end + end +end \ No newline at end of file diff -Nur mephisto-0.7.3/vendor/plugins/rspec/spec.opts technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec.opts --- mephisto-0.7.3/vendor/plugins/rspec/spec.opts 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/spec.opts 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,6 @@ +--colour +--format +profile +--timeout +20 +--diff \ No newline at end of file diff -Nur mephisto-0.7.3/vendor/plugins/rspec/stories/all.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/stories/all.rb --- mephisto-0.7.3/vendor/plugins/rspec/stories/all.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/stories/all.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,72 @@ +$LOAD_PATH.unshift File.expand_path("#{File.dirname(__FILE__)}/../lib") +require 'spec' +require 'rbconfig' +require 'tempfile' +require File.dirname(__FILE__) + '/smart_match' + +module StoryHelper + def ruby(args, stderr) + config = ::Config::CONFIG + interpreter = File::join(config['bindir'], config['ruby_install_name']) + config['EXEEXT'] + cmd = "#{interpreter} #{args} 2> #{stderr}" + #puts "\nCOMMAND: #{cmd}" + `#{cmd}` + end + + def spec(args, stderr) + ruby("#{File.dirname(__FILE__) + '/../bin/spec'} #{args}", stderr) + end + + def cmdline(args, stderr) + ruby("#{File.dirname(__FILE__) + '/cmdline.rb'} #{args}", stderr) + end + + Spec::Story::World.send :include, self +end + + +steps_for :rspec_and_test_unit do + + Given("the file $relative_path") do |relative_path| + @path = File.join(File.dirname(__FILE__), relative_path) + end + When("I run it with the $interpreter") do |interpreter| + stderr_file = Tempfile.new('rspec') + stderr_file.close + @stdout = case(interpreter) + when 'ruby interpreter' then ruby(@path, stderr_file.path) + when 'spec script' then spec(@path, stderr_file.path) + when 'CommandLine object' then cmdline(@path, stderr_file.path) + else raise "Unknown interpreter: #{interpreter}" + end + @stderr = IO.read(stderr_file.path) + @exit_code = $?.to_i + end + Then("the exit code should be $exit_code") do |exit_code| + if @exit_code != exit_code.to_i + raise "Did not exit with #{exit_code}, but with #{@exit_code}. Standard error:\n#{@stderr}" + end + end + Then("the $stream should match $regex") do |stream, string_or_regex| + written = case(stream) + when 'stdout' then @stdout + when 'stderr' then @stderr + else raise "Unknown stream: #{stream}" + end + written.should smart_match(string_or_regex) + end + Then("the $stream should not match $regex") do |stream, string_or_regex| + written = case(stream) + when 'stdout' then @stdout + when 'stderr' then @stderr + else raise "Unknown stream: #{stream}" + end + written.should_not smart_match(string_or_regex) + end +end + +with_steps_for :rspec_and_test_unit do + Dir["#{File.dirname(__FILE__)}/**"].each do |file| + run file if File.file?(file) && !(file =~ /\.rb$/) + end +end \ No newline at end of file diff -Nur mephisto-0.7.3/vendor/plugins/rspec/stories/cmdline.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/stories/cmdline.rb --- mephisto-0.7.3/vendor/plugins/rspec/stories/cmdline.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/stories/cmdline.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,9 @@ +$:.push File.join(File.dirname(__FILE__), *%w[.. lib]) +require 'spec' + +# Uncommenting next line will break the output story (no output!!) +# rspec_options +options = Spec::Runner::OptionParser.parse( + ARGV, $stderr, $stdout +) +Spec::Runner::CommandLine.run(options) diff -Nur mephisto-0.7.3/vendor/plugins/rspec/stories/output technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/stories/output --- mephisto-0.7.3/vendor/plugins/rspec/stories/output 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/stories/output 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,20 @@ +Story: Getting correct output + + As an RSpec user + I want to see output only once + So that I don't get confused + + Scenario: Run with ruby + Given the file spec/simple_spec.rb + When I run it with the ruby interpreter + Then the exit code should be 0 + And the stdout should not match /\d+ tests, \d+ assertions, \d+ failures, \d+ errors/m + And the stdout should match "1 example, 0 failures" + + Scenario: Run with CommandLine object + Given the file spec/simple_spec.rb + When I run it with the CommandLine object + Then the exit code should be 0 + And the stdout should not match "Loaded suite" + And the stdout should not match /\d+ tests, \d+ assertions, \d+ failures, \d+ errors/m + And the stdout should match "1 example, 0 failures" diff -Nur mephisto-0.7.3/vendor/plugins/rspec/stories/smart_match.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/stories/smart_match.rb --- mephisto-0.7.3/vendor/plugins/rspec/stories/smart_match.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/stories/smart_match.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,37 @@ +module Spec + module Matchers + class SmartMatch + def initialize(expected) + @expected = expected + end + + def matches?(actual) + @actual = actual + # Satisfy expectation here. Return false or raise an error if it's not met. + + if @expected =~ /^\/.*\/?$/ || @expected =~ /^".*"$/ + regex_or_string = eval(@expected) + if Regexp === regex_or_string + (@actual =~ regex_or_string) ? true : false + else + @actual.index(regex_or_string) != nil + end + else + false + end + end + + def failure_message + "expected #{@actual.inspect} to smart_match #{@expected.inspect}, but it didn't" + end + + def negative_failure_message + "expected #{@actual.inspect} not to smart_match #{@expected.inspect}, but it did" + end + end + + def smart_match(expected) + SmartMatch.new(expected) + end + end +end \ No newline at end of file diff -Nur mephisto-0.7.3/vendor/plugins/rspec/stories/spec/simple_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/stories/spec/simple_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec/stories/spec/simple_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/stories/spec/simple_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,8 @@ +$:.push File.join(File.dirname(__FILE__), *%w[.. .. lib]) +require 'spec' + +describe "Running an Example" do + it "should not output twice" do + true.should be_true + end +end \ No newline at end of file diff -Nur mephisto-0.7.3/vendor/plugins/rspec/stories/specs_and_test_together technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/stories/specs_and_test_together --- mephisto-0.7.3/vendor/plugins/rspec/stories/specs_and_test_together 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/stories/specs_and_test_together 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,33 @@ +Story: Spec and test together + + As an RSpec adopter with existing Test::Unit tests + I want to run a few specs alongside my existing Test::Unit tests + So that I can experience a smooth, gradual migration path + + Scenario: Run with ruby + Given the file test/spec_and_test_together.rb + + When I run it with the ruby interpreter + + Then the exit code should be 256 + And the stdout should match "Loaded suite" + And the stdout should match "test_should_fail_with_assert(NeighborlyTest)" + And the stdout should match "test_should_fail_with_should(NeighborlyTest)" + And the stdout should match "4 tests, 2 assertions, 1 failures, 1 errors" + And the stdout should match "Test::Unit::AssertionFailedError in 'spec should fail with assert'" + And the stdout should match "'spec should fail with should' FAILED" + And the stdout should match "4 examples, 2 failures" + + Scenario: Run with spec + Given the file test/spec_and_test_together.rb + + When I run it with the spec script + + Then the exit code should be 256 +# And the stdout should match "Loaded suite" +# And the stdout should match "test_should_fail_with_assert(NeighborlyTest)" +# And the stdout should match "test_should_fail_with_should(NeighborlyTest)" +# And the stdout should match "4 tests, 2 assertions, 1 failures, 1 errors" + And the stdout should match "Test::Unit::AssertionFailedError in 'spec should fail with assert'" + And the stdout should match "'spec should fail with should' FAILED" + And the stdout should match "4 examples, 2 failures" diff -Nur mephisto-0.7.3/vendor/plugins/rspec/stories/test/spec_and_test_together.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/stories/test/spec_and_test_together.rb --- mephisto-0.7.3/vendor/plugins/rspec/stories/test/spec_and_test_together.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/stories/test/spec_and_test_together.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,39 @@ +$:.push File.join(File.dirname(__FILE__), *%w[.. .. lib]) +require 'spec' +require 'spec/extensions/test' + +describe "spec" do + it "should pass with assert" do + assert true + end + + it "should fail with assert" do + assert false + end + + it "should pass with should" do + 1.should == 1 + end + + it "should fail with should" do + 1.should == 2 + end +end + +class NeighborlyTest < Test::Unit::TestCase + def test_should_pass_with_assert + assert true + end + + def test_should_fail_with_assert + assert false + end + + def test_should_pass_with_should + 1.should == 1 + end + + def test_should_fail_with_should + 1.should == 2 + end +end \ No newline at end of file diff -Nur mephisto-0.7.3/vendor/plugins/rspec/stories/test/tu_example_group_subclass_with_should_methods.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/stories/test/tu_example_group_subclass_with_should_methods.rb --- mephisto-0.7.3/vendor/plugins/rspec/stories/test/tu_example_group_subclass_with_should_methods.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/stories/test/tu_example_group_subclass_with_should_methods.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,21 @@ +$:.push File.join(File.dirname(__FILE__), *%w[.. .. lib]) +require 'spec' +require 'spec/extensions/test' + +class MySpec < Test::Unit::TestCase::ExampleGroup + def should_pass_with_should + 1.should == 1 + end + + def should_fail_with_should + 1.should == 2 + end + + def should_pass_with_assert + assert true + end + + def should_fail_with_assert + assert false + end +end \ No newline at end of file diff -Nur mephisto-0.7.3/vendor/plugins/rspec/stories/tu_example_group_subclass_with_should_methods technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/stories/tu_example_group_subclass_with_should_methods --- mephisto-0.7.3/vendor/plugins/rspec/stories/tu_example_group_subclass_with_should_methods 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/stories/tu_example_group_subclass_with_should_methods 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,17 @@ +Story: Test::Unit::TestCase::ExampleGroup subclass with should methods + + As an RSpec adopter with existing Test::Unit tests + I want to use should_* methods in a Test::Unit::TestCase::ExampleGroup subclass + So that I use RSpec with classes and methods that look more like RSpec examples + + Scenario: Run with ruby + Given the file test/tu_example_group_subclass_with_should_methods.rb + When I run it with the ruby interpreter + Then the exit code should be 256 + And the stdout should match "4 examples, 2 failures" + + Scenario: Run with spec + Given the file test/tu_example_group_subclass_with_should_methods.rb + When I run it with the spec script + Then the exit code should be 256 + And the stdout should match "4 examples, 2 failures" diff -Nur mephisto-0.7.3/vendor/plugins/rspec/story_server/prototype/javascripts/application.js technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/story_server/prototype/javascripts/application.js --- mephisto-0.7.3/vendor/plugins/rspec/story_server/prototype/javascripts/application.js 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/story_server/prototype/javascripts/application.js 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,149 @@ +var InPlaceEditor = {}; +InPlaceEditor.Local = Class.create(); +Object.extend(Object.extend(InPlaceEditor.Local.prototype, Ajax.InPlaceEditor.prototype), { + enterHover: function() {}, + leaveHover: function() {}, + onComplete: function() {}, + handleFormSubmission: function(e) { + var value = $F(this._controls.editor); + RSpec.addStockStep(value); + this.element.innerHTML = value; + this.leaveEditMode(); + if (e) Event.stop(e); + } +}); + +var RSpec = { + stockSteps: function() { + return $('stock_steps').childElements().map(function(li){ + return li.innerHTML; + }).sort(); + }, + + addStockStep: function(stockStep) { + if(!this.stockSteps().include(stockStep)) { + $('stock_steps').appendChild(Builder.node('li', {}, stockStep)); + } + }, + + makeParamEditors: function() { + $$('span.param').each(function(span) { + span.removeClassName('param'); + span.addClassName('param_editor'); + new InPlaceEditor.Local(span, null, {}); + }); + }, + + setId: function(e) { + if(!this.currentId) this.currentId = 0; + this.currentId++; + e.id = "id_" + this.currentId; + }, + + applyUi: function() { + this.setUpTogglers(); + this.makeParamEditors(); + + var currentId = 0; + $$('ul.steps').each(function(ul) { + RSpec.setId(ul); + var footer = document.createElement("p"); + var addStepLink = document.createElement("a"); + addStepLink.href = "#"; + addStepLink.appendChild(document.createTextNode('Add step')); + footer.appendChild(addStepLink); + ul.parentNode.appendChild(footer); + + Sortable.create(ul, { + scroll: window + }); + +/* Disable for now - it messes with the autocomplete's visibility (zIndex galore) + Droppables.add(footer, { + hoverclass: 'wastebin', + onDrop: function(li, droppable, evt) { + li.remove(); + } + }); +*/ + Event.observe(addStepLink, 'click', function() { + var form = Builder.node('form', {}); + + var li = Builder.node('li', {className: 'new'}); + var input = Builder.node('input', {}, 'New step here'); + var autoComplete = Builder.node('div', {className: 'auto_complete'}, ''); + + li.appendChild(form); + form.appendChild(input); + form.appendChild(autoComplete); + ul.appendChild(li); + Sortable.destroy(ul); + Sortable.create(ul); + + Event.observe(form, 'submit', function(e) { + var value = input.value; + Element.remove(this); + li.innerHTML = value.gsub(/(\$[a-z]*)/, '#{1}'); + RSpec.makeParamEditors(); + if (e) Event.stop(e); + }); + + var ac = new Autocompleter.Local(input, autoComplete, RSpec.stockSteps(), {}); + input.focus(); + }); + }) + }, + + setUpTogglers: function() { + $$('dt').each(function(dt) { + var dd = dt.parentNode.getElementsByTagName('dd')[0]; + dt.onclick = function(){ + dd.toggle(); + } + }); + } +}; + +var StoryDom = { + narrativeText: function(s) { + return s.split(/\n/m).map(function(line){ + if(line == "" || line.match(/^\s+$/) ) { + return null; + } else { + return " " + (line.gsub(/^\s+/, '').gsub(/
      /, "\n").gsub(/
      /, "\n")); + } + }).compact().join(""); + }, + + stepText: function(s) { + return s.gsub(/]*>([^<]*)<\/span>/, "#{1}"); + }, + + scenario: function(dl) { + var scenario = ' Scenario: ' + dl.getElementsByTagName('dt')[0].innerHTML + '\n'; + scenario += $A(dl.getElementsByTagName('li')).map(function(li){ + return ' ' + StoryDom.stepText(li.innerHTML); + }).join("\n") + "\n"; + return scenario; + }, + + story: function() { + var dl = $$('dl.story')[0]; + var story = 'Story: ' + dl.getElementsByTagName('dt')[0].innerHTML + '\n\n'; + story += this.narrativeText(dl.getElementsByTagName('p')[0].innerHTML) + '\n'; + story += $A(dl.getElementsByTagName('dl')).map(function(scenarioDl){ + return StoryDom.scenario(scenarioDl); + }).join("\n"); + return story; + }, + + save: function() { + new Ajax.Request('stories', { + postBody: this.story() + }); + } +}; + +Event.observe(window, 'load', function() { + RSpec.applyUi(); +}); diff -Nur mephisto-0.7.3/vendor/plugins/rspec/story_server/prototype/javascripts/builder.js technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/story_server/prototype/javascripts/builder.js --- mephisto-0.7.3/vendor/plugins/rspec/story_server/prototype/javascripts/builder.js 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/story_server/prototype/javascripts/builder.js 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,136 @@ +// script.aculo.us builder.js v1.8.0_pre1, Fri Oct 12 21:34:51 +0200 2007 + +// Copyright (c) 2005-2007 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) +// +// script.aculo.us is freely distributable under the terms of an MIT-style license. +// For details, see the script.aculo.us web site: http://script.aculo.us/ + +var Builder = { + NODEMAP: { + AREA: 'map', + CAPTION: 'table', + COL: 'table', + COLGROUP: 'table', + LEGEND: 'fieldset', + OPTGROUP: 'select', + OPTION: 'select', + PARAM: 'object', + TBODY: 'table', + TD: 'table', + TFOOT: 'table', + TH: 'table', + THEAD: 'table', + TR: 'table' + }, + // note: For Firefox < 1.5, OPTION and OPTGROUP tags are currently broken, + // due to a Firefox bug + node: function(elementName) { + elementName = elementName.toUpperCase(); + + // try innerHTML approach + var parentTag = this.NODEMAP[elementName] || 'div'; + var parentElement = document.createElement(parentTag); + try { // prevent IE "feature": http://dev.rubyonrails.org/ticket/2707 + parentElement.innerHTML = "<" + elementName + ">"; + } catch(e) {} + var element = parentElement.firstChild || null; + + // see if browser added wrapping tags + if(element && (element.tagName.toUpperCase() != elementName)) + element = element.getElementsByTagName(elementName)[0]; + + // fallback to createElement approach + if(!element) element = document.createElement(elementName); + + // abort if nothing could be created + if(!element) return; + + // attributes (or text) + if(arguments[1]) + if(this._isStringOrNumber(arguments[1]) || + (arguments[1] instanceof Array) || + arguments[1].tagName) { + this._children(element, arguments[1]); + } else { + var attrs = this._attributes(arguments[1]); + if(attrs.length) { + try { // prevent IE "feature": http://dev.rubyonrails.org/ticket/2707 + parentElement.innerHTML = "<" +elementName + " " + + attrs + ">"; + } catch(e) {} + element = parentElement.firstChild || null; + // workaround firefox 1.0.X bug + if(!element) { + element = document.createElement(elementName); + for(attr in arguments[1]) + element[attr == 'class' ? 'className' : attr] = arguments[1][attr]; + } + if(element.tagName.toUpperCase() != elementName) + element = parentElement.getElementsByTagName(elementName)[0]; + } + } + + // text, or array of children + if(arguments[2]) + this._children(element, arguments[2]); + + return element; + }, + _text: function(text) { + return document.createTextNode(text); + }, + + ATTR_MAP: { + 'className': 'class', + 'htmlFor': 'for' + }, + + _attributes: function(attributes) { + var attrs = []; + for(attribute in attributes) + attrs.push((attribute in this.ATTR_MAP ? this.ATTR_MAP[attribute] : attribute) + + '="' + attributes[attribute].toString().escapeHTML().gsub(/"/,'"') + '"'); + return attrs.join(" "); + }, + _children: function(element, children) { + if(children.tagName) { + element.appendChild(children); + return; + } + if(typeof children=='object') { // array can hold nodes and text + children.flatten().each( function(e) { + if(typeof e=='object') + element.appendChild(e) + else + if(Builder._isStringOrNumber(e)) + element.appendChild(Builder._text(e)); + }); + } else + if(Builder._isStringOrNumber(children)) + element.appendChild(Builder._text(children)); + }, + _isStringOrNumber: function(param) { + return(typeof param=='string' || typeof param=='number'); + }, + build: function(html) { + var element = this.node('div'); + $(element).update(html.strip()); + return element.down(); + }, + dump: function(scope) { + if(typeof scope != 'object' && typeof scope != 'function') scope = window; //global scope + + var tags = ("A ABBR ACRONYM ADDRESS APPLET AREA B BASE BASEFONT BDO BIG BLOCKQUOTE BODY " + + "BR BUTTON CAPTION CENTER CITE CODE COL COLGROUP DD DEL DFN DIR DIV DL DT EM FIELDSET " + + "FONT FORM FRAME FRAMESET H1 H2 H3 H4 H5 H6 HEAD HR HTML I IFRAME IMG INPUT INS ISINDEX "+ + "KBD LABEL LEGEND LI LINK MAP MENU META NOFRAMES NOSCRIPT OBJECT OL OPTGROUP OPTION P "+ + "PARAM PRE Q S SAMP SCRIPT SELECT SMALL SPAN STRIKE STRONG STYLE SUB SUP TABLE TBODY TD "+ + "TEXTAREA TFOOT TH THEAD TITLE TR TT U UL VAR").split(/\s+/); + + tags.each( function(tag){ + scope[tag] = function() { + return Builder.node.apply(Builder, [tag].concat($A(arguments))); + } + }); + } +} diff -Nur mephisto-0.7.3/vendor/plugins/rspec/story_server/prototype/javascripts/controls.js technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/story_server/prototype/javascripts/controls.js --- mephisto-0.7.3/vendor/plugins/rspec/story_server/prototype/javascripts/controls.js 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/story_server/prototype/javascripts/controls.js 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,972 @@ +// script.aculo.us controls.js v1.8.0_pre1, Fri Oct 12 21:34:51 +0200 2007 + +// Copyright (c) 2005-2007 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) +// (c) 2005-2007 Ivan Krstic (http://blogs.law.harvard.edu/ivan) +// (c) 2005-2007 Jon Tirsen (http://www.tirsen.com) +// Contributors: +// Richard Livsey +// Rahul Bhargava +// Rob Wills +// +// script.aculo.us is freely distributable under the terms of an MIT-style license. +// For details, see the script.aculo.us web site: http://script.aculo.us/ + +// Autocompleter.Base handles all the autocompletion functionality +// that's independent of the data source for autocompletion. This +// includes drawing the autocompletion menu, observing keyboard +// and mouse events, and similar. +// +// Specific autocompleters need to provide, at the very least, +// a getUpdatedChoices function that will be invoked every time +// the text inside the monitored textbox changes. This method +// should get the text for which to provide autocompletion by +// invoking this.getToken(), NOT by directly accessing +// this.element.value. This is to allow incremental tokenized +// autocompletion. Specific auto-completion logic (AJAX, etc) +// belongs in getUpdatedChoices. +// +// Tokenized incremental autocompletion is enabled automatically +// when an autocompleter is instantiated with the 'tokens' option +// in the options parameter, e.g.: +// new Ajax.Autocompleter('id','upd', '/url/', { tokens: ',' }); +// will incrementally autocomplete with a comma as the token. +// Additionally, ',' in the above example can be replaced with +// a token array, e.g. { tokens: [',', '\n'] } which +// enables autocompletion on multiple tokens. This is most +// useful when one of the tokens is \n (a newline), as it +// allows smart autocompletion after linebreaks. +// +// vim:expandtab ts=8 sw=2 + +if(typeof Effect == 'undefined') + throw("controls.js requires including script.aculo.us' effects.js library"); + +var Autocompleter = { } +Autocompleter.Base = function() { }; +Autocompleter.Base.prototype = { + baseInitialize: function(element, update, options) { + element = $(element) + this.element = element; + this.update = $(update); + this.hasFocus = false; + this.changed = false; + this.active = false; + this.index = 0; + this.entryCount = 0; + this.oldElementValue = this.element.value; + + if(this.setOptions) + this.setOptions(options); + else + this.options = options || { }; + + this.options.paramName = this.options.paramName || this.element.name; + this.options.tokens = this.options.tokens || []; + this.options.frequency = this.options.frequency || 0.4; + this.options.minChars = this.options.minChars || 1; + this.options.onShow = this.options.onShow || + function(element, update){ + if(!update.style.position || update.style.position=='absolute') { + update.style.position = 'absolute'; + Position.clone(element, update, { + setHeight: false, + offsetTop: element.offsetHeight + }); + } + Effect.Appear(update,{duration:0.15}); + }; + this.options.onHide = this.options.onHide || + function(element, update){ new Effect.Fade(update,{duration:0.15}) }; + + if(typeof(this.options.tokens) == 'string') + this.options.tokens = new Array(this.options.tokens); + // Force carriage returns as token delimiters anyway + if (!this.options.tokens.include('\n')) + this.options.tokens.push('\n'); + + this.observer = null; + + this.element.setAttribute('autocomplete','off'); + + Element.hide(this.update); + + Event.observe(this.element, 'blur', this.onBlur.bindAsEventListener(this)); + Event.observe(this.element, 'keypress', this.onKeyPress.bindAsEventListener(this)); + }, + + show: function() { + if(Element.getStyle(this.update, 'display')=='none') this.options.onShow(this.element, this.update); + if(!this.iefix && + (Prototype.Browser.IE) && + (Element.getStyle(this.update, 'position')=='absolute')) { + new Insertion.After(this.update, + ''); + this.iefix = $(this.update.id+'_iefix'); + } + if(this.iefix) setTimeout(this.fixIEOverlapping.bind(this), 50); + }, + + fixIEOverlapping: function() { + Position.clone(this.update, this.iefix, {setTop:(!this.update.style.height)}); + this.iefix.style.zIndex = 1; + this.update.style.zIndex = 2; + Element.show(this.iefix); + }, + + hide: function() { + this.stopIndicator(); + if(Element.getStyle(this.update, 'display')!='none') this.options.onHide(this.element, this.update); + if(this.iefix) Element.hide(this.iefix); + }, + + startIndicator: function() { + if(this.options.indicator) Element.show(this.options.indicator); + }, + + stopIndicator: function() { + if(this.options.indicator) Element.hide(this.options.indicator); + }, + + onKeyPress: function(event) { + if(this.active) + switch(event.keyCode) { + case Event.KEY_TAB: + case Event.KEY_RETURN: + this.selectEntry(); + Event.stop(event); + case Event.KEY_ESC: + this.hide(); + this.active = false; + Event.stop(event); + return; + case Event.KEY_LEFT: + case Event.KEY_RIGHT: + return; + case Event.KEY_UP: + this.markPrevious(); + this.render(); + if(Prototype.Browser.WebKit) Event.stop(event); + return; + case Event.KEY_DOWN: + this.markNext(); + this.render(); + if(Prototype.Browser.WebKit) Event.stop(event); + return; + } + else + if(event.keyCode==Event.KEY_TAB || event.keyCode==Event.KEY_RETURN || + (Prototype.Browser.WebKit > 0 && event.keyCode == 0)) return; + + this.changed = true; + this.hasFocus = true; + + if(this.observer) clearTimeout(this.observer); + this.observer = + setTimeout(this.onObserverEvent.bind(this), this.options.frequency*1000); + }, + + activate: function() { + this.changed = false; + this.hasFocus = true; + this.getUpdatedChoices(); + }, + + onHover: function(event) { + var element = Event.findElement(event, 'LI'); + if(this.index != element.autocompleteIndex) + { + this.index = element.autocompleteIndex; + this.render(); + } + Event.stop(event); + }, + + onClick: function(event) { + var element = Event.findElement(event, 'LI'); + this.index = element.autocompleteIndex; + this.selectEntry(); + this.hide(); + }, + + onBlur: function(event) { + // needed to make click events working + setTimeout(this.hide.bind(this), 250); + this.hasFocus = false; + this.active = false; + }, + + render: function() { + if(this.entryCount > 0) { + for (var i = 0; i < this.entryCount; i++) + this.index==i ? + Element.addClassName(this.getEntry(i),"selected") : + Element.removeClassName(this.getEntry(i),"selected"); + if(this.hasFocus) { + this.show(); + this.active = true; + } + } else { + this.active = false; + this.hide(); + } + }, + + markPrevious: function() { + if(this.index > 0) this.index-- + else this.index = this.entryCount-1; + this.getEntry(this.index).scrollIntoView(true); + }, + + markNext: function() { + if(this.index < this.entryCount-1) this.index++ + else this.index = 0; + this.getEntry(this.index).scrollIntoView(false); + }, + + getEntry: function(index) { + return this.update.firstChild.childNodes[index]; + }, + + getCurrentEntry: function() { + return this.getEntry(this.index); + }, + + selectEntry: function() { + this.active = false; + this.updateElement(this.getCurrentEntry()); + }, + + updateElement: function(selectedElement) { + if (this.options.updateElement) { + this.options.updateElement(selectedElement); + return; + } + var value = ''; + if (this.options.select) { + var nodes = document.getElementsByClassName(this.options.select, selectedElement) || []; + if(nodes.length>0) value = Element.collectTextNodes(nodes[0], this.options.select); + } else + value = Element.collectTextNodesIgnoreClass(selectedElement, 'informal'); + + var bounds = this.getTokenBounds(); + if (bounds[0] != -1) { + var newValue = this.element.value.substr(0, bounds[0]); + var whitespace = this.element.value.substr(bounds[0]).match(/^\s+/); + if (whitespace) + newValue += whitespace[0]; + this.element.value = newValue + value + this.element.value.substr(bounds[1]); + } else { + this.element.value = value; + } + this.oldElementValue = this.element.value; + this.element.focus(); + + if (this.options.afterUpdateElement) + this.options.afterUpdateElement(this.element, selectedElement); + }, + + updateChoices: function(choices) { + if(!this.changed && this.hasFocus) { + this.update.innerHTML = choices; + Element.cleanWhitespace(this.update); + Element.cleanWhitespace(this.update.down()); + + if(this.update.firstChild && this.update.down().childNodes) { + this.entryCount = + this.update.down().childNodes.length; + for (var i = 0; i < this.entryCount; i++) { + var entry = this.getEntry(i); + entry.autocompleteIndex = i; + this.addObservers(entry); + } + } else { + this.entryCount = 0; + } + + this.stopIndicator(); + this.index = 0; + + if(this.entryCount==1 && this.options.autoSelect) { + this.selectEntry(); + this.hide(); + } else { + this.render(); + } + } + }, + + addObservers: function(element) { + Event.observe(element, "mouseover", this.onHover.bindAsEventListener(this)); + Event.observe(element, "click", this.onClick.bindAsEventListener(this)); + }, + + onObserverEvent: function() { + this.changed = false; + this.tokenBounds = null; + if(this.getToken().length>=this.options.minChars) { + this.getUpdatedChoices(); + } else { + this.active = false; + this.hide(); + } + this.oldElementValue = this.element.value; + }, + + getToken: function() { + var bounds = this.getTokenBounds(); + return this.element.value.substring(bounds[0], bounds[1]).strip(); + }, + + getTokenBounds: function() { + if (null != this.tokenBounds) return this.tokenBounds; + var value = this.element.value; + if (value.strip().empty()) return [-1, 0]; + var diff = arguments.callee.getFirstDifferencePos(value, this.oldElementValue); + var offset = (diff == this.oldElementValue.length ? 1 : 0); + var prevTokenPos = -1, nextTokenPos = value.length; + var tp; + for (var index = 0, l = this.options.tokens.length; index < l; ++index) { + tp = value.lastIndexOf(this.options.tokens[index], diff + offset - 1); + if (tp > prevTokenPos) prevTokenPos = tp; + tp = value.indexOf(this.options.tokens[index], diff + offset); + if (-1 != tp && tp < nextTokenPos) nextTokenPos = tp; + } + return (this.tokenBounds = [prevTokenPos + 1, nextTokenPos]); + } +} + +Autocompleter.Base.prototype.getTokenBounds.getFirstDifferencePos = function(newS, oldS) { + var boundary = Math.min(newS.length, oldS.length); + for (var index = 0; index < boundary; ++index) + if (newS[index] != oldS[index]) + return index; + return boundary; +}; + +Ajax.Autocompleter = Class.create(); +Object.extend(Object.extend(Ajax.Autocompleter.prototype, Autocompleter.Base.prototype), { + initialize: function(element, update, url, options) { + this.baseInitialize(element, update, options); + this.options.asynchronous = true; + this.options.onComplete = this.onComplete.bind(this); + this.options.defaultParams = this.options.parameters || null; + this.url = url; + }, + + getUpdatedChoices: function() { + this.startIndicator(); + + var entry = encodeURIComponent(this.options.paramName) + '=' + + encodeURIComponent(this.getToken()); + + this.options.parameters = this.options.callback ? + this.options.callback(this.element, entry) : entry; + + if(this.options.defaultParams) + this.options.parameters += '&' + this.options.defaultParams; + + new Ajax.Request(this.url, this.options); + }, + + onComplete: function(request) { + this.updateChoices(request.responseText); + } + +}); + +// The local array autocompleter. Used when you'd prefer to +// inject an array of autocompletion options into the page, rather +// than sending out Ajax queries, which can be quite slow sometimes. +// +// The constructor takes four parameters. The first two are, as usual, +// the id of the monitored textbox, and id of the autocompletion menu. +// The third is the array you want to autocomplete from, and the fourth +// is the options block. +// +// Extra local autocompletion options: +// - choices - How many autocompletion choices to offer +// +// - partialSearch - If false, the autocompleter will match entered +// text only at the beginning of strings in the +// autocomplete array. Defaults to true, which will +// match text at the beginning of any *word* in the +// strings in the autocomplete array. If you want to +// search anywhere in the string, additionally set +// the option fullSearch to true (default: off). +// +// - fullSsearch - Search anywhere in autocomplete array strings. +// +// - partialChars - How many characters to enter before triggering +// a partial match (unlike minChars, which defines +// how many characters are required to do any match +// at all). Defaults to 2. +// +// - ignoreCase - Whether to ignore case when autocompleting. +// Defaults to true. +// +// It's possible to pass in a custom function as the 'selector' +// option, if you prefer to write your own autocompletion logic. +// In that case, the other options above will not apply unless +// you support them. + +Autocompleter.Local = Class.create(); +Autocompleter.Local.prototype = Object.extend(new Autocompleter.Base(), { + initialize: function(element, update, array, options) { + this.baseInitialize(element, update, options); + this.options.array = array; + }, + + getUpdatedChoices: function() { + this.updateChoices(this.options.selector(this)); + }, + + setOptions: function(options) { + this.options = Object.extend({ + choices: 10, + partialSearch: true, + partialChars: 2, + ignoreCase: true, + fullSearch: false, + selector: function(instance) { + var ret = []; // Beginning matches + var partial = []; // Inside matches + var entry = instance.getToken(); + var count = 0; + + for (var i = 0; i < instance.options.array.length && + ret.length < instance.options.choices ; i++) { + + var elem = instance.options.array[i]; + var foundPos = instance.options.ignoreCase ? + elem.toLowerCase().indexOf(entry.toLowerCase()) : + elem.indexOf(entry); + + while (foundPos != -1) { + if (foundPos == 0 && elem.length != entry.length) { + ret.push("
    • " + elem.substr(0, entry.length) + "" + + elem.substr(entry.length) + "
    • "); + break; + } else if (entry.length >= instance.options.partialChars && + instance.options.partialSearch && foundPos != -1) { + if (instance.options.fullSearch || /\s/.test(elem.substr(foundPos-1,1))) { + partial.push("
    • " + elem.substr(0, foundPos) + "" + + elem.substr(foundPos, entry.length) + "" + elem.substr( + foundPos + entry.length) + "
    • "); + break; + } + } + + foundPos = instance.options.ignoreCase ? + elem.toLowerCase().indexOf(entry.toLowerCase(), foundPos + 1) : + elem.indexOf(entry, foundPos + 1); + + } + } + if (partial.length) + ret = ret.concat(partial.slice(0, instance.options.choices - ret.length)) + return "
        " + ret.join('') + "
      "; + } + }, options || { }); + } +}); + +// AJAX in-place editor and collection editor +// Full rewrite by Christophe Porteneuve (April 2007). + +// Use this if you notice weird scrolling problems on some browsers, +// the DOM might be a bit confused when this gets called so do this +// waits 1 ms (with setTimeout) until it does the activation +Field.scrollFreeActivate = function(field) { + setTimeout(function() { + Field.activate(field); + }, 1); +} + +Ajax.InPlaceEditor = Class.create(); +Object.extend(Ajax.InPlaceEditor, { + DefaultOptions: { + ajaxOptions: { }, + autoRows: 3, // Use when multi-line w/ rows == 1 + cancelControl: 'link', // 'link'|'button'|false + cancelText: 'cancel', + clickToEditText: 'Click to edit', + externalControl: null, // id|elt + externalControlOnly: false, + fieldPostCreation: 'activate', // 'activate'|'focus'|false + formClassName: 'inplaceeditor-form', + formId: null, // id|elt + highlightColor: '#ffff99', + highlightEndColor: '#ffffff', + hoverClassName: '', + htmlResponse: true, + loadingClassName: 'inplaceeditor-loading', + loadingText: 'Loading...', + okControl: 'button', // 'link'|'button'|false + okText: 'ok', + paramName: 'value', + rows: 1, // If 1 and multi-line, uses autoRows + savingClassName: 'inplaceeditor-saving', + savingText: 'Saving...', + size: 0, + stripLoadedTextTags: false, + submitOnBlur: false, + textAfterControls: '', + textBeforeControls: '', + textBetweenControls: '' + }, + DefaultCallbacks: { + callback: function(form) { + return Form.serialize(form); + }, + onComplete: function(transport, element) { + // For backward compatibility, this one is bound to the IPE, and passes + // the element directly. It was too often customized, so we don't break it. + new Effect.Highlight(element, { + startcolor: this.options.highlightColor, keepBackgroundImage: true }); + }, + onEnterEditMode: null, + onEnterHover: function(ipe) { + ipe.element.style.backgroundColor = ipe.options.highlightColor; + if (ipe._effect) + ipe._effect.cancel(); + }, + onFailure: function(transport, ipe) { + alert('Error communication with the server: ' + transport.responseText.stripTags()); + }, + onFormCustomization: null, // Takes the IPE and its generated form, after editor, before controls. + onLeaveEditMode: null, + onLeaveHover: function(ipe) { + ipe._effect = new Effect.Highlight(ipe.element, { + startcolor: ipe.options.highlightColor, endcolor: ipe.options.highlightEndColor, + restorecolor: ipe._originalBackground, keepBackgroundImage: true + }); + } + }, + Listeners: { + click: 'enterEditMode', + keydown: 'checkForEscapeOrReturn', + mouseover: 'enterHover', + mouseout: 'leaveHover' + } +}); +Ajax.InPlaceEditor.prototype = { + initialize: function(element, url, options) { + this.url = url; + this.element = element = $(element); + this.prepareOptions(); + this._controls = { }; + arguments.callee.dealWithDeprecatedOptions(options); // DEPRECATION LAYER!!! + Object.extend(this.options, options || { }); + if (!this.options.formId && this.element.id) { + this.options.formId = this.element.id + '-inplaceeditor'; + if ($(this.options.formId)) + this.options.formId = ''; + } + if (this.options.externalControl) + this.options.externalControl = $(this.options.externalControl); + if (!this.options.externalControl) + this.options.externalControlOnly = false; + this._originalBackground = this.element.getStyle('background-color') || 'transparent'; + this.element.title = this.options.clickToEditText; + this._boundCancelHandler = this.handleFormCancellation.bind(this); + this._boundComplete = (this.options.onComplete || Prototype.emptyFunction).bind(this); + this._boundFailureHandler = this.handleAJAXFailure.bind(this); + this._boundSubmitHandler = this.handleFormSubmission.bind(this); + this._boundWrapperHandler = this.wrapUp.bind(this); + this.registerListeners(); + }, + checkForEscapeOrReturn: function(e) { + if (!this._editing || e.ctrlKey || e.altKey || e.shiftKey) return; + if (Event.KEY_ESC == e.keyCode) + this.handleFormCancellation(e); + else if (Event.KEY_RETURN == e.keyCode) + this.handleFormSubmission(e); + }, + createControl: function(mode, handler, extraClasses) { + var control = this.options[mode + 'Control']; + var text = this.options[mode + 'Text']; + if ('button' == control) { + var btn = document.createElement('input'); + btn.type = 'submit'; + btn.value = text; + btn.className = 'editor_' + mode + '_button'; + if ('cancel' == mode) + btn.onclick = this._boundCancelHandler; + this._form.appendChild(btn); + this._controls[mode] = btn; + } else if ('link' == control) { + var link = document.createElement('a'); + link.href = '#'; + link.appendChild(document.createTextNode(text)); + link.onclick = 'cancel' == mode ? this._boundCancelHandler : this._boundSubmitHandler; + link.className = 'editor_' + mode + '_link'; + if (extraClasses) + link.className += ' ' + extraClasses; + this._form.appendChild(link); + this._controls[mode] = link; + } + }, + createEditField: function() { + var text = (this.options.loadTextURL ? this.options.loadingText : this.getText()); + var fld; + if (1 >= this.options.rows && !/\r|\n/.test(this.getText())) { + fld = document.createElement('input'); + fld.type = 'text'; + var size = this.options.size || this.options.cols || 0; + if (0 < size) fld.size = size; + } else { + fld = document.createElement('textarea'); + fld.rows = (1 >= this.options.rows ? this.options.autoRows : this.options.rows); + fld.cols = this.options.cols || 40; + } + fld.name = this.options.paramName; + fld.value = text; // No HTML breaks conversion anymore + fld.className = 'editor_field'; + if (this.options.submitOnBlur) + fld.onblur = this._boundSubmitHandler; + this._controls.editor = fld; + if (this.options.loadTextURL) + this.loadExternalText(); + this._form.appendChild(this._controls.editor); + }, + createForm: function() { + var ipe = this; + function addText(mode, condition) { + var text = ipe.options['text' + mode + 'Controls']; + if (!text || condition === false) return; + ipe._form.appendChild(document.createTextNode(text)); + }; + this._form = $(document.createElement('form')); + this._form.id = this.options.formId; + this._form.addClassName(this.options.formClassName); + this._form.onsubmit = this._boundSubmitHandler; + this.createEditField(); + if ('textarea' == this._controls.editor.tagName.toLowerCase()) + this._form.appendChild(document.createElement('br')); + if (this.options.onFormCustomization) + this.options.onFormCustomization(this, this._form); + addText('Before', this.options.okControl || this.options.cancelControl); + this.createControl('ok', this._boundSubmitHandler); + addText('Between', this.options.okControl && this.options.cancelControl); + this.createControl('cancel', this._boundCancelHandler, 'editor_cancel'); + addText('After', this.options.okControl || this.options.cancelControl); + }, + destroy: function() { + if (this._oldInnerHTML) + this.element.innerHTML = this._oldInnerHTML; + this.leaveEditMode(); + this.unregisterListeners(); + }, + enterEditMode: function(e) { + if (this._saving || this._editing) return; + this._editing = true; + this.triggerCallback('onEnterEditMode'); + if (this.options.externalControl) + this.options.externalControl.hide(); + this.element.hide(); + this.createForm(); + this.element.parentNode.insertBefore(this._form, this.element); + if (!this.options.loadTextURL) + this.postProcessEditField(); + if (e) Event.stop(e); + }, + enterHover: function(e) { + if (this.options.hoverClassName) + this.element.addClassName(this.options.hoverClassName); + if (this._saving) return; + this.triggerCallback('onEnterHover'); + }, + getText: function() { + return this.element.innerHTML; + }, + handleAJAXFailure: function(transport) { + this.triggerCallback('onFailure', transport); + if (this._oldInnerHTML) { + this.element.innerHTML = this._oldInnerHTML; + this._oldInnerHTML = null; + } + }, + handleFormCancellation: function(e) { + this.wrapUp(); + if (e) Event.stop(e); + }, + handleFormSubmission: function(e) { + var form = this._form; + var value = $F(this._controls.editor); + this.prepareSubmission(); + var params = this.options.callback(form, value); + params = (params ? params + '&' : '?') + 'editorId=' + this.element.id; + if (this.options.htmlResponse) { + var options = Object.extend({ evalScripts: true }, this.options.ajaxOptions); + Object.extend(options, { + parameters: params, + onComplete: this._boundWrapperHandler, + onFailure: this._boundFailureHandler + }); + new Ajax.Updater({ success: this.element }, this.url, options); + } else { + var options = Object.extend({ method: 'get' }, this.options.ajaxOptions); + Object.extend(options, { + parameters: params, + onComplete: this._boundWrapperHandler, + onFailure: this._boundFailureHandler + }); + new Ajax.Request(this.url, options); + } + if (e) Event.stop(e); + }, + leaveEditMode: function() { + this.element.removeClassName(this.options.savingClassName); + this.removeForm(); + this.leaveHover(); + this.element.style.backgroundColor = this._originalBackground; + this.element.show(); + if (this.options.externalControl) + this.options.externalControl.show(); + this._saving = false; + this._editing = false; + this._oldInnerHTML = null; + this.triggerCallback('onLeaveEditMode'); + }, + leaveHover: function(e) { + if (this.options.hoverClassName) + this.element.removeClassName(this.options.hoverClassName); + if (this._saving) return; + this.triggerCallback('onLeaveHover'); + }, + loadExternalText: function() { + this._form.addClassName(this.options.loadingClassName); + this._controls.editor.disabled = true; + var options = Object.extend({ method: 'get' }, this.options.ajaxOptions); + Object.extend(options, { + parameters: 'editorId=' + encodeURIComponent(this.element.id), + onComplete: Prototype.emptyFunction, + onSuccess: function(transport) { + this._form.removeClassName(this.options.loadingClassName); + var text = transport.responseText; + if (this.options.stripLoadedTextTags) + text = text.stripTags(); + this._controls.editor.value = text; + this._controls.editor.disabled = false; + this.postProcessEditField(); + }.bind(this), + onFailure: this._boundFailureHandler + }); + new Ajax.Request(this.options.loadTextURL, options); + }, + postProcessEditField: function() { + var fpc = this.options.fieldPostCreation; + if (fpc) + $(this._controls.editor)['focus' == fpc ? 'focus' : 'activate'](); + }, + prepareOptions: function() { + this.options = Object.clone(Ajax.InPlaceEditor.DefaultOptions); + Object.extend(this.options, Ajax.InPlaceEditor.DefaultCallbacks); + [this._extraDefaultOptions].flatten().compact().each(function(defs) { + Object.extend(this.options, defs); + }.bind(this)); + }, + prepareSubmission: function() { + this._saving = true; + this.removeForm(); + this.leaveHover(); + this.showSaving(); + }, + registerListeners: function() { + this._listeners = { }; + var listener; + $H(Ajax.InPlaceEditor.Listeners).each(function(pair) { + listener = this[pair.value].bind(this); + this._listeners[pair.key] = listener; + if (!this.options.externalControlOnly) + this.element.observe(pair.key, listener); + if (this.options.externalControl) + this.options.externalControl.observe(pair.key, listener); + }.bind(this)); + }, + removeForm: function() { + if (!this._form) return; + this._form.remove(); + this._form = null; + this._controls = { }; + }, + showSaving: function() { + this._oldInnerHTML = this.element.innerHTML; + this.element.innerHTML = this.options.savingText; + this.element.addClassName(this.options.savingClassName); + this.element.style.backgroundColor = this._originalBackground; + this.element.show(); + }, + triggerCallback: function(cbName, arg) { + if ('function' == typeof this.options[cbName]) { + this.options[cbName](this, arg); + } + }, + unregisterListeners: function() { + $H(this._listeners).each(function(pair) { + if (!this.options.externalControlOnly) + this.element.stopObserving(pair.key, pair.value); + if (this.options.externalControl) + this.options.externalControl.stopObserving(pair.key, pair.value); + }.bind(this)); + }, + wrapUp: function(transport) { + this.leaveEditMode(); + // Can't use triggerCallback due to backward compatibility: requires + // binding + direct element + this._boundComplete(transport, this.element); + } +}; +Object.extend(Ajax.InPlaceEditor.prototype, { + dispose: Ajax.InPlaceEditor.prototype.destroy +}); + + +Ajax.InPlaceCollectionEditor = Class.create(); +Ajax.InPlaceCollectionEditor.DefaultOptions = { + loadingCollectionText: 'Loading options...' +}; +Object.extend(Ajax.InPlaceCollectionEditor.prototype, Ajax.InPlaceEditor.prototype); +Object.extend(Ajax.InPlaceCollectionEditor.prototype, { + initialize: function(element, url, options) { + this._extraDefaultOptions = Ajax.InPlaceCollectionEditor.DefaultOptions; + Ajax.InPlaceEditor.prototype.initialize.call(this, element, url, options); + }, + + createEditField: function() { + var list = document.createElement('select'); + list.name = this.options.paramName; + list.size = 1; + this._controls.editor = list; + this._collection = this.options.collection || []; + if (this.options.loadCollectionURL) + this.loadCollection(); + else + this.checkForExternalText(); + this._form.appendChild(this._controls.editor); + }, + + loadCollection: function() { + this._form.addClassName(this.options.loadingClassName); + this.showLoadingText(this.options.loadingCollectionText); + var options = Object.extend({ method: 'get' }, this.options.ajaxOptions); + Object.extend(options, { + parameters: 'editorId=' + encodeURIComponent(this.element.id), + onComplete: Prototype.emptyFunction, + onSuccess: function(transport) { + var js = transport.responseText.strip(); + if (!/^\[.*\]$/.test(js)) // TODO: improve sanity check + throw 'Server returned an invalid collection representation.'; + this._collection = eval(js); + this.checkForExternalText(); + }.bind(this), + onFailure: this.onFailure + }); + new Ajax.Request(this.options.loadCollectionURL, options); + }, + + showLoadingText: function(text) { + this._controls.editor.disabled = true; + var tempOption = this._controls.editor.firstChild; + if (!tempOption) { + tempOption = document.createElement('option'); + tempOption.value = ''; + this._controls.editor.appendChild(tempOption); + tempOption.selected = true; + } + tempOption.update((text || '').stripScripts().stripTags()); + }, + + checkForExternalText: function() { + this._text = this.getText(); + if (this.options.loadTextURL) + this.loadExternalText(); + else + this.buildOptionList(); + }, + + loadExternalText: function() { + this.showLoadingText(this.options.loadingText); + var options = Object.extend({ method: 'get' }, this.options.ajaxOptions); + Object.extend(options, { + parameters: 'editorId=' + encodeURIComponent(this.element.id), + onComplete: Prototype.emptyFunction, + onSuccess: function(transport) { + this._text = transport.responseText.strip(); + this.buildOptionList(); + }.bind(this), + onFailure: this.onFailure + }); + new Ajax.Request(this.options.loadTextURL, options); + }, + + buildOptionList: function() { + this._form.removeClassName(this.options.loadingClassName); + this._collection = this._collection.map(function(entry) { + return 2 === entry.length ? entry : [entry, entry].flatten(); + }); + var marker = ('value' in this.options) ? this.options.value : this._text; + var textFound = this._collection.any(function(entry) { + return entry[0] == marker; + }.bind(this)); + this._controls.editor.update(''); + var option; + this._collection.each(function(entry, index) { + option = document.createElement('option'); + option.value = entry[0]; + option.selected = textFound ? entry[0] == marker : 0 == index; + option.appendChild(document.createTextNode(entry[1])); + this._controls.editor.appendChild(option); + }.bind(this)); + this._controls.editor.disabled = false; + Field.scrollFreeActivate(this._controls.editor); + } +}); + +//**** DEPRECATION LAYER FOR InPlace[Collection]Editor! **** +//**** This only exists for a while, in order to let **** +//**** users adapt to the new API. Read up on the new **** +//**** API and convert your code to it ASAP! **** + +Ajax.InPlaceEditor.prototype.initialize.dealWithDeprecatedOptions = function(options) { + if (!options) return; + function fallback(name, expr) { + if (name in options || expr === undefined) return; + options[name] = expr; + }; + fallback('cancelControl', (options.cancelLink ? 'link' : (options.cancelButton ? 'button' : + options.cancelLink == options.cancelButton == false ? false : undefined))); + fallback('okControl', (options.okLink ? 'link' : (options.okButton ? 'button' : + options.okLink == options.okButton == false ? false : undefined))); + fallback('highlightColor', options.highlightcolor); + fallback('highlightEndColor', options.highlightendcolor); +}; + + +// Delayed observer, like Form.Element.Observer, +// but waits for delay after last key input +// Ideal for live-search fields + +Form.Element.DelayedObserver = Class.create(); +Form.Element.DelayedObserver.prototype = { + initialize: function(element, delay, callback) { + this.delay = delay || 0.5; + this.element = $(element); + this.callback = callback; + this.timer = null; + this.lastValue = $F(this.element); + Event.observe(this.element,'keyup',this.delayedListener.bindAsEventListener(this)); + }, + delayedListener: function(event) { + if(this.lastValue == $F(this.element)) return; + if(this.timer) clearTimeout(this.timer); + this.timer = setTimeout(this.onTimerEvent.bind(this), this.delay * 1000); + this.lastValue = $F(this.element); + }, + onTimerEvent: function() { + this.timer = null; + this.callback(this.element, $F(this.element)); + } +}; diff -Nur mephisto-0.7.3/vendor/plugins/rspec/story_server/prototype/javascripts/dragdrop.js technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/story_server/prototype/javascripts/dragdrop.js --- mephisto-0.7.3/vendor/plugins/rspec/story_server/prototype/javascripts/dragdrop.js 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/story_server/prototype/javascripts/dragdrop.js 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,976 @@ +// script.aculo.us dragdrop.js v1.8.0_pre1, Fri Oct 12 21:34:51 +0200 2007 + +// Copyright (c) 2005-2007 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) +// (c) 2005-2007 Sammi Williams (http://www.oriontransfer.co.nz, sammi@oriontransfer.co.nz) +// +// script.aculo.us is freely distributable under the terms of an MIT-style license. +// For details, see the script.aculo.us web site: http://script.aculo.us/ + +if(Object.isUndefined(Effect)) + throw("dragdrop.js requires including script.aculo.us' effects.js library"); + +var Droppables = { + drops: [], + + remove: function(element) { + this.drops = this.drops.reject(function(d) { return d.element==$(element) }); + }, + + add: function(element) { + element = $(element); + var options = Object.extend({ + greedy: true, + hoverclass: null, + tree: false + }, arguments[1] || { }); + + // cache containers + if(options.containment) { + options._containers = []; + var containment = options.containment; + if(Object.isArray(containment)) { + containment.each( function(c) { options._containers.push($(c)) }); + } else { + options._containers.push($(containment)); + } + } + + if(options.accept) options.accept = [options.accept].flatten(); + + Element.makePositioned(element); // fix IE + options.element = element; + + this.drops.push(options); + }, + + findDeepestChild: function(drops) { + deepest = drops[0]; + + for (i = 1; i < drops.length; ++i) + if (Element.isParent(drops[i].element, deepest.element)) + deepest = drops[i]; + + return deepest; + }, + + isContained: function(element, drop) { + var containmentNode; + if(drop.tree) { + containmentNode = element.treeNode; + } else { + containmentNode = element.parentNode; + } + return drop._containers.detect(function(c) { return containmentNode == c }); + }, + + isAffected: function(point, element, drop) { + return ( + (drop.element!=element) && + ((!drop._containers) || + this.isContained(element, drop)) && + ((!drop.accept) || + (Element.classNames(element).detect( + function(v) { return drop.accept.include(v) } ) )) && + Position.within(drop.element, point[0], point[1]) ); + }, + + deactivate: function(drop) { + if(drop.hoverclass) + Element.removeClassName(drop.element, drop.hoverclass); + this.last_active = null; + }, + + activate: function(drop) { + if(drop.hoverclass) + Element.addClassName(drop.element, drop.hoverclass); + this.last_active = drop; + }, + + show: function(point, element) { + if(!this.drops.length) return; + var drop, affected = []; + + this.drops.each( function(drop) { + if(Droppables.isAffected(point, element, drop)) + affected.push(drop); + }); + + if(affected.length>0) + drop = Droppables.findDeepestChild(affected); + + if(this.last_active && this.last_active != drop) this.deactivate(this.last_active); + if (drop) { + Position.within(drop.element, point[0], point[1]); + if(drop.onHover) + drop.onHover(element, drop.element, Position.overlap(drop.overlap, drop.element)); + + if (drop != this.last_active) Droppables.activate(drop); + } + }, + + fire: function(event, element) { + if(!this.last_active) return; + Position.prepare(); + + if (this.isAffected([Event.pointerX(event), Event.pointerY(event)], element, this.last_active)) + if (this.last_active.onDrop) { + this.last_active.onDrop(element, this.last_active.element, event); + return true; + } + }, + + reset: function() { + if(this.last_active) + this.deactivate(this.last_active); + } +} + +var Draggables = { + drags: [], + observers: [], + + register: function(draggable) { + if(this.drags.length == 0) { + this.eventMouseUp = this.endDrag.bindAsEventListener(this); + this.eventMouseMove = this.updateDrag.bindAsEventListener(this); + this.eventKeypress = this.keyPress.bindAsEventListener(this); + + Event.observe(document, "mouseup", this.eventMouseUp); + Event.observe(document, "mousemove", this.eventMouseMove); + Event.observe(document, "keypress", this.eventKeypress); + } + this.drags.push(draggable); + }, + + unregister: function(draggable) { + this.drags = this.drags.reject(function(d) { return d==draggable }); + if(this.drags.length == 0) { + Event.stopObserving(document, "mouseup", this.eventMouseUp); + Event.stopObserving(document, "mousemove", this.eventMouseMove); + Event.stopObserving(document, "keypress", this.eventKeypress); + } + }, + + activate: function(draggable) { + if(draggable.options.delay) { + this._timeout = setTimeout(function() { + Draggables._timeout = null; + window.focus(); + Draggables.activeDraggable = draggable; + }.bind(this), draggable.options.delay); + } else { + window.focus(); // allows keypress events if window isn't currently focused, fails for Safari + this.activeDraggable = draggable; + } + }, + + deactivate: function() { + this.activeDraggable = null; + }, + + updateDrag: function(event) { + if(!this.activeDraggable) return; + var pointer = [Event.pointerX(event), Event.pointerY(event)]; + // Mozilla-based browsers fire successive mousemove events with + // the same coordinates, prevent needless redrawing (moz bug?) + if(this._lastPointer && (this._lastPointer.inspect() == pointer.inspect())) return; + this._lastPointer = pointer; + + this.activeDraggable.updateDrag(event, pointer); + }, + + endDrag: function(event) { + if(this._timeout) { + clearTimeout(this._timeout); + this._timeout = null; + } + if(!this.activeDraggable) return; + this._lastPointer = null; + this.activeDraggable.endDrag(event); + this.activeDraggable = null; + }, + + keyPress: function(event) { + if(this.activeDraggable) + this.activeDraggable.keyPress(event); + }, + + addObserver: function(observer) { + this.observers.push(observer); + this._cacheObserverCallbacks(); + }, + + removeObserver: function(element) { // element instead of observer fixes mem leaks + this.observers = this.observers.reject( function(o) { return o.element==element }); + this._cacheObserverCallbacks(); + }, + + notify: function(eventName, draggable, event) { // 'onStart', 'onEnd', 'onDrag' + if(this[eventName+'Count'] > 0) + this.observers.each( function(o) { + if(o[eventName]) o[eventName](eventName, draggable, event); + }); + if(draggable.options[eventName]) draggable.options[eventName](draggable, event); + }, + + _cacheObserverCallbacks: function() { + ['onStart','onEnd','onDrag'].each( function(eventName) { + Draggables[eventName+'Count'] = Draggables.observers.select( + function(o) { return o[eventName]; } + ).length; + }); + } +} + +/*--------------------------------------------------------------------------*/ + +var Draggable = Class.create(); +Draggable._dragging = { }; + +Draggable.prototype = { + initialize: function(element) { + var defaults = { + handle: false, + reverteffect: function(element, top_offset, left_offset) { + var dur = Math.sqrt(Math.abs(top_offset^2)+Math.abs(left_offset^2))*0.02; + new Effect.Move(element, { x: -left_offset, y: -top_offset, duration: dur, + queue: {scope:'_draggable', position:'end'} + }); + }, + endeffect: function(element) { + var toOpacity = Object.isNumber(element._opacity) ? element._opacity : 1.0; + new Effect.Opacity(element, {duration:0.2, from:0.7, to:toOpacity, + queue: {scope:'_draggable', position:'end'}, + afterFinish: function(){ + Draggable._dragging[element] = false + } + }); + }, + zindex: 1000, + revert: false, + quiet: false, + scroll: false, + scrollSensitivity: 20, + scrollSpeed: 15, + snap: false, // false, or xy or [x,y] or function(x,y){ return [x,y] } + delay: 0 + }; + + if(!arguments[1] || Object.isUndefined(arguments[1].endeffect)) + Object.extend(defaults, { + starteffect: function(element) { + element._opacity = Element.getOpacity(element); + Draggable._dragging[element] = true; + new Effect.Opacity(element, {duration:0.2, from:element._opacity, to:0.7}); + } + }); + + var options = Object.extend(defaults, arguments[1] || { }); + + this.element = $(element); + + if(options.handle && Object.isString(options.handle)) + this.handle = this.element.down('.'+options.handle, 0); + + if(!this.handle) this.handle = $(options.handle); + if(!this.handle) this.handle = this.element; + + if(options.scroll && !options.scroll.scrollTo && !options.scroll.outerHTML) { + options.scroll = $(options.scroll); + this._isScrollChild = Element.childOf(this.element, options.scroll); + } + + Element.makePositioned(this.element); // fix IE + + this.options = options; + this.dragging = false; + + this.eventMouseDown = this.initDrag.bindAsEventListener(this); + Event.observe(this.handle, "mousedown", this.eventMouseDown); + + Draggables.register(this); + }, + + destroy: function() { + Event.stopObserving(this.handle, "mousedown", this.eventMouseDown); + Draggables.unregister(this); + }, + + currentDelta: function() { + return([ + parseInt(Element.getStyle(this.element,'left') || '0'), + parseInt(Element.getStyle(this.element,'top') || '0')]); + }, + + initDrag: function(event) { + if(!Object.isUndefined(Draggable._dragging[this.element]) && + Draggable._dragging[this.element]) return; + if(Event.isLeftClick(event)) { + // abort on form elements, fixes a Firefox issue + var src = Event.element(event); + if((tag_name = src.tagName.toUpperCase()) && ( + tag_name=='INPUT' || + tag_name=='SELECT' || + tag_name=='OPTION' || + tag_name=='BUTTON' || + tag_name=='TEXTAREA')) return; + + var pointer = [Event.pointerX(event), Event.pointerY(event)]; + var pos = Position.cumulativeOffset(this.element); + this.offset = [0,1].map( function(i) { return (pointer[i] - pos[i]) }); + + Draggables.activate(this); + Event.stop(event); + } + }, + + startDrag: function(event) { + this.dragging = true; + if(!this.delta) + this.delta = this.currentDelta(); + + if(this.options.zindex) { + this.originalZ = parseInt(Element.getStyle(this.element,'z-index') || 0); + this.element.style.zIndex = this.options.zindex; + } + + if(this.options.ghosting) { + this._clone = this.element.cloneNode(true); + this.element._originallyAbsolute = (this.element.getStyle('position') == 'absolute'); + if (!this.element._originallyAbsolute) + Position.absolutize(this.element); + this.element.parentNode.insertBefore(this._clone, this.element); + } + + if(this.options.scroll) { + if (this.options.scroll == window) { + var where = this._getWindowScroll(this.options.scroll); + this.originalScrollLeft = where.left; + this.originalScrollTop = where.top; + } else { + this.originalScrollLeft = this.options.scroll.scrollLeft; + this.originalScrollTop = this.options.scroll.scrollTop; + } + } + + Draggables.notify('onStart', this, event); + + if(this.options.starteffect) this.options.starteffect(this.element); + }, + + updateDrag: function(event, pointer) { + if(!this.dragging) this.startDrag(event); + + if(!this.options.quiet){ + Position.prepare(); + Droppables.show(pointer, this.element); + } + + Draggables.notify('onDrag', this, event); + + this.draw(pointer); + if(this.options.change) this.options.change(this); + + if(this.options.scroll) { + this.stopScrolling(); + + var p; + if (this.options.scroll == window) { + with(this._getWindowScroll(this.options.scroll)) { p = [ left, top, left+width, top+height ]; } + } else { + p = Position.page(this.options.scroll); + p[0] += this.options.scroll.scrollLeft + Position.deltaX; + p[1] += this.options.scroll.scrollTop + Position.deltaY; + p.push(p[0]+this.options.scroll.offsetWidth); + p.push(p[1]+this.options.scroll.offsetHeight); + } + var speed = [0,0]; + if(pointer[0] < (p[0]+this.options.scrollSensitivity)) speed[0] = pointer[0]-(p[0]+this.options.scrollSensitivity); + if(pointer[1] < (p[1]+this.options.scrollSensitivity)) speed[1] = pointer[1]-(p[1]+this.options.scrollSensitivity); + if(pointer[0] > (p[2]-this.options.scrollSensitivity)) speed[0] = pointer[0]-(p[2]-this.options.scrollSensitivity); + if(pointer[1] > (p[3]-this.options.scrollSensitivity)) speed[1] = pointer[1]-(p[3]-this.options.scrollSensitivity); + this.startScrolling(speed); + } + + // fix AppleWebKit rendering + if(Prototype.Browser.WebKit) window.scrollBy(0,0); + + Event.stop(event); + }, + + finishDrag: function(event, success) { + this.dragging = false; + + if(this.options.quiet){ + Position.prepare(); + var pointer = [Event.pointerX(event), Event.pointerY(event)]; + Droppables.show(pointer, this.element); + } + + if(this.options.ghosting) { + if (!this.element._originallyAbsolute) + Position.relativize(this.element); + delete this.element._originallyAbsolute; + Element.remove(this._clone); + this._clone = null; + } + + var dropped = false; + if(success) { + dropped = Droppables.fire(event, this.element); + if (!dropped) dropped = false; + } + if(dropped && this.options.onDropped) this.options.onDropped(this.element); + Draggables.notify('onEnd', this, event); + + var revert = this.options.revert; + if(revert && Object.isFunction(revert)) revert = revert(this.element); + + var d = this.currentDelta(); + if(revert && this.options.reverteffect) { + if (dropped == 0 || revert != 'failure') + this.options.reverteffect(this.element, + d[1]-this.delta[1], d[0]-this.delta[0]); + } else { + this.delta = d; + } + + if(this.options.zindex) + this.element.style.zIndex = this.originalZ; + + if(this.options.endeffect) + this.options.endeffect(this.element); + + Draggables.deactivate(this); + Droppables.reset(); + }, + + keyPress: function(event) { + if(event.keyCode!=Event.KEY_ESC) return; + this.finishDrag(event, false); + Event.stop(event); + }, + + endDrag: function(event) { + if(!this.dragging) return; + this.stopScrolling(); + this.finishDrag(event, true); + Event.stop(event); + }, + + draw: function(point) { + var pos = Position.cumulativeOffset(this.element); + if(this.options.ghosting) { + var r = Position.realOffset(this.element); + pos[0] += r[0] - Position.deltaX; pos[1] += r[1] - Position.deltaY; + } + + var d = this.currentDelta(); + pos[0] -= d[0]; pos[1] -= d[1]; + + if(this.options.scroll && (this.options.scroll != window && this._isScrollChild)) { + pos[0] -= this.options.scroll.scrollLeft-this.originalScrollLeft; + pos[1] -= this.options.scroll.scrollTop-this.originalScrollTop; + } + + var p = [0,1].map(function(i){ + return (point[i]-pos[i]-this.offset[i]) + }.bind(this)); + + if(this.options.snap) { + if(Object.isFunction(this.options.snap)) { + p = this.options.snap(p[0],p[1],this); + } else { + if(Object.isArray(this.options.snap)) { + p = p.map( function(v, i) { + return (v/this.options.snap[i]).round()*this.options.snap[i] }.bind(this)) + } else { + p = p.map( function(v) { + return (v/this.options.snap).round()*this.options.snap }.bind(this)) + } + }} + + var style = this.element.style; + if((!this.options.constraint) || (this.options.constraint=='horizontal')) + style.left = p[0] + "px"; + if((!this.options.constraint) || (this.options.constraint=='vertical')) + style.top = p[1] + "px"; + + if(style.visibility=="hidden") style.visibility = ""; // fix gecko rendering + }, + + stopScrolling: function() { + if(this.scrollInterval) { + clearInterval(this.scrollInterval); + this.scrollInterval = null; + Draggables._lastScrollPointer = null; + } + }, + + startScrolling: function(speed) { + if(!(speed[0] || speed[1])) return; + this.scrollSpeed = [speed[0]*this.options.scrollSpeed,speed[1]*this.options.scrollSpeed]; + this.lastScrolled = new Date(); + this.scrollInterval = setInterval(this.scroll.bind(this), 10); + }, + + scroll: function() { + var current = new Date(); + var delta = current - this.lastScrolled; + this.lastScrolled = current; + if(this.options.scroll == window) { + with (this._getWindowScroll(this.options.scroll)) { + if (this.scrollSpeed[0] || this.scrollSpeed[1]) { + var d = delta / 1000; + this.options.scroll.scrollTo( left + d*this.scrollSpeed[0], top + d*this.scrollSpeed[1] ); + } + } + } else { + this.options.scroll.scrollLeft += this.scrollSpeed[0] * delta / 1000; + this.options.scroll.scrollTop += this.scrollSpeed[1] * delta / 1000; + } + + Position.prepare(); + Droppables.show(Draggables._lastPointer, this.element); + Draggables.notify('onDrag', this); + if (this._isScrollChild) { + Draggables._lastScrollPointer = Draggables._lastScrollPointer || $A(Draggables._lastPointer); + Draggables._lastScrollPointer[0] += this.scrollSpeed[0] * delta / 1000; + Draggables._lastScrollPointer[1] += this.scrollSpeed[1] * delta / 1000; + if (Draggables._lastScrollPointer[0] < 0) + Draggables._lastScrollPointer[0] = 0; + if (Draggables._lastScrollPointer[1] < 0) + Draggables._lastScrollPointer[1] = 0; + this.draw(Draggables._lastScrollPointer); + } + + if(this.options.change) this.options.change(this); + }, + + _getWindowScroll: function(w) { + var T, L, W, H; + with (w.document) { + if (w.document.documentElement && documentElement.scrollTop) { + T = documentElement.scrollTop; + L = documentElement.scrollLeft; + } else if (w.document.body) { + T = body.scrollTop; + L = body.scrollLeft; + } + if (w.innerWidth) { + W = w.innerWidth; + H = w.innerHeight; + } else if (w.document.documentElement && documentElement.clientWidth) { + W = documentElement.clientWidth; + H = documentElement.clientHeight; + } else { + W = body.offsetWidth; + H = body.offsetHeight + } + } + return { top: T, left: L, width: W, height: H }; + } +} + +/*--------------------------------------------------------------------------*/ + +var SortableObserver = Class.create(); +SortableObserver.prototype = { + initialize: function(element, observer) { + this.element = $(element); + this.observer = observer; + this.lastValue = Sortable.serialize(this.element); + }, + + onStart: function() { + this.lastValue = Sortable.serialize(this.element); + }, + + onEnd: function() { + Sortable.unmark(); + if(this.lastValue != Sortable.serialize(this.element)) + this.observer(this.element) + } +} + +var Sortable = { + SERIALIZE_RULE: /^[^_\-](?:[A-Za-z0-9\-\_]*)[_](.*)$/, + + sortables: { }, + + _findRootElement: function(element) { + while (element.tagName.toUpperCase() != "BODY") { + if(element.id && Sortable.sortables[element.id]) return element; + element = element.parentNode; + } + }, + + options: function(element) { + element = Sortable._findRootElement($(element)); + if(!element) return; + return Sortable.sortables[element.id]; + }, + + destroy: function(element){ + var s = Sortable.options(element); + + if(s) { + Draggables.removeObserver(s.element); + s.droppables.each(function(d){ Droppables.remove(d) }); + s.draggables.invoke('destroy'); + + delete Sortable.sortables[s.element.id]; + } + }, + + create: function(element) { + element = $(element); + var options = Object.extend({ + element: element, + tag: 'li', // assumes li children, override with tag: 'tagname' + dropOnEmpty: false, + tree: false, + treeTag: 'ul', + overlap: 'vertical', // one of 'vertical', 'horizontal' + constraint: 'vertical', // one of 'vertical', 'horizontal', false + containment: element, // also takes array of elements (or id's); or false + handle: false, // or a CSS class + only: false, + delay: 0, + hoverclass: null, + ghosting: false, + quiet: false, + scroll: false, + scrollSensitivity: 20, + scrollSpeed: 15, + format: this.SERIALIZE_RULE, + + // these take arrays of elements or ids and can be + // used for better initialization performance + elements: false, + handles: false, + + onChange: Prototype.emptyFunction, + onUpdate: Prototype.emptyFunction + }, arguments[1] || { }); + + // clear any old sortable with same element + this.destroy(element); + + // build options for the draggables + var options_for_draggable = { + revert: true, + quiet: options.quiet, + scroll: options.scroll, + scrollSpeed: options.scrollSpeed, + scrollSensitivity: options.scrollSensitivity, + delay: options.delay, + ghosting: options.ghosting, + constraint: options.constraint, + handle: options.handle }; + + if(options.starteffect) + options_for_draggable.starteffect = options.starteffect; + + if(options.reverteffect) + options_for_draggable.reverteffect = options.reverteffect; + else + if(options.ghosting) options_for_draggable.reverteffect = function(element) { + element.style.top = 0; + element.style.left = 0; + }; + + if(options.endeffect) + options_for_draggable.endeffect = options.endeffect; + + if(options.zindex) + options_for_draggable.zindex = options.zindex; + + // build options for the droppables + var options_for_droppable = { + overlap: options.overlap, + containment: options.containment, + tree: options.tree, + hoverclass: options.hoverclass, + onHover: Sortable.onHover + } + + var options_for_tree = { + onHover: Sortable.onEmptyHover, + overlap: options.overlap, + containment: options.containment, + hoverclass: options.hoverclass + } + + // fix for gecko engine + Element.cleanWhitespace(element); + + options.draggables = []; + options.droppables = []; + + // drop on empty handling + if(options.dropOnEmpty || options.tree) { + Droppables.add(element, options_for_tree); + options.droppables.push(element); + } + + (options.elements || this.findElements(element, options) || []).each( function(e,i) { + var handle = options.handles ? $(options.handles[i]) : + (options.handle ? $(e).getElementsByClassName(options.handle)[0] : e); + options.draggables.push( + new Draggable(e, Object.extend(options_for_draggable, { handle: handle }))); + Droppables.add(e, options_for_droppable); + if(options.tree) e.treeNode = element; + options.droppables.push(e); + }); + + if(options.tree) { + (Sortable.findTreeElements(element, options) || []).each( function(e) { + Droppables.add(e, options_for_tree); + e.treeNode = element; + options.droppables.push(e); + }); + } + + // keep reference + this.sortables[element.id] = options; + + // for onupdate + Draggables.addObserver(new SortableObserver(element, options.onUpdate)); + + }, + + // return all suitable-for-sortable elements in a guaranteed order + findElements: function(element, options) { + return Element.findChildren( + element, options.only, options.tree ? true : false, options.tag); + }, + + findTreeElements: function(element, options) { + return Element.findChildren( + element, options.only, options.tree ? true : false, options.treeTag); + }, + + onHover: function(element, dropon, overlap) { + if(Element.isParent(dropon, element)) return; + + if(overlap > .33 && overlap < .66 && Sortable.options(dropon).tree) { + return; + } else if(overlap>0.5) { + Sortable.mark(dropon, 'before'); + if(dropon.previousSibling != element) { + var oldParentNode = element.parentNode; + element.style.visibility = "hidden"; // fix gecko rendering + dropon.parentNode.insertBefore(element, dropon); + if(dropon.parentNode!=oldParentNode) + Sortable.options(oldParentNode).onChange(element); + Sortable.options(dropon.parentNode).onChange(element); + } + } else { + Sortable.mark(dropon, 'after'); + var nextElement = dropon.nextSibling || null; + if(nextElement != element) { + var oldParentNode = element.parentNode; + element.style.visibility = "hidden"; // fix gecko rendering + dropon.parentNode.insertBefore(element, nextElement); + if(dropon.parentNode!=oldParentNode) + Sortable.options(oldParentNode).onChange(element); + Sortable.options(dropon.parentNode).onChange(element); + } + } + }, + + onEmptyHover: function(element, dropon, overlap) { + var oldParentNode = element.parentNode; + var droponOptions = Sortable.options(dropon); + + if(!Element.isParent(dropon, element)) { + var index; + + var children = Sortable.findElements(dropon, {tag: droponOptions.tag, only: droponOptions.only}); + var child = null; + + if(children) { + var offset = Element.offsetSize(dropon, droponOptions.overlap) * (1.0 - overlap); + + for (index = 0; index < children.length; index += 1) { + if (offset - Element.offsetSize (children[index], droponOptions.overlap) >= 0) { + offset -= Element.offsetSize (children[index], droponOptions.overlap); + } else if (offset - (Element.offsetSize (children[index], droponOptions.overlap) / 2) >= 0) { + child = index + 1 < children.length ? children[index + 1] : null; + break; + } else { + child = children[index]; + break; + } + } + } + + dropon.insertBefore(element, child); + + Sortable.options(oldParentNode).onChange(element); + droponOptions.onChange(element); + } + }, + + unmark: function() { + if(Sortable._marker) Sortable._marker.hide(); + }, + + mark: function(dropon, position) { + // mark on ghosting only + var sortable = Sortable.options(dropon.parentNode); + if(sortable && !sortable.ghosting) return; + + if(!Sortable._marker) { + Sortable._marker = + ($('dropmarker') || Element.extend(document.createElement('DIV'))). + hide().addClassName('dropmarker').setStyle({position:'absolute'}); + document.getElementsByTagName("body").item(0).appendChild(Sortable._marker); + } + var offsets = Position.cumulativeOffset(dropon); + Sortable._marker.setStyle({left: offsets[0]+'px', top: offsets[1] + 'px'}); + + if(position=='after') + if(sortable.overlap == 'horizontal') + Sortable._marker.setStyle({left: (offsets[0]+dropon.clientWidth) + 'px'}); + else + Sortable._marker.setStyle({top: (offsets[1]+dropon.clientHeight) + 'px'}); + + Sortable._marker.show(); + }, + + _tree: function(element, options, parent) { + var children = Sortable.findElements(element, options) || []; + + for (var i = 0; i < children.length; ++i) { + var match = children[i].id.match(options.format); + + if (!match) continue; + + var child = { + id: encodeURIComponent(match ? match[1] : null), + element: element, + parent: parent, + children: [], + position: parent.children.length, + container: $(children[i]).down(options.treeTag) + } + + /* Get the element containing the children and recurse over it */ + if (child.container) + this._tree(child.container, options, child) + + parent.children.push (child); + } + + return parent; + }, + + tree: function(element) { + element = $(element); + var sortableOptions = this.options(element); + var options = Object.extend({ + tag: sortableOptions.tag, + treeTag: sortableOptions.treeTag, + only: sortableOptions.only, + name: element.id, + format: sortableOptions.format + }, arguments[1] || { }); + + var root = { + id: null, + parent: null, + children: [], + container: element, + position: 0 + } + + return Sortable._tree(element, options, root); + }, + + /* Construct a [i] index for a particular node */ + _constructIndex: function(node) { + var index = ''; + do { + if (node.id) index = '[' + node.position + ']' + index; + } while ((node = node.parent) != null); + return index; + }, + + sequence: function(element) { + element = $(element); + var options = Object.extend(this.options(element), arguments[1] || { }); + + return $(this.findElements(element, options) || []).map( function(item) { + return item.id.match(options.format) ? item.id.match(options.format)[1] : ''; + }); + }, + + setSequence: function(element, new_sequence) { + element = $(element); + var options = Object.extend(this.options(element), arguments[2] || { }); + + var nodeMap = { }; + this.findElements(element, options).each( function(n) { + if (n.id.match(options.format)) + nodeMap[n.id.match(options.format)[1]] = [n, n.parentNode]; + n.parentNode.removeChild(n); + }); + + new_sequence.each(function(ident) { + var n = nodeMap[ident]; + if (n) { + n[1].appendChild(n[0]); + delete nodeMap[ident]; + } + }); + }, + + serialize: function(element) { + element = $(element); + var options = Object.extend(Sortable.options(element), arguments[1] || { }); + var name = encodeURIComponent( + (arguments[1] && arguments[1].name) ? arguments[1].name : element.id); + + if (options.tree) { + return Sortable.tree(element, arguments[1]).children.map( function (item) { + return [name + Sortable._constructIndex(item) + "[id]=" + + encodeURIComponent(item.id)].concat(item.children.map(arguments.callee)); + }).flatten().join('&'); + } else { + return Sortable.sequence(element, arguments[1]).map( function(item) { + return name + "[]=" + encodeURIComponent(item); + }).join('&'); + } + } +} + +// Returns true if child is contained within element +Element.isParent = function(child, element) { + if (!child.parentNode || child == element) return false; + if (child.parentNode == element) return true; + return Element.isParent(child.parentNode, element); +} + +Element.findChildren = function(element, only, recursive, tagName) { + if(!element.hasChildNodes()) return null; + tagName = tagName.toUpperCase(); + if(only) only = [only].flatten(); + var elements = []; + $A(element.childNodes).each( function(e) { + if(e.tagName && e.tagName.toUpperCase()==tagName && + (!only || (Element.classNames(e).detect(function(v) { return only.include(v) })))) + elements.push(e); + if(recursive) { + var grandchildren = Element.findChildren(e, only, recursive, tagName); + if(grandchildren) elements.push(grandchildren); + } + }); + + return (elements.length>0 ? elements.flatten() : []); +} + +Element.offsetSize = function (element, type) { + return element['offset' + ((type=='vertical' || type=='height') ? 'Height' : 'Width')]; +} diff -Nur mephisto-0.7.3/vendor/plugins/rspec/story_server/prototype/javascripts/effects.js technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/story_server/prototype/javascripts/effects.js --- mephisto-0.7.3/vendor/plugins/rspec/story_server/prototype/javascripts/effects.js 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/story_server/prototype/javascripts/effects.js 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,1117 @@ +// script.aculo.us effects.js v1.8.0_pre1, Fri Oct 12 21:34:51 +0200 2007 + +// Copyright (c) 2005-2007 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) +// Contributors: +// Justin Palmer (http://encytemedia.com/) +// Mark Pilgrim (http://diveintomark.org/) +// Martin Bialasinki +// +// script.aculo.us is freely distributable under the terms of an MIT-style license. +// For details, see the script.aculo.us web site: http://script.aculo.us/ + +// converts rgb() and #xxx to #xxxxxx format, +// returns self (or first argument) if not convertable +String.prototype.parseColor = function() { + var color = '#'; + if (this.slice(0,4) == 'rgb(') { + var cols = this.slice(4,this.length-1).split(','); + var i=0; do { color += parseInt(cols[i]).toColorPart() } while (++i<3); + } else { + if (this.slice(0,1) == '#') { + if (this.length==4) for(var i=1;i<4;i++) color += (this.charAt(i) + this.charAt(i)).toLowerCase(); + if (this.length==7) color = this.toLowerCase(); + } + } + return (color.length==7 ? color : (arguments[0] || this)); +}; + +/*--------------------------------------------------------------------------*/ + +Element.collectTextNodes = function(element) { + return $A($(element).childNodes).collect( function(node) { + return (node.nodeType==3 ? node.nodeValue : + (node.hasChildNodes() ? Element.collectTextNodes(node) : '')); + }).flatten().join(''); +}; + +Element.collectTextNodesIgnoreClass = function(element, className) { + return $A($(element).childNodes).collect( function(node) { + return (node.nodeType==3 ? node.nodeValue : + ((node.hasChildNodes() && !Element.hasClassName(node,className)) ? + Element.collectTextNodesIgnoreClass(node, className) : '')); + }).flatten().join(''); +}; + +Element.setContentZoom = function(element, percent) { + element = $(element); + element.setStyle({fontSize: (percent/100) + 'em'}); + if (Prototype.Browser.WebKit) window.scrollBy(0,0); + return element; +}; + +Element.getInlineOpacity = function(element){ + return $(element).style.opacity || ''; +}; + +Element.forceRerendering = function(element) { + try { + element = $(element); + var n = document.createTextNode(' '); + element.appendChild(n); + element.removeChild(n); + } catch(e) { } +}; + +/*--------------------------------------------------------------------------*/ + +var Effect = { + _elementDoesNotExistError: { + name: 'ElementDoesNotExistError', + message: 'The specified DOM element does not exist, but is required for this effect to operate' + }, + Transitions: { + linear: Prototype.K, + sinoidal: function(pos) { + return (-Math.cos(pos*Math.PI)/2) + 0.5; + }, + reverse: function(pos) { + return 1-pos; + }, + flicker: function(pos) { + var pos = ((-Math.cos(pos*Math.PI)/4) + 0.75) + Math.random()/4; + return pos > 1 ? 1 : pos; + }, + wobble: function(pos) { + return (-Math.cos(pos*Math.PI*(9*pos))/2) + 0.5; + }, + pulse: function(pos, pulses) { + pulses = pulses || 5; + return ( + ((pos % (1/pulses)) * pulses).round() == 0 ? + ((pos * pulses * 2) - (pos * pulses * 2).floor()) : + 1 - ((pos * pulses * 2) - (pos * pulses * 2).floor()) + ); + }, + spring: function(pos) { + return 1 - (Math.cos(pos * 4.5 * Math.PI) * Math.exp(-pos * 6)); + }, + none: function(pos) { + return 0; + }, + full: function(pos) { + return 1; + } + }, + DefaultOptions: { + duration: 1.0, // seconds + fps: 100, // 100= assume 66fps max. + sync: false, // true for combining + from: 0.0, + to: 1.0, + delay: 0.0, + queue: 'parallel' + }, + tagifyText: function(element) { + var tagifyStyle = 'position:relative'; + if (Prototype.Browser.IE) tagifyStyle += ';zoom:1'; + + element = $(element); + $A(element.childNodes).each( function(child) { + if (child.nodeType==3) { + child.nodeValue.toArray().each( function(character) { + element.insertBefore( + new Element('span', {style: tagifyStyle}).update( + character == ' ' ? String.fromCharCode(160) : character), + child); + }); + Element.remove(child); + } + }); + }, + multiple: function(element, effect) { + var elements; + if (((typeof element == 'object') || + Object.isFunction(element)) && + (element.length)) + elements = element; + else + elements = $(element).childNodes; + + var options = Object.extend({ + speed: 0.1, + delay: 0.0 + }, arguments[2] || { }); + var masterDelay = options.delay; + + $A(elements).each( function(element, index) { + new effect(element, Object.extend(options, { delay: index * options.speed + masterDelay })); + }); + }, + PAIRS: { + 'slide': ['SlideDown','SlideUp'], + 'blind': ['BlindDown','BlindUp'], + 'appear': ['Appear','Fade'] + }, + toggle: function(element, effect) { + element = $(element); + effect = (effect || 'appear').toLowerCase(); + var options = Object.extend({ + queue: { position:'end', scope:(element.id || 'global'), limit: 1 } + }, arguments[2] || { }); + Effect[element.visible() ? + Effect.PAIRS[effect][1] : Effect.PAIRS[effect][0]](element, options); + } +}; + +Effect.DefaultOptions.transition = Effect.Transitions.sinoidal; + +/* ------------- core effects ------------- */ + +Effect.ScopedQueue = Class.create(Enumerable, { + initialize: function() { + this.effects = []; + this.interval = null; + }, + _each: function(iterator) { + this.effects._each(iterator); + }, + add: function(effect) { + var timestamp = new Date().getTime(); + + var position = Object.isString(effect.options.queue) ? + effect.options.queue : effect.options.queue.position; + + switch(position) { + case 'front': + // move unstarted effects after this effect + this.effects.findAll(function(e){ return e.state=='idle' }).each( function(e) { + e.startOn += effect.finishOn; + e.finishOn += effect.finishOn; + }); + break; + case 'with-last': + timestamp = this.effects.pluck('startOn').max() || timestamp; + break; + case 'end': + // start effect after last queued effect has finished + timestamp = this.effects.pluck('finishOn').max() || timestamp; + break; + } + + effect.startOn += timestamp; + effect.finishOn += timestamp; + + if (!effect.options.queue.limit || (this.effects.length < effect.options.queue.limit)) + this.effects.push(effect); + + if (!this.interval) + this.interval = setInterval(this.loop.bind(this), 15); + }, + remove: function(effect) { + this.effects = this.effects.reject(function(e) { return e==effect }); + if (this.effects.length == 0) { + clearInterval(this.interval); + this.interval = null; + } + }, + loop: function() { + var timePos = new Date().getTime(); + for(var i=0, len=this.effects.length;i= this.startOn) { + if (timePos >= this.finishOn) { + this.render(1.0); + this.cancel(); + this.event('beforeFinish'); + if (this.finish) this.finish(); + this.event('afterFinish'); + return; + } + var pos = (timePos - this.startOn) / this.totalTime, + frame = (pos * this.totalFrames).round(); + if (frame > this.currentFrame) { + this.render(pos); + this.currentFrame = frame; + } + } + }, + cancel: function() { + if (!this.options.sync) + Effect.Queues.get(Object.isString(this.options.queue) ? + 'global' : this.options.queue.scope).remove(this); + this.state = 'finished'; + }, + event: function(eventName) { + if (this.options[eventName + 'Internal']) this.options[eventName + 'Internal'](this); + if (this.options[eventName]) this.options[eventName](this); + }, + inspect: function() { + var data = $H(); + for(property in this) + if (!Object.isFunction(this[property])) data[property] = this[property]; + return '#'; + } +}; + +Effect.Parallel = Class.create(Effect.Base, { + initialize: function(effects) { + this.effects = effects || []; + this.start(arguments[1]); + }, + update: function(position) { + this.effects.invoke('render', position); + }, + finish: function(position) { + this.effects.each( function(effect) { + effect.render(1.0); + effect.cancel(); + effect.event('beforeFinish'); + if (effect.finish) effect.finish(position); + effect.event('afterFinish'); + }); + } +}); + +Effect.Tween = Class.create(Effect.Base, { + initialize: function(object, from, to) { + object = Object.isString(object) ? $(object) : object; + var args = $A(arguments), method = args.last(), + options = args.length == 5 ? args[3] : null; + this.method = Object.isFunction(method) ? method.bind(object) : + Object.isFunction(object[method]) ? object[method].bind(object) : + function(value) { object[method] = value }; + this.start(Object.extend({ from: from, to: to }, options || { })); + }, + update: function(position) { + this.method(position); + } +}); + +Effect.Event = Class.create(Effect.Base, { + initialize: function() { + this.start(Object.extend({ duration: 0 }, arguments[0] || { })); + }, + update: Prototype.emptyFunction +}); + +Effect.Opacity = Class.create(Effect.Base, { + initialize: function(element) { + this.element = $(element); + if (!this.element) throw(Effect._elementDoesNotExistError); + // make this work on IE on elements without 'layout' + if (Prototype.Browser.IE && (!this.element.currentStyle.hasLayout)) + this.element.setStyle({zoom: 1}); + var options = Object.extend({ + from: this.element.getOpacity() || 0.0, + to: 1.0 + }, arguments[1] || { }); + this.start(options); + }, + update: function(position) { + this.element.setOpacity(position); + } +}); + +Effect.Move = Class.create(Effect.Base, { + initialize: function(element) { + this.element = $(element); + if (!this.element) throw(Effect._elementDoesNotExistError); + var options = Object.extend({ + x: 0, + y: 0, + mode: 'relative' + }, arguments[1] || { }); + this.start(options); + }, + setup: function() { + this.element.makePositioned(); + this.originalLeft = parseFloat(this.element.getStyle('left') || '0'); + this.originalTop = parseFloat(this.element.getStyle('top') || '0'); + if (this.options.mode == 'absolute') { + this.options.x = this.options.x - this.originalLeft; + this.options.y = this.options.y - this.originalTop; + } + }, + update: function(position) { + this.element.setStyle({ + left: (this.options.x * position + this.originalLeft).round() + 'px', + top: (this.options.y * position + this.originalTop).round() + 'px' + }); + } +}); + +// for backwards compatibility +Effect.MoveBy = function(element, toTop, toLeft) { + return new Effect.Move(element, + Object.extend({ x: toLeft, y: toTop }, arguments[3] || { })); +}; + +Effect.Scale = Class.create(Effect.Base, { + initialize: function(element, percent) { + this.element = $(element); + if (!this.element) throw(Effect._elementDoesNotExistError); + var options = Object.extend({ + scaleX: true, + scaleY: true, + scaleContent: true, + scaleFromCenter: false, + scaleMode: 'box', // 'box' or 'contents' or { } with provided values + scaleFrom: 100.0, + scaleTo: percent + }, arguments[2] || { }); + this.start(options); + }, + setup: function() { + this.restoreAfterFinish = this.options.restoreAfterFinish || false; + this.elementPositioning = this.element.getStyle('position'); + + this.originalStyle = { }; + ['top','left','width','height','fontSize'].each( function(k) { + this.originalStyle[k] = this.element.style[k]; + }.bind(this)); + + this.originalTop = this.element.offsetTop; + this.originalLeft = this.element.offsetLeft; + + var fontSize = this.element.getStyle('font-size') || '100%'; + ['em','px','%','pt'].each( function(fontSizeType) { + if (fontSize.indexOf(fontSizeType)>0) { + this.fontSize = parseFloat(fontSize); + this.fontSizeType = fontSizeType; + } + }.bind(this)); + + this.factor = (this.options.scaleTo - this.options.scaleFrom)/100; + + this.dims = null; + if (this.options.scaleMode=='box') + this.dims = [this.element.offsetHeight, this.element.offsetWidth]; + if (/^content/.test(this.options.scaleMode)) + this.dims = [this.element.scrollHeight, this.element.scrollWidth]; + if (!this.dims) + this.dims = [this.options.scaleMode.originalHeight, + this.options.scaleMode.originalWidth]; + }, + update: function(position) { + var currentScale = (this.options.scaleFrom/100.0) + (this.factor * position); + if (this.options.scaleContent && this.fontSize) + this.element.setStyle({fontSize: this.fontSize * currentScale + this.fontSizeType }); + this.setDimensions(this.dims[0] * currentScale, this.dims[1] * currentScale); + }, + finish: function(position) { + if (this.restoreAfterFinish) this.element.setStyle(this.originalStyle); + }, + setDimensions: function(height, width) { + var d = { }; + if (this.options.scaleX) d.width = width.round() + 'px'; + if (this.options.scaleY) d.height = height.round() + 'px'; + if (this.options.scaleFromCenter) { + var topd = (height - this.dims[0])/2; + var leftd = (width - this.dims[1])/2; + if (this.elementPositioning == 'absolute') { + if (this.options.scaleY) d.top = this.originalTop-topd + 'px'; + if (this.options.scaleX) d.left = this.originalLeft-leftd + 'px'; + } else { + if (this.options.scaleY) d.top = -topd + 'px'; + if (this.options.scaleX) d.left = -leftd + 'px'; + } + } + this.element.setStyle(d); + } +}); + +Effect.Highlight = Class.create(Effect.Base, { + initialize: function(element) { + this.element = $(element); + if (!this.element) throw(Effect._elementDoesNotExistError); + var options = Object.extend({ startcolor: '#ffff99' }, arguments[1] || { }); + this.start(options); + }, + setup: function() { + // Prevent executing on elements not in the layout flow + if (this.element.getStyle('display')=='none') { this.cancel(); return; } + // Disable background image during the effect + this.oldStyle = { }; + if (!this.options.keepBackgroundImage) { + this.oldStyle.backgroundImage = this.element.getStyle('background-image'); + this.element.setStyle({backgroundImage: 'none'}); + } + if (!this.options.endcolor) + this.options.endcolor = this.element.getStyle('background-color').parseColor('#ffffff'); + if (!this.options.restorecolor) + this.options.restorecolor = this.element.getStyle('background-color'); + // init color calculations + this._base = $R(0,2).map(function(i){ return parseInt(this.options.startcolor.slice(i*2+1,i*2+3),16) }.bind(this)); + this._delta = $R(0,2).map(function(i){ return parseInt(this.options.endcolor.slice(i*2+1,i*2+3),16)-this._base[i] }.bind(this)); + }, + update: function(position) { + this.element.setStyle({backgroundColor: $R(0,2).inject('#',function(m,v,i){ + return m+((this._base[i]+(this._delta[i]*position)).round().toColorPart()); }.bind(this)) }); + }, + finish: function() { + this.element.setStyle(Object.extend(this.oldStyle, { + backgroundColor: this.options.restorecolor + })); + } +}); + +Effect.ScrollTo = function(element) { + var options = arguments[1] || { }, + scrollOffsets = document.viewport.getScrollOffsets(), + elementOffsets = $(element).cumulativeOffset(), + max = (window.height || document.body.scrollHeight) - document.viewport.getHeight(); + + if (options.offset) elementOffsets[1] += options.offset; + + return new Effect.Tween(null, + scrollOffsets.top, + elementOffsets[1] > max ? max : elementOffsets[1], + options, + function(p){ scrollTo(scrollOffsets.left, p.round()) } + ); +}; + +/* ------------- combination effects ------------- */ + +Effect.Fade = function(element) { + element = $(element); + var oldOpacity = element.getInlineOpacity(); + var options = Object.extend({ + from: element.getOpacity() || 1.0, + to: 0.0, + afterFinishInternal: function(effect) { + if (effect.options.to!=0) return; + effect.element.hide().setStyle({opacity: oldOpacity}); + } + }, arguments[1] || { }); + return new Effect.Opacity(element,options); +}; + +Effect.Appear = function(element) { + element = $(element); + var options = Object.extend({ + from: (element.getStyle('display') == 'none' ? 0.0 : element.getOpacity() || 0.0), + to: 1.0, + // force Safari to render floated elements properly + afterFinishInternal: function(effect) { + effect.element.forceRerendering(); + }, + beforeSetup: function(effect) { + effect.element.setOpacity(effect.options.from).show(); + }}, arguments[1] || { }); + return new Effect.Opacity(element,options); +}; + +Effect.Puff = function(element) { + element = $(element); + var oldStyle = { + opacity: element.getInlineOpacity(), + position: element.getStyle('position'), + top: element.style.top, + left: element.style.left, + width: element.style.width, + height: element.style.height + }; + return new Effect.Parallel( + [ new Effect.Scale(element, 200, + { sync: true, scaleFromCenter: true, scaleContent: true, restoreAfterFinish: true }), + new Effect.Opacity(element, { sync: true, to: 0.0 } ) ], + Object.extend({ duration: 1.0, + beforeSetupInternal: function(effect) { + Position.absolutize(effect.effects[0].element) + }, + afterFinishInternal: function(effect) { + effect.effects[0].element.hide().setStyle(oldStyle); } + }, arguments[1] || { }) + ); +}; + +Effect.BlindUp = function(element) { + element = $(element); + element.makeClipping(); + return new Effect.Scale(element, 0, + Object.extend({ scaleContent: false, + scaleX: false, + restoreAfterFinish: true, + afterFinishInternal: function(effect) { + effect.element.hide().undoClipping(); + } + }, arguments[1] || { }) + ); +}; + +Effect.BlindDown = function(element) { + element = $(element); + var elementDimensions = element.getDimensions(); + return new Effect.Scale(element, 100, Object.extend({ + scaleContent: false, + scaleX: false, + scaleFrom: 0, + scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width}, + restoreAfterFinish: true, + afterSetup: function(effect) { + effect.element.makeClipping().setStyle({height: '0px'}).show(); + }, + afterFinishInternal: function(effect) { + effect.element.undoClipping(); + } + }, arguments[1] || { })); +}; + +Effect.SwitchOff = function(element) { + element = $(element); + var oldOpacity = element.getInlineOpacity(); + return new Effect.Appear(element, Object.extend({ + duration: 0.4, + from: 0, + transition: Effect.Transitions.flicker, + afterFinishInternal: function(effect) { + new Effect.Scale(effect.element, 1, { + duration: 0.3, scaleFromCenter: true, + scaleX: false, scaleContent: false, restoreAfterFinish: true, + beforeSetup: function(effect) { + effect.element.makePositioned().makeClipping(); + }, + afterFinishInternal: function(effect) { + effect.element.hide().undoClipping().undoPositioned().setStyle({opacity: oldOpacity}); + } + }) + } + }, arguments[1] || { })); +}; + +Effect.DropOut = function(element) { + element = $(element); + var oldStyle = { + top: element.getStyle('top'), + left: element.getStyle('left'), + opacity: element.getInlineOpacity() }; + return new Effect.Parallel( + [ new Effect.Move(element, {x: 0, y: 100, sync: true }), + new Effect.Opacity(element, { sync: true, to: 0.0 }) ], + Object.extend( + { duration: 0.5, + beforeSetup: function(effect) { + effect.effects[0].element.makePositioned(); + }, + afterFinishInternal: function(effect) { + effect.effects[0].element.hide().undoPositioned().setStyle(oldStyle); + } + }, arguments[1] || { })); +}; + +Effect.Shake = function(element) { + element = $(element); + var oldStyle = { + top: element.getStyle('top'), + left: element.getStyle('left') }; + return new Effect.Move(element, + { x: 20, y: 0, duration: 0.05, afterFinishInternal: function(effect) { + new Effect.Move(effect.element, + { x: -40, y: 0, duration: 0.1, afterFinishInternal: function(effect) { + new Effect.Move(effect.element, + { x: 40, y: 0, duration: 0.1, afterFinishInternal: function(effect) { + new Effect.Move(effect.element, + { x: -40, y: 0, duration: 0.1, afterFinishInternal: function(effect) { + new Effect.Move(effect.element, + { x: 40, y: 0, duration: 0.1, afterFinishInternal: function(effect) { + new Effect.Move(effect.element, + { x: -20, y: 0, duration: 0.05, afterFinishInternal: function(effect) { + effect.element.undoPositioned().setStyle(oldStyle); + }}) }}) }}) }}) }}) }}); +}; + +Effect.SlideDown = function(element) { + element = $(element).cleanWhitespace(); + // SlideDown need to have the content of the element wrapped in a container element with fixed height! + var oldInnerBottom = element.down().getStyle('bottom'); + var elementDimensions = element.getDimensions(); + return new Effect.Scale(element, 100, Object.extend({ + scaleContent: false, + scaleX: false, + scaleFrom: window.opera ? 0 : 1, + scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width}, + restoreAfterFinish: true, + afterSetup: function(effect) { + effect.element.makePositioned(); + effect.element.down().makePositioned(); + if (window.opera) effect.element.setStyle({top: ''}); + effect.element.makeClipping().setStyle({height: '0px'}).show(); + }, + afterUpdateInternal: function(effect) { + effect.element.down().setStyle({bottom: + (effect.dims[0] - effect.element.clientHeight) + 'px' }); + }, + afterFinishInternal: function(effect) { + effect.element.undoClipping().undoPositioned(); + effect.element.down().undoPositioned().setStyle({bottom: oldInnerBottom}); } + }, arguments[1] || { }) + ); +}; + +Effect.SlideUp = function(element) { + element = $(element).cleanWhitespace(); + var oldInnerBottom = element.down().getStyle('bottom'); + var elementDimensions = element.getDimensions(); + return new Effect.Scale(element, window.opera ? 0 : 1, + Object.extend({ scaleContent: false, + scaleX: false, + scaleMode: 'box', + scaleFrom: 100, + scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width}, + restoreAfterFinish: true, + afterSetup: function(effect) { + effect.element.makePositioned(); + effect.element.down().makePositioned(); + if (window.opera) effect.element.setStyle({top: ''}); + effect.element.makeClipping().show(); + }, + afterUpdateInternal: function(effect) { + effect.element.down().setStyle({bottom: + (effect.dims[0] - effect.element.clientHeight) + 'px' }); + }, + afterFinishInternal: function(effect) { + effect.element.hide().undoClipping().undoPositioned(); + effect.element.down().undoPositioned().setStyle({bottom: oldInnerBottom}); + } + }, arguments[1] || { }) + ); +}; + +// Bug in opera makes the TD containing this element expand for a instance after finish +Effect.Squish = function(element) { + return new Effect.Scale(element, window.opera ? 1 : 0, { + restoreAfterFinish: true, + beforeSetup: function(effect) { + effect.element.makeClipping(); + }, + afterFinishInternal: function(effect) { + effect.element.hide().undoClipping(); + } + }); +}; + +Effect.Grow = function(element) { + element = $(element); + var options = Object.extend({ + direction: 'center', + moveTransition: Effect.Transitions.sinoidal, + scaleTransition: Effect.Transitions.sinoidal, + opacityTransition: Effect.Transitions.full + }, arguments[1] || { }); + var oldStyle = { + top: element.style.top, + left: element.style.left, + height: element.style.height, + width: element.style.width, + opacity: element.getInlineOpacity() }; + + var dims = element.getDimensions(); + var initialMoveX, initialMoveY; + var moveX, moveY; + + switch (options.direction) { + case 'top-left': + initialMoveX = initialMoveY = moveX = moveY = 0; + break; + case 'top-right': + initialMoveX = dims.width; + initialMoveY = moveY = 0; + moveX = -dims.width; + break; + case 'bottom-left': + initialMoveX = moveX = 0; + initialMoveY = dims.height; + moveY = -dims.height; + break; + case 'bottom-right': + initialMoveX = dims.width; + initialMoveY = dims.height; + moveX = -dims.width; + moveY = -dims.height; + break; + case 'center': + initialMoveX = dims.width / 2; + initialMoveY = dims.height / 2; + moveX = -dims.width / 2; + moveY = -dims.height / 2; + break; + } + + return new Effect.Move(element, { + x: initialMoveX, + y: initialMoveY, + duration: 0.01, + beforeSetup: function(effect) { + effect.element.hide().makeClipping().makePositioned(); + }, + afterFinishInternal: function(effect) { + new Effect.Parallel( + [ new Effect.Opacity(effect.element, { sync: true, to: 1.0, from: 0.0, transition: options.opacityTransition }), + new Effect.Move(effect.element, { x: moveX, y: moveY, sync: true, transition: options.moveTransition }), + new Effect.Scale(effect.element, 100, { + scaleMode: { originalHeight: dims.height, originalWidth: dims.width }, + sync: true, scaleFrom: window.opera ? 1 : 0, transition: options.scaleTransition, restoreAfterFinish: true}) + ], Object.extend({ + beforeSetup: function(effect) { + effect.effects[0].element.setStyle({height: '0px'}).show(); + }, + afterFinishInternal: function(effect) { + effect.effects[0].element.undoClipping().undoPositioned().setStyle(oldStyle); + } + }, options) + ) + } + }); +}; + +Effect.Shrink = function(element) { + element = $(element); + var options = Object.extend({ + direction: 'center', + moveTransition: Effect.Transitions.sinoidal, + scaleTransition: Effect.Transitions.sinoidal, + opacityTransition: Effect.Transitions.none + }, arguments[1] || { }); + var oldStyle = { + top: element.style.top, + left: element.style.left, + height: element.style.height, + width: element.style.width, + opacity: element.getInlineOpacity() }; + + var dims = element.getDimensions(); + var moveX, moveY; + + switch (options.direction) { + case 'top-left': + moveX = moveY = 0; + break; + case 'top-right': + moveX = dims.width; + moveY = 0; + break; + case 'bottom-left': + moveX = 0; + moveY = dims.height; + break; + case 'bottom-right': + moveX = dims.width; + moveY = dims.height; + break; + case 'center': + moveX = dims.width / 2; + moveY = dims.height / 2; + break; + } + + return new Effect.Parallel( + [ new Effect.Opacity(element, { sync: true, to: 0.0, from: 1.0, transition: options.opacityTransition }), + new Effect.Scale(element, window.opera ? 1 : 0, { sync: true, transition: options.scaleTransition, restoreAfterFinish: true}), + new Effect.Move(element, { x: moveX, y: moveY, sync: true, transition: options.moveTransition }) + ], Object.extend({ + beforeStartInternal: function(effect) { + effect.effects[0].element.makePositioned().makeClipping(); + }, + afterFinishInternal: function(effect) { + effect.effects[0].element.hide().undoClipping().undoPositioned().setStyle(oldStyle); } + }, options) + ); +}; + +Effect.Pulsate = function(element) { + element = $(element); + var options = arguments[1] || { }; + var oldOpacity = element.getInlineOpacity(); + var transition = options.transition || Effect.Transitions.sinoidal; + var reverser = function(pos){ return transition(1-Effect.Transitions.pulse(pos, options.pulses)) }; + reverser.bind(transition); + return new Effect.Opacity(element, + Object.extend(Object.extend({ duration: 2.0, from: 0, + afterFinishInternal: function(effect) { effect.element.setStyle({opacity: oldOpacity}); } + }, options), {transition: reverser})); +}; + +Effect.Fold = function(element) { + element = $(element); + var oldStyle = { + top: element.style.top, + left: element.style.left, + width: element.style.width, + height: element.style.height }; + element.makeClipping(); + return new Effect.Scale(element, 5, Object.extend({ + scaleContent: false, + scaleX: false, + afterFinishInternal: function(effect) { + new Effect.Scale(element, 1, { + scaleContent: false, + scaleY: false, + afterFinishInternal: function(effect) { + effect.element.hide().undoClipping().setStyle(oldStyle); + } }); + }}, arguments[1] || { })); +}; + +Effect.Morph = Class.create(Effect.Base, { + initialize: function(element) { + this.element = $(element); + if (!this.element) throw(Effect._elementDoesNotExistError); + var options = Object.extend({ + style: { } + }, arguments[1] || { }); + + if (!Object.isString(options.style)) this.style = $H(options.style); + else { + if (options.style.include(':')) + this.style = options.style.parseStyle(); + else { + this.element.addClassName(options.style); + this.style = $H(this.element.getStyles()); + this.element.removeClassName(options.style); + var css = this.element.getStyles(); + this.style = this.style.reject(function(style) { + return style.value == css[style.key]; + }); + options.afterFinishInternal = function(effect) { + effect.element.addClassName(effect.options.style); + effect.transforms.each(function(transform) { + effect.element.style[transform.style] = ''; + }); + } + } + } + this.start(options); + }, + + setup: function(){ + function parseColor(color){ + if (!color || ['rgba(0, 0, 0, 0)','transparent'].include(color)) color = '#ffffff'; + color = color.parseColor(); + return $R(0,2).map(function(i){ + return parseInt( color.slice(i*2+1,i*2+3), 16 ) + }); + } + this.transforms = this.style.map(function(pair){ + var property = pair[0], value = pair[1], unit = null; + + if (value.parseColor('#zzzzzz') != '#zzzzzz') { + value = value.parseColor(); + unit = 'color'; + } else if (property == 'opacity') { + value = parseFloat(value); + if (Prototype.Browser.IE && (!this.element.currentStyle.hasLayout)) + this.element.setStyle({zoom: 1}); + } else if (Element.CSS_LENGTH.test(value)) { + var components = value.match(/^([\+\-]?[0-9\.]+)(.*)$/); + value = parseFloat(components[1]); + unit = (components.length == 3) ? components[2] : null; + } + + var originalValue = this.element.getStyle(property); + return { + style: property.camelize(), + originalValue: unit=='color' ? parseColor(originalValue) : parseFloat(originalValue || 0), + targetValue: unit=='color' ? parseColor(value) : value, + unit: unit + }; + }.bind(this)).reject(function(transform){ + return ( + (transform.originalValue == transform.targetValue) || + ( + transform.unit != 'color' && + (isNaN(transform.originalValue) || isNaN(transform.targetValue)) + ) + ) + }); + }, + update: function(position) { + var style = { }, transform, i = this.transforms.length; + while(i--) + style[(transform = this.transforms[i]).style] = + transform.unit=='color' ? '#'+ + (Math.round(transform.originalValue[0]+ + (transform.targetValue[0]-transform.originalValue[0])*position)).toColorPart() + + (Math.round(transform.originalValue[1]+ + (transform.targetValue[1]-transform.originalValue[1])*position)).toColorPart() + + (Math.round(transform.originalValue[2]+ + (transform.targetValue[2]-transform.originalValue[2])*position)).toColorPart() : + (transform.originalValue + + (transform.targetValue - transform.originalValue) * position).toFixed(3) + + (transform.unit === null ? '' : transform.unit); + this.element.setStyle(style, true); + } +}); + +Effect.Transform = Class.create({ + initialize: function(tracks){ + this.tracks = []; + this.options = arguments[1] || { }; + this.addTracks(tracks); + }, + addTracks: function(tracks){ + tracks.each(function(track){ + var data = $H(track).values().first(); + this.tracks.push($H({ + ids: $H(track).keys().first(), + effect: Effect.Morph, + options: { style: data } + })); + }.bind(this)); + return this; + }, + play: function(){ + return new Effect.Parallel( + this.tracks.map(function(track){ + var elements = [$(track.ids) || $$(track.ids)].flatten(); + return elements.map(function(e){ return new track.effect(e, Object.extend({ sync:true }, track.options)) }); + }).flatten(), + this.options + ); + } +}); + +Element.CSS_PROPERTIES = $w( + 'backgroundColor backgroundPosition borderBottomColor borderBottomStyle ' + + 'borderBottomWidth borderLeftColor borderLeftStyle borderLeftWidth ' + + 'borderRightColor borderRightStyle borderRightWidth borderSpacing ' + + 'borderTopColor borderTopStyle borderTopWidth bottom clip color ' + + 'fontSize fontWeight height left letterSpacing lineHeight ' + + 'marginBottom marginLeft marginRight marginTop markerOffset maxHeight '+ + 'maxWidth minHeight minWidth opacity outlineColor outlineOffset ' + + 'outlineWidth paddingBottom paddingLeft paddingRight paddingTop ' + + 'right textIndent top width wordSpacing zIndex'); + +Element.CSS_LENGTH = /^(([\+\-]?[0-9\.]+)(em|ex|px|in|cm|mm|pt|pc|\%))|0$/; + +String.__parseStyleElement = document.createElement('div'); +String.prototype.parseStyle = function(){ + var style, styleRules = $H(); + if (Prototype.Browser.WebKit) + style = new Element('div',{style:this}).style; + else { + String.__parseStyleElement.innerHTML = '
      '; + style = String.__parseStyleElement.childNodes[0].style; + } + + Element.CSS_PROPERTIES.each(function(property){ + if (style[property]) styleRules[property] = style[property]; + }); + + if (Prototype.Browser.IE && this.include('opacity')) + styleRules.opacity = this.match(/opacity:\s*((?:0|1)?(?:\.\d*)?)/)[1]; + + return styleRules; +}; + +if (document.defaultView && document.defaultView.getComputedStyle) { + Element.getStyles = function(element) { + var css = document.defaultView.getComputedStyle($(element), null); + return Element.CSS_PROPERTIES.inject({ }, function(styles, property) { + styles[property] = css[property]; + return styles; + }); + }; +} else { + Element.getStyles = function(element) { + element = $(element); + var css = element.currentStyle, styles; + styles = Element.CSS_PROPERTIES.inject({ }, function(hash, property) { + hash[property] = css[property]; + return hash; + }); + if (!styles.opacity) styles.opacity = element.getOpacity(); + return styles; + }; +}; + +Effect.Methods = { + morph: function(element, style) { + element = $(element); + new Effect.Morph(element, Object.extend({ style: style }, arguments[2] || { })); + return element; + }, + visualEffect: function(element, effect, options) { + element = $(element) + var s = effect.dasherize().camelize(), klass = s.charAt(0).toUpperCase() + s.substring(1); + new Effect[klass](element, options); + return element; + }, + highlight: function(element, options) { + element = $(element); + new Effect.Highlight(element, options); + return element; + } +}; + +$w('fade appear grow shrink fold blindUp blindDown slideUp slideDown '+ + 'pulsate shake puff squish switchOff dropOut').each( + function(effect) { + Effect.Methods[effect] = function(element, options){ + element = $(element); + Effect[effect.charAt(0).toUpperCase() + effect.substring(1)](element, options); + return element; + } + } +); + +$w('getInlineOpacity forceRerendering setContentZoom collectTextNodes collectTextNodesIgnoreClass getStyles').each( + function(f) { Effect.Methods[f] = Element[f]; } +); + +Element.addMethods(Effect.Methods); \ No newline at end of file diff -Nur mephisto-0.7.3/vendor/plugins/rspec/story_server/prototype/javascripts/prototype.js technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/story_server/prototype/javascripts/prototype.js --- mephisto-0.7.3/vendor/plugins/rspec/story_server/prototype/javascripts/prototype.js 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/story_server/prototype/javascripts/prototype.js 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,4140 @@ +/* Prototype JavaScript framework, version 1.6.0_rc0 + * (c) 2005-2007 Sam Stephenson + * + * Prototype is freely distributable under the terms of an MIT-style license. + * For details, see the Prototype web site: http://www.prototypejs.org/ + * + *--------------------------------------------------------------------------*/ + +var Prototype = { + Version: '1.6.0_rc0', + + Browser: { + IE: !!(window.attachEvent && !window.opera), + Opera: !!window.opera, + WebKit: navigator.userAgent.indexOf('AppleWebKit/') > -1, + Gecko: navigator.userAgent.indexOf('Gecko') > -1 && navigator.userAgent.indexOf('KHTML') == -1, + MobileSafari: !!navigator.userAgent.match(/Apple.*Mobile.*Safari/) + }, + + BrowserFeatures: { + XPath: !!document.evaluate, + ElementExtensions: !!window.HTMLElement, + SpecificElementExtensions: + document.createElement('div').__proto__ !== + document.createElement('form').__proto__ + }, + + ScriptFragment: ']*>([\\S\\s]*?)<\/script>', + JSONFilter: /^\/\*-secure-([\s\S]*)\*\/\s*$/, + + emptyFunction: function() { }, + K: function(x) { return x } +}; + +if (Prototype.Browser.MobileSafari) + Prototype.BrowserFeatures.SpecificElementExtensions = false; + +/* Based on Alex Arnell's inheritance implementation. */ +var Class = { + create: function() { + var parent = null, properties = $A(arguments); + if (Object.isFunction(properties[0])) + parent = properties.shift(); + + function klass() { + this.initialize.apply(this, arguments); + } + + Object.extend(klass, Class.Methods); + klass.superclass = parent; + klass.subclasses = []; + + if (parent) { + var subclass = function() { }; + subclass.prototype = parent.prototype; + klass.prototype = new subclass; + parent.subclasses.push(klass); + } + + for (var i = 0; i < properties.length; i++) + klass.addMethods(properties[i]); + + if (!klass.prototype.initialize) + klass.prototype.initialize = Prototype.emptyFunction; + + klass.prototype.constructor = klass; + + return klass; + } +}; + +Class.Methods = { + addMethods: function(source) { + var ancestor = this.superclass && this.superclass.prototype; + + for (var property in source) { + var value = source[property]; + if (ancestor && Object.isFunction(value) && + value.argumentNames().first() == "$super") { + var method = value, value = Object.extend((function(m) { + return function() { return ancestor[m].apply(this, arguments) }; + })(property).wrap(method), { + valueOf: function() { return method }, + toString: function() { return method.toString() } + }); + } + this.prototype[property] = value; + } + + return this; + } +}; + +var Abstract = { }; + +Object.extend = function(destination, source) { + for (var property in source) + destination[property] = source[property]; + return destination; +}; + +Object.extend(Object, { + inspect: function(object) { + try { + if (object === undefined) return 'undefined'; + if (object === null) return 'null'; + return object.inspect ? object.inspect() : object.toString(); + } catch (e) { + if (e instanceof RangeError) return '...'; + throw e; + } + }, + + toJSON: function(object) { + var type = typeof object; + switch (type) { + case 'undefined': + case 'function': + case 'unknown': return; + case 'boolean': return object.toString(); + } + + if (object === null) return 'null'; + if (object.toJSON) return object.toJSON(); + if (Object.isElement(object)) return; + + var results = []; + for (var property in object) { + var value = Object.toJSON(object[property]); + if (value !== undefined) + results.push(property.toJSON() + ': ' + value); + } + + return '{' + results.join(', ') + '}'; + }, + + toHTML: function(object) { + return object && object.toHTML ? object.toHTML() : String.interpret(object); + }, + + keys: function(object) { + var keys = []; + for (var property in object) + keys.push(property); + return keys; + }, + + values: function(object) { + var values = []; + for (var property in object) + values.push(object[property]); + return values; + }, + + clone: function(object) { + return Object.extend({ }, object); + }, + + isElement: function(object) { + return object && object.nodeType == 1; + }, + + isArray: function(object) { + return object && object.constructor === Array; + }, + + isFunction: function(object) { + return typeof object == "function"; + }, + + isString: function(object) { + return typeof object == "string"; + }, + + isNumber: function(object) { + return typeof object == "number"; + }, + + isUndefined: function(object) { + return typeof object == "undefined"; + } +}); + +Object.extend(Function.prototype, { + argumentNames: function() { + var names = this.toString().match(/^[\s\(]*function\s*\((.*?)\)/)[1].split(",").invoke("strip"); + return names.length == 1 && !names[0] ? [] : names; + }, + + bind: function() { + if (arguments.length < 2 && arguments[0] === undefined) return this; + var __method = this, args = $A(arguments), object = args.shift(); + return function() { + return __method.apply(object, args.concat($A(arguments))); + } + }, + + bindAsEventListener: function() { + var __method = this, args = $A(arguments), object = args.shift(); + return function(event) { + return __method.apply(object, [event || window.event].concat(args)); + } + }, + + curry: function() { + if (!arguments.length) return this; + var __method = this, args = $A(arguments); + return function() { + return __method.apply(this, args.concat($A(arguments))); + } + }, + + delay: function() { + var __method = this, args = $A(arguments), timeout = args.shift() * 1000; + return window.setTimeout(function() { + return __method.apply(__method, args); + }, timeout); + }, + + wrap: function(wrapper) { + var __method = this; + return function() { + return wrapper.apply(this, [__method.bind(this)].concat($A(arguments))); + } + }, + + methodize: function() { + if (this._methodized) return this._methodized; + var __method = this; + return this._methodized = function() { + return __method.apply(null, [this].concat($A(arguments))); + }; + } +}); + +Function.prototype.defer = Function.prototype.delay.curry(0.01); + +Date.prototype.toJSON = function() { + return '"' + this.getUTCFullYear() + '-' + + (this.getUTCMonth() + 1).toPaddedString(2) + '-' + + this.getUTCDate().toPaddedString(2) + 'T' + + this.getUTCHours().toPaddedString(2) + ':' + + this.getUTCMinutes().toPaddedString(2) + ':' + + this.getUTCSeconds().toPaddedString(2) + 'Z"'; +}; + +var Try = { + these: function() { + var returnValue; + + for (var i = 0, length = arguments.length; i < length; i++) { + var lambda = arguments[i]; + try { + returnValue = lambda(); + break; + } catch (e) { } + } + + return returnValue; + } +}; + +RegExp.prototype.match = RegExp.prototype.test; + +RegExp.escape = function(str) { + return String(str).replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1'); +}; + +/*--------------------------------------------------------------------------*/ + +var PeriodicalExecuter = Class.create({ + initialize: function(callback, frequency) { + this.callback = callback; + this.frequency = frequency; + this.currentlyExecuting = false; + + this.registerCallback(); + }, + + registerCallback: function() { + this.timer = setInterval(this.onTimerEvent.bind(this), this.frequency * 1000); + }, + + execute: function() { + this.callback(this); + }, + + stop: function() { + if (!this.timer) return; + clearInterval(this.timer); + this.timer = null; + }, + + onTimerEvent: function() { + if (!this.currentlyExecuting) { + try { + this.currentlyExecuting = true; + this.execute(); + } finally { + this.currentlyExecuting = false; + } + } + } +}); +Object.extend(String, { + interpret: function(value) { + return value == null ? '' : String(value); + }, + specialChar: { + '\b': '\\b', + '\t': '\\t', + '\n': '\\n', + '\f': '\\f', + '\r': '\\r', + '\\': '\\\\' + } +}); + +Object.extend(String.prototype, { + gsub: function(pattern, replacement) { + var result = '', source = this, match; + replacement = arguments.callee.prepareReplacement(replacement); + + while (source.length > 0) { + if (match = source.match(pattern)) { + result += source.slice(0, match.index); + result += String.interpret(replacement(match)); + source = source.slice(match.index + match[0].length); + } else { + result += source, source = ''; + } + } + return result; + }, + + sub: function(pattern, replacement, count) { + replacement = this.gsub.prepareReplacement(replacement); + count = count === undefined ? 1 : count; + + return this.gsub(pattern, function(match) { + if (--count < 0) return match[0]; + return replacement(match); + }); + }, + + scan: function(pattern, iterator) { + this.gsub(pattern, iterator); + return String(this); + }, + + truncate: function(length, truncation) { + length = length || 30; + truncation = truncation === undefined ? '...' : truncation; + return this.length > length ? + this.slice(0, length - truncation.length) + truncation : String(this); + }, + + strip: function() { + return this.replace(/^\s+/, '').replace(/\s+$/, ''); + }, + + stripTags: function() { + return this.replace(/<\/?[^>]+>/gi, ''); + }, + + stripScripts: function() { + return this.replace(new RegExp(Prototype.ScriptFragment, 'img'), ''); + }, + + extractScripts: function() { + var matchAll = new RegExp(Prototype.ScriptFragment, 'img'); + var matchOne = new RegExp(Prototype.ScriptFragment, 'im'); + return (this.match(matchAll) || []).map(function(scriptTag) { + return (scriptTag.match(matchOne) || ['', ''])[1]; + }); + }, + + evalScripts: function() { + return this.extractScripts().map(function(script) { return eval(script) }); + }, + + escapeHTML: function() { + var self = arguments.callee; + self.text.data = this; + return self.div.innerHTML; + }, + + unescapeHTML: function() { + var div = new Element('div'); + div.innerHTML = this.stripTags(); + return div.childNodes[0] ? (div.childNodes.length > 1 ? + $A(div.childNodes).inject('', function(memo, node) { return memo+node.nodeValue }) : + div.childNodes[0].nodeValue) : ''; + }, + + toQueryParams: function(separator) { + var match = this.strip().match(/([^?#]*)(#.*)?$/); + if (!match) return { }; + + return match[1].split(separator || '&').inject({ }, function(hash, pair) { + if ((pair = pair.split('='))[0]) { + var key = decodeURIComponent(pair.shift()); + var value = pair.length > 1 ? pair.join('=') : pair[0]; + if (value != undefined) value = decodeURIComponent(value); + + if (key in hash) { + if (!Object.isArray(hash[key])) hash[key] = [hash[key]]; + hash[key].push(value); + } + else hash[key] = value; + } + return hash; + }); + }, + + toArray: function() { + return this.split(''); + }, + + succ: function() { + return this.slice(0, this.length - 1) + + String.fromCharCode(this.charCodeAt(this.length - 1) + 1); + }, + + times: function(count) { + var result = ''; + for (var i = 0; i < count; i++) result += this; + return result; + }, + + camelize: function() { + var parts = this.split('-'), len = parts.length; + if (len == 1) return parts[0]; + + var camelized = this.charAt(0) == '-' + ? parts[0].charAt(0).toUpperCase() + parts[0].substring(1) + : parts[0]; + + for (var i = 1; i < len; i++) + camelized += parts[i].charAt(0).toUpperCase() + parts[i].substring(1); + + return camelized; + }, + + capitalize: function() { + return this.charAt(0).toUpperCase() + this.substring(1).toLowerCase(); + }, + + underscore: function() { + return this.gsub(/::/, '/').gsub(/([A-Z]+)([A-Z][a-z])/,'#{1}_#{2}').gsub(/([a-z\d])([A-Z])/,'#{1}_#{2}').gsub(/-/,'_').toLowerCase(); + }, + + dasherize: function() { + return this.gsub(/_/,'-'); + }, + + inspect: function(useDoubleQuotes) { + var escapedString = this.gsub(/[\x00-\x1f\\]/, function(match) { + var character = String.specialChar[match[0]]; + return character ? character : '\\u00' + match[0].charCodeAt().toPaddedString(2, 16); + }); + if (useDoubleQuotes) return '"' + escapedString.replace(/"/g, '\\"') + '"'; + return "'" + escapedString.replace(/'/g, '\\\'') + "'"; + }, + + toJSON: function() { + return this.inspect(true); + }, + + unfilterJSON: function(filter) { + return this.sub(filter || Prototype.JSONFilter, '#{1}'); + }, + + isJSON: function() { + var str = this.replace(/\\./g, '@').replace(/"[^"\\\n\r]*"/g, ''); + return (/^[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]*$/).test(str); + }, + + evalJSON: function(sanitize) { + var json = this.unfilterJSON(); + try { + if (!sanitize || json.isJSON()) return eval('(' + json + ')'); + } catch (e) { } + throw new SyntaxError('Badly formed JSON string: ' + this.inspect()); + }, + + include: function(pattern) { + return this.indexOf(pattern) > -1; + }, + + startsWith: function(pattern) { + return this.indexOf(pattern) === 0; + }, + + endsWith: function(pattern) { + var d = this.length - pattern.length; + return d >= 0 && this.lastIndexOf(pattern) === d; + }, + + empty: function() { + return this == ''; + }, + + blank: function() { + return /^\s*$/.test(this); + }, + + interpolate: function(object, pattern) { + return new Template(this, pattern).evaluate(object); + } +}); + +if (Prototype.Browser.WebKit || Prototype.Browser.IE) Object.extend(String.prototype, { + escapeHTML: function() { + return this.replace(/&/g,'&').replace(//g,'>'); + }, + unescapeHTML: function() { + return this.replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>'); + } +}); + +String.prototype.gsub.prepareReplacement = function(replacement) { + if (Object.isFunction(replacement)) return replacement; + var template = new Template(replacement); + return function(match) { return template.evaluate(match) }; +}; + +String.prototype.parseQuery = String.prototype.toQueryParams; + +Object.extend(String.prototype.escapeHTML, { + div: document.createElement('div'), + text: document.createTextNode('') +}); + +with (String.prototype.escapeHTML) div.appendChild(text); + +var Template = Class.create({ + initialize: function(template, pattern) { + this.template = template.toString(); + this.pattern = pattern || Template.Pattern; + }, + + evaluate: function(object) { + if (Object.isFunction(object.toTemplateReplacements)) + object = object.toTemplateReplacements(); + + return this.template.gsub(this.pattern, function(match) { + if (object == null) return ''; + + var before = match[1] || ''; + if (before == '\\') return match[2]; + + var ctx = object, expr = match[3]; + var pattern = /^([^.[]+|\[((?:.*?[^\\])?)\])(\.|\[|$)/, match = pattern.exec(expr); + if (match == null) return ''; + + while (match != null) { + var comp = match[1].startsWith('[') ? match[2].gsub('\\\\]', ']') : match[1]; + ctx = ctx[comp]; + if (null == ctx || '' == match[3]) break; + expr = expr.substring('[' == match[3] ? match[1].length : match[0].length); + match = pattern.exec(expr); + } + + return before + String.interpret(ctx); + }.bind(this)); + } +}); +Template.Pattern = /(^|.|\r|\n)(#\{(.*?)\})/; + +var $break = { }; + +var Enumerable = { + each: function(iterator, context) { + var index = 0; + iterator = iterator.bind(context); + try { + this._each(function(value) { + iterator(value, index++); + }); + } catch (e) { + if (e != $break) throw e; + } + return this; + }, + + eachSlice: function(number, iterator, context) { + iterator = iterator ? iterator.bind(context) : Prototype.K; + var index = -number, slices = [], array = this.toArray(); + while ((index += number) < array.length) + slices.push(array.slice(index, index+number)); + return slices.collect(iterator, context); + }, + + all: function(iterator, context) { + iterator = iterator ? iterator.bind(context) : Prototype.K; + var result = true; + this.each(function(value, index) { + result = result && !!iterator(value, index); + if (!result) throw $break; + }); + return result; + }, + + any: function(iterator, context) { + iterator = iterator ? iterator.bind(context) : Prototype.K; + var result = false; + this.each(function(value, index) { + if (result = !!iterator(value, index)) + throw $break; + }); + return result; + }, + + collect: function(iterator, context) { + iterator = iterator ? iterator.bind(context) : Prototype.K; + var results = []; + this.each(function(value, index) { + results.push(iterator(value, index)); + }); + return results; + }, + + detect: function(iterator, context) { + iterator = iterator.bind(context); + var result; + this.each(function(value, index) { + if (iterator(value, index)) { + result = value; + throw $break; + } + }); + return result; + }, + + findAll: function(iterator, context) { + iterator = iterator.bind(context); + var results = []; + this.each(function(value, index) { + if (iterator(value, index)) + results.push(value); + }); + return results; + }, + + grep: function(filter, iterator, context) { + iterator = iterator ? iterator.bind(context) : Prototype.K; + var results = []; + + if (Object.isString(filter)) + filter = new RegExp(filter); + + this.each(function(value, index) { + if (filter.match(value)) + results.push(iterator(value, index)); + }); + return results; + }, + + include: function(object) { + if (Object.isFunction(this.indexOf)) + if (this.indexOf(object) != -1) return true; + + var found = false; + this.each(function(value) { + if (value == object) { + found = true; + throw $break; + } + }); + return found; + }, + + inGroupsOf: function(number, fillWith) { + fillWith = fillWith === undefined ? null : fillWith; + return this.eachSlice(number, function(slice) { + while(slice.length < number) slice.push(fillWith); + return slice; + }); + }, + + inject: function(memo, iterator, context) { + iterator = iterator.bind(context); + this.each(function(value, index) { + memo = iterator(memo, value, index); + }); + return memo; + }, + + invoke: function(method) { + var args = $A(arguments).slice(1); + return this.map(function(value) { + return value[method].apply(value, args); + }); + }, + + max: function(iterator, context) { + iterator = iterator ? iterator.bind(context) : Prototype.K; + var result; + this.each(function(value, index) { + value = iterator(value, index); + if (result == undefined || value >= result) + result = value; + }); + return result; + }, + + min: function(iterator, context) { + iterator = iterator ? iterator.bind(context) : Prototype.K; + var result; + this.each(function(value, index) { + value = iterator(value, index); + if (result == undefined || value < result) + result = value; + }); + return result; + }, + + partition: function(iterator, context) { + iterator = iterator ? iterator.bind(context) : Prototype.K; + var trues = [], falses = []; + this.each(function(value, index) { + (iterator(value, index) ? + trues : falses).push(value); + }); + return [trues, falses]; + }, + + pluck: function(property) { + var results = []; + this.each(function(value) { + results.push(value[property]); + }); + return results; + }, + + reject: function(iterator, context) { + iterator = iterator.bind(context); + var results = []; + this.each(function(value, index) { + if (!iterator(value, index)) + results.push(value); + }); + return results; + }, + + sortBy: function(iterator, context) { + iterator = iterator.bind(context); + return this.map(function(value, index) { + return {value: value, criteria: iterator(value, index)}; + }).sort(function(left, right) { + var a = left.criteria, b = right.criteria; + return a < b ? -1 : a > b ? 1 : 0; + }).pluck('value'); + }, + + toArray: function() { + return this.map(); + }, + + zip: function() { + var iterator = Prototype.K, args = $A(arguments); + if (Object.isFunction(args.last())) + iterator = args.pop(); + + var collections = [this].concat(args).map($A); + return this.map(function(value, index) { + return iterator(collections.pluck(index)); + }); + }, + + size: function() { + return this.toArray().length; + }, + + inspect: function() { + return '#'; + } +}; + +Object.extend(Enumerable, { + map: Enumerable.collect, + find: Enumerable.detect, + select: Enumerable.findAll, + filter: Enumerable.findAll, + member: Enumerable.include, + entries: Enumerable.toArray, + every: Enumerable.all, + some: Enumerable.any +}); +function $A(iterable) { + if (!iterable) return []; + if (iterable.toArray) return iterable.toArray(); + else { + var results = []; + for (var i = 0, length = iterable.length; i < length; i++) + results.push(iterable[i]); + return results; + } +} + +if (Prototype.Browser.WebKit) { + function $A(iterable) { + if (!iterable) return []; + if (!(Object.isFunction(iterable) && iterable == '[object NodeList]') && + iterable.toArray) { + return iterable.toArray(); + } else { + var results = []; + for (var i = 0, length = iterable.length; i < length; i++) + results.push(iterable[i]); + return results; + } + } +} + +Array.from = $A; + +Object.extend(Array.prototype, Enumerable); + +if (!Array.prototype._reverse) Array.prototype._reverse = Array.prototype.reverse; + +Object.extend(Array.prototype, { + _each: function(iterator) { + for (var i = 0, length = this.length; i < length; i++) + iterator(this[i]); + }, + + clear: function() { + this.length = 0; + return this; + }, + + first: function() { + return this[0]; + }, + + last: function() { + return this[this.length - 1]; + }, + + compact: function() { + return this.select(function(value) { + return value != null; + }); + }, + + flatten: function() { + return this.inject([], function(array, value) { + return array.concat(Object.isArray(value) ? + value.flatten() : [value]); + }); + }, + + without: function() { + var values = $A(arguments); + return this.select(function(value) { + return !values.include(value); + }); + }, + + reverse: function(inline) { + return (inline !== false ? this : this.toArray())._reverse(); + }, + + reduce: function() { + return this.length > 1 ? this : this[0]; + }, + + uniq: function(sorted) { + return this.inject([], function(array, value, index) { + if (0 == index || (sorted ? array.last() != value : !array.include(value))) + array.push(value); + return array; + }); + }, + + intersect: function(array) { + return this.uniq().findAll(function(item) { + return array.detect(function(value) { return item === value }); + }); + }, + + clone: function() { + return [].concat(this); + }, + + size: function() { + return this.length; + }, + + inspect: function() { + return '[' + this.map(Object.inspect).join(', ') + ']'; + }, + + toJSON: function() { + var results = []; + this.each(function(object) { + var value = Object.toJSON(object); + if (value !== undefined) results.push(value); + }); + return '[' + results.join(', ') + ']'; + } +}); + +// use native browser JS 1.6 implementation if available +if (Object.isFunction(Array.prototype.forEach)) + Array.prototype._each = Array.prototype.forEach; + +if (!Array.prototype.indexOf) Array.prototype.indexOf = function(item, i) { + i || (i = 0); + var length = this.length; + if (i < 0) i = length + i; + for (; i < length; i++) + if (this[i] === item) return i; + return -1; +}; + +if (!Array.prototype.lastIndexOf) Array.prototype.lastIndexOf = function(item, i) { + i = isNaN(i) ? this.length : (i < 0 ? this.length + i : i) + 1; + var n = this.slice(0, i).reverse().indexOf(item); + return (n < 0) ? n : i - n - 1; +}; + +Array.prototype.toArray = Array.prototype.clone; + +function $w(string) { + string = string.strip(); + return string ? string.split(/\s+/) : []; +} + +if (Prototype.Browser.Opera){ + Array.prototype.concat = function() { + var array = []; + for (var i = 0, length = this.length; i < length; i++) array.push(this[i]); + for (var i = 0, length = arguments.length; i < length; i++) { + if (Object.isArray(arguments[i])) { + for (var j = 0, arrayLength = arguments[i].length; j < arrayLength; j++) + array.push(arguments[i][j]); + } else { + array.push(arguments[i]); + } + } + return array; + }; +} +Object.extend(Number.prototype, { + toColorPart: function() { + return this.toPaddedString(2, 16); + }, + + succ: function() { + return this + 1; + }, + + times: function(iterator) { + $R(0, this, true).each(iterator); + return this; + }, + + toPaddedString: function(length, radix) { + var string = this.toString(radix || 10); + return '0'.times(length - string.length) + string; + }, + + toJSON: function() { + return isFinite(this) ? this.toString() : 'null'; + } +}); + +$w('abs round ceil floor').each(function(method){ + Number.prototype[method] = Math[method].methodize(); +}); +var Hash = function(object) { + if (object instanceof Hash) this.merge(object); + else Object.extend(this, object || { }); +}; + +Object.extend(Hash, { + toQueryString: function(obj) { + var parts = []; + parts.add = arguments.callee.addPair; + + this.prototype._each.call(obj, function(pair) { + if (!pair.key) return; + var value = pair.value; + + if (value && typeof value == 'object') { + if (Object.isArray(value)) value.each(function(value) { + parts.add(pair.key, value); + }); + return; + } + parts.add(pair.key, value); + }); + + return parts.join('&'); + }, + + toJSON: function(object) { + var results = []; + this.prototype._each.call(object, function(pair) { + var value = Object.toJSON(pair.value); + if (value !== undefined) results.push(pair.key.toJSON() + ': ' + value); + }); + return '{' + results.join(', ') + '}'; + } +}); + +Hash.toQueryString.addPair = function(key, value, prefix) { + key = encodeURIComponent(key); + if (value === undefined) this.push(key); + else this.push(key + '=' + (value == null ? '' : encodeURIComponent(value))); +}; + +Object.extend(Hash.prototype, Enumerable); +Object.extend(Hash.prototype, { + _each: function(iterator) { + for (var key in this) { + var value = this[key]; + if (value && value == Hash.prototype[key]) continue; + + var pair = [key, value]; + pair.key = key; + pair.value = value; + iterator(pair); + } + }, + + keys: function() { + return this.pluck('key'); + }, + + values: function() { + return this.pluck('value'); + }, + + index: function(value) { + var match = this.detect(function(pair) { + return pair.value === value; + }); + return match && match.key; + }, + + merge: function(hash) { + return $H(hash).inject(this, function(mergedHash, pair) { + mergedHash[pair.key] = pair.value; + return mergedHash; + }); + }, + + remove: function() { + var result; + for(var i = 0, length = arguments.length; i < length; i++) { + var value = this[arguments[i]]; + if (value !== undefined){ + if (result === undefined) result = value; + else { + if (!Object.isArray(result)) result = [result]; + result.push(value); + } + } + delete this[arguments[i]]; + } + return result; + }, + + toQueryString: function() { + return Hash.toQueryString(this); + }, + + inspect: function() { + return '#'; + }, + + toJSON: function() { + return Hash.toJSON(this); + } +}); + +function $H(object) { + if (object instanceof Hash) return object; + return new Hash(object); +}; + +// Safari iterates over shadowed properties +if (function() { + var i = 0, Test = function(value) { this.key = value }; + Test.prototype.key = 'foo'; + for (var property in new Test('bar')) i++; + return i > 1; +}()) Hash.prototype._each = function(iterator) { + var cache = []; + for (var key in this) { + var value = this[key]; + if ((value && value == Hash.prototype[key]) || cache.include(key)) continue; + cache.push(key); + var pair = [key, value]; + pair.key = key; + pair.value = value; + iterator(pair); + } +}; +ObjectRange = Class.create({ + initialize: function(start, end, exclusive) { + this.start = start; + this.end = end; + this.exclusive = exclusive; + }, + + _each: function(iterator) { + var value = this.start; + while (this.include(value)) { + iterator(value); + value = value.succ(); + } + } +}); + +Object.extend(ObjectRange.prototype, Enumerable); + +ObjectRange.prototype.include = function(value) { + if (value < this.start) + return false; + if (this.exclusive) + return value < this.end; + return value <= this.end; +}; + +var $R = function(start, end, exclusive) { + return new ObjectRange(start, end, exclusive); +}; + +var Ajax = { + getTransport: function() { + return Try.these( + function() {return new XMLHttpRequest()}, + function() {return new ActiveXObject('Msxml2.XMLHTTP')}, + function() {return new ActiveXObject('Microsoft.XMLHTTP')} + ) || false; + }, + + activeRequestCount: 0 +}; + +Ajax.Responders = { + responders: [], + + _each: function(iterator) { + this.responders._each(iterator); + }, + + register: function(responder) { + if (!this.include(responder)) + this.responders.push(responder); + }, + + unregister: function(responder) { + this.responders = this.responders.without(responder); + }, + + dispatch: function(callback, request, transport, json) { + this.each(function(responder) { + if (Object.isFunction(responder[callback])) { + try { + responder[callback].apply(responder, [request, transport, json]); + } catch (e) { } + } + }); + } +}; + +Object.extend(Ajax.Responders, Enumerable); + +Ajax.Responders.register({ + onCreate: function() { Ajax.activeRequestCount++ }, + onComplete: function() { Ajax.activeRequestCount-- } +}); + +Ajax.Base = Class.create({ + initialize: function(options) { + this.options = { + method: 'post', + asynchronous: true, + contentType: 'application/x-www-form-urlencoded', + encoding: 'UTF-8', + parameters: '', + evalJSON: true, + evalJS: true + }; + Object.extend(this.options, options || { }); + + this.options.method = this.options.method.toLowerCase(); + if (Object.isString(this.options.parameters)) + this.options.parameters = this.options.parameters.toQueryParams(); + } +}); + +Ajax.Request = Class.create(Ajax.Base, { + _complete: false, + + initialize: function($super, url, options) { + $super(options); + this.transport = Ajax.getTransport(); + this.request(url); + }, + + request: function(url) { + this.url = url; + this.method = this.options.method; + var params = Object.clone(this.options.parameters); + + if (!['get', 'post'].include(this.method)) { + // simulate other verbs over post + params['_method'] = this.method; + this.method = 'post'; + } + + this.parameters = params; + + if (params = Hash.toQueryString(params)) { + // when GET, append parameters to URL + if (this.method == 'get') + this.url += (this.url.include('?') ? '&' : '?') + params; + else if (/Konqueror|Safari|KHTML/.test(navigator.userAgent)) + params += '&_='; + } + + try { + var response = new Ajax.Response(this); + if (this.options.onCreate) this.options.onCreate(response); + Ajax.Responders.dispatch('onCreate', this, response); + + this.transport.open(this.method.toUpperCase(), this.url, + this.options.asynchronous); + + if (this.options.asynchronous) this.respondToReadyState.bind(this).defer(1); + + this.transport.onreadystatechange = this.onStateChange.bind(this); + this.setRequestHeaders(); + + this.body = this.method == 'post' ? (this.options.postBody || params) : null; + this.transport.send(this.body); + + /* Force Firefox to handle ready state 4 for synchronous requests */ + if (!this.options.asynchronous && this.transport.overrideMimeType) + this.onStateChange(); + + } + catch (e) { + this.dispatchException(e); + } + }, + + onStateChange: function() { + var readyState = this.transport.readyState; + if (readyState > 1 && !((readyState == 4) && this._complete)) + this.respondToReadyState(this.transport.readyState); + }, + + setRequestHeaders: function() { + var headers = { + 'X-Requested-With': 'XMLHttpRequest', + 'X-Prototype-Version': Prototype.Version, + 'Accept': 'text/javascript, text/html, application/xml, text/xml, */*' + }; + + if (this.method == 'post') { + headers['Content-type'] = this.options.contentType + + (this.options.encoding ? '; charset=' + this.options.encoding : ''); + + /* Force "Connection: close" for older Mozilla browsers to work + * around a bug where XMLHttpRequest sends an incorrect + * Content-length header. See Mozilla Bugzilla #246651. + */ + if (this.transport.overrideMimeType && + (navigator.userAgent.match(/Gecko\/(\d{4})/) || [0,2005])[1] < 2005) + headers['Connection'] = 'close'; + } + + // user-defined headers + if (typeof this.options.requestHeaders == 'object') { + var extras = this.options.requestHeaders; + + if (Object.isFunction(extras.push)) + for (var i = 0, length = extras.length; i < length; i += 2) + headers[extras[i]] = extras[i+1]; + else + $H(extras).each(function(pair) { headers[pair.key] = pair.value }); + } + + for (var name in headers) + this.transport.setRequestHeader(name, headers[name]); + }, + + success: function() { + var status = this.getStatus(); + return !status || (status >= 200 && status < 300); + }, + + getStatus: function() { + try { + return this.transport.status || 0; + } catch (e) { return 0 } + }, + + respondToReadyState: function(readyState) { + var state = Ajax.Request.Events[readyState], response = new Ajax.Response(this); + + if (state == 'Complete') { + try { + this._complete = true; + (this.options['on' + response.status] + || this.options['on' + (this.success() ? 'Success' : 'Failure')] + || Prototype.emptyFunction)(response, response.headerJSON); + } catch (e) { + this.dispatchException(e); + } + + var contentType = response.getHeader('Content-type'); + if (this.options.evalJS == 'force' + || (this.options.evalJS && contentType + && contentType.match(/^\s*(text|application)\/(x-)?(java|ecma)script(;.*)?\s*$/i))) + this.evalResponse(); + } + + try { + (this.options['on' + state] || Prototype.emptyFunction)(response, response.headerJSON); + Ajax.Responders.dispatch('on' + state, this, response, response.headerJSON); + } catch (e) { + this.dispatchException(e); + } + + if (state == 'Complete') { + // avoid memory leak in MSIE: clean up + this.transport.onreadystatechange = Prototype.emptyFunction; + } + }, + + getHeader: function(name) { + try { + return this.transport.getResponseHeader(name); + } catch (e) { return null } + }, + + evalResponse: function() { + try { + return eval((this.transport.responseText || '').unfilterJSON()); + } catch (e) { + this.dispatchException(e); + } + }, + + dispatchException: function(exception) { + (this.options.onException || Prototype.emptyFunction)(this, exception); + Ajax.Responders.dispatch('onException', this, exception); + } +}); + +Ajax.Request.Events = + ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete']; + +Ajax.Response = Class.create({ + initialize: function(request){ + this.request = request; + var transport = this.transport = request.transport, + readyState = this.readyState = transport.readyState; + + if((readyState > 2 && !Prototype.Browser.IE) || readyState == 4) { + this.status = this.getStatus(); + this.statusText = this.getStatusText(); + this.responseText = String.interpret(transport.responseText); + this.headerJSON = this.getHeaderJSON(); + } + + if(readyState == 4) { + var xml = transport.responseXML; + this.responseXML = xml === undefined ? null : xml; + this.responseJSON = this.getResponseJSON(); + } + }, + + status: 0, + statusText: '', + + getStatus: Ajax.Request.prototype.getStatus, + + getStatusText: function() { + try { + return this.transport.statusText || ''; + } catch (e) { return '' } + }, + + getHeader: Ajax.Request.prototype.getHeader, + + getAllHeaders: function() { + try { + return this.getAllResponseHeaders(); + } catch (e) { return null } + }, + + getResponseHeader: function(name) { + return this.transport.getResponseHeader(name); + }, + + getAllResponseHeaders: function() { + return this.transport.getAllResponseHeaders(); + }, + + getHeaderJSON: function() { + var json = this.getHeader('X-JSON'); + try { + return json ? json.evalJSON(this.request.options.sanitizeJSON) : null; + } catch (e) { + this.request.dispatchException(e); + } + }, + + getResponseJSON: function() { + var options = this.request.options; + try { + if (options.evalJSON == 'force' || (options.evalJSON && + (this.getHeader('Content-type') || '').include('application/json'))) + return this.transport.responseText.evalJSON(options.sanitizeJSON); + return null; + } catch (e) { + this.request.dispatchException(e); + } + } +}); + +Ajax.Updater = Class.create(Ajax.Request, { + initialize: function($super, container, url, options) { + this.container = { + success: (container.success || container), + failure: (container.failure || (container.success ? null : container)) + }; + + options = options || { }; + var onComplete = options.onComplete; + options.onComplete = (function(response, param) { + this.updateContent(response.responseText); + if (Object.isFunction(onComplete)) onComplete(response, param); + }).bind(this); + + $super(url, options); + }, + + updateContent: function(responseText) { + var receiver = this.container[this.success() ? 'success' : 'failure'], + options = this.options; + + if (!options.evalScripts) responseText = responseText.stripScripts(); + + if (receiver = $(receiver)) { + if (options.insertion) { + if (Object.isString(options.insertion)) { + var insertion = { }; insertion[options.insertion] = responseText; + receiver.insert(insertion); + } + else options.insertion(receiver, responseText); + } + else receiver.update(responseText); + } + + if (this.success()) { + if (this.onComplete) this.onComplete.bind(this).defer(); + } + } +}); + +Ajax.PeriodicalUpdater = Class.create(Ajax.Base, { + initialize: function($super, container, url, options) { + $super(options); + this.onComplete = this.options.onComplete; + + this.frequency = (this.options.frequency || 2); + this.decay = (this.options.decay || 1); + + this.updater = { }; + this.container = container; + this.url = url; + + this.start(); + }, + + start: function() { + this.options.onComplete = this.updateComplete.bind(this); + this.onTimerEvent(); + }, + + stop: function() { + this.updater.options.onComplete = undefined; + clearTimeout(this.timer); + (this.onComplete || Prototype.emptyFunction).apply(this, arguments); + }, + + updateComplete: function(response) { + if (this.options.decay) { + this.decay = (response.responseText == this.lastText ? + this.decay * this.options.decay : 1); + + this.lastText = response.responseText; + } + this.timer = this.onTimerEvent.bind(this).delay(this.decay * this.frequency); + }, + + onTimerEvent: function() { + this.updater = new Ajax.Updater(this.container, this.url, this.options); + } +}); +function $(element) { + if (arguments.length > 1) { + for (var i = 0, elements = [], length = arguments.length; i < length; i++) + elements.push($(arguments[i])); + return elements; + } + if (Object.isString(element)) + element = document.getElementById(element); + return Element.extend(element); +} + +if (Prototype.BrowserFeatures.XPath) { + document._getElementsByXPath = function(expression, parentElement) { + var results = []; + var query = document.evaluate(expression, $(parentElement) || document, + null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null); + for (var i = 0, length = query.snapshotLength; i < length; i++) + results.push(Element.extend(query.snapshotItem(i))); + return results; + }; +} + +/*--------------------------------------------------------------------------*/ + +if (!window.Node) var Node = { }; + +if (!Node.ELEMENT_NODE) { + // DOM level 2 ECMAScript Language Binding + Object.extend(Node, { + ELEMENT_NODE: 1, + ATTRIBUTE_NODE: 2, + TEXT_NODE: 3, + CDATA_SECTION_NODE: 4, + ENTITY_REFERENCE_NODE: 5, + ENTITY_NODE: 6, + PROCESSING_INSTRUCTION_NODE: 7, + COMMENT_NODE: 8, + DOCUMENT_NODE: 9, + DOCUMENT_TYPE_NODE: 10, + DOCUMENT_FRAGMENT_NODE: 11, + NOTATION_NODE: 12 + }); +} + +(function() { + var element = this.Element; + this.Element = function(tagName, attributes) { + attributes = attributes || { }; + tagName = tagName.toLowerCase(); + var cache = Element.cache; + if (Prototype.Browser.IE && attributes.name) { + tagName = '<' + tagName + ' name="' + attributes.name + '">'; + delete attributes.name; + return Element.writeAttribute(document.createElement(tagName), attributes); + } + if (!cache[tagName]) cache[tagName] = Element.extend(document.createElement(tagName)); + return Element.writeAttribute(cache[tagName].cloneNode(false), attributes); + }; + Object.extend(this.Element, element || { }); +}).call(window); + +Element.cache = { }; + +Element.Methods = { + visible: function(element) { + return $(element).style.display != 'none'; + }, + + toggle: function(element) { + element = $(element); + Element[Element.visible(element) ? 'hide' : 'show'](element); + return element; + }, + + hide: function(element) { + $(element).style.display = 'none'; + return element; + }, + + show: function(element) { + $(element).style.display = ''; + return element; + }, + + remove: function(element) { + element = $(element); + element.parentNode.removeChild(element); + return element; + }, + + update: function(element, content) { + element = $(element); + if (content && content.toElement) content = content.toElement(); + if (Object.isElement(content)) return element.update().insert(content); + content = Object.toHTML(content); + element.innerHTML = content.stripScripts(); + content.evalScripts.bind(content).defer(); + return element; + }, + + replace: function(element, content) { + element = $(element); + if (content && content.toElement) content = content.toElement(); + else if (!Object.isElement(content)) { + content = Object.toHTML(content); + var range = element.ownerDocument.createRange(); + range.selectNode(element); + content.evalScripts.bind(content).defer(); + content = range.createContextualFragment(content.stripScripts()); + } + element.parentNode.replaceChild(content, element); + return element; + }, + + insert: function(element, insertions) { + element = $(element); + + if (Object.isString(insertions) || Object.isNumber(insertions) || + Object.isElement(insertions) || (insertions && (insertions.toElement || insertions.toHTML))) + insertions = {bottom:insertions}; + + var content, t, range; + + for (position in insertions) { + content = insertions[position]; + position = position.toLowerCase(); + t = Element._insertionTranslations[position]; + + if (content && content.toElement) content = content.toElement(); + if (Object.isElement(content)) { + t.insert(element, content); + continue; + } + + content = Object.toHTML(content); + + range = element.ownerDocument.createRange(); + t.initializeRange(element, range); + t.insert(element, range.createContextualFragment(content.stripScripts())); + + content.evalScripts.bind(content).defer(); + } + + return element; + }, + + wrap: function(element, wrapper, attributes) { + element = $(element); + if (Object.isElement(wrapper)) + $(wrapper).writeAttribute(attributes || { }); + else if (Object.isString(wrapper)) wrapper = new Element(wrapper, attributes); + else wrapper = new Element('div', wrapper); + if (element.parentNode) + element.parentNode.replaceChild(wrapper, element); + wrapper.appendChild(element); + return wrapper; + }, + + inspect: function(element) { + element = $(element); + var result = '<' + element.tagName.toLowerCase(); + $H({'id': 'id', 'className': 'class'}).each(function(pair) { + var property = pair.first(), attribute = pair.last(); + var value = (element[property] || '').toString(); + if (value) result += ' ' + attribute + '=' + value.inspect(true); + }); + return result + '>'; + }, + + recursivelyCollect: function(element, property) { + element = $(element); + var elements = []; + while (element = element[property]) + if (element.nodeType == 1) + elements.push(Element.extend(element)); + return elements; + }, + + ancestors: function(element) { + return $(element).recursivelyCollect('parentNode'); + }, + + descendants: function(element) { + return $A($(element).getElementsByTagName('*')).each(Element.extend); + }, + + firstDescendant: function(element) { + element = $(element).firstChild; + while (element && element.nodeType != 1) element = element.nextSibling; + return $(element); + }, + + immediateDescendants: function(element) { + if (!(element = $(element).firstChild)) return []; + while (element && element.nodeType != 1) element = element.nextSibling; + if (element) return [element].concat($(element).nextSiblings()); + return []; + }, + + previousSiblings: function(element) { + return $(element).recursivelyCollect('previousSibling'); + }, + + nextSiblings: function(element) { + return $(element).recursivelyCollect('nextSibling'); + }, + + siblings: function(element) { + element = $(element); + return element.previousSiblings().reverse().concat(element.nextSiblings()); + }, + + match: function(element, selector) { + if (Object.isString(selector)) + selector = new Selector(selector); + return selector.match($(element)); + }, + + up: function(element, expression, index) { + element = $(element); + if (arguments.length == 1) return $(element.parentNode); + var ancestors = element.ancestors(); + return expression ? Selector.findElement(ancestors, expression, index) : + ancestors[index || 0]; + }, + + down: function(element, expression, index) { + element = $(element); + if (arguments.length == 1) return element.firstDescendant(); + var descendants = element.descendants(); + return expression ? Selector.findElement(descendants, expression, index) : + descendants[index || 0]; + }, + + previous: function(element, expression, index) { + element = $(element); + if (arguments.length == 1) return $(Selector.handlers.previousElementSibling(element)); + var previousSiblings = element.previousSiblings(); + return expression ? Selector.findElement(previousSiblings, expression, index) : + previousSiblings[index || 0]; + }, + + next: function(element, expression, index) { + element = $(element); + if (arguments.length == 1) return $(Selector.handlers.nextElementSibling(element)); + var nextSiblings = element.nextSiblings(); + return expression ? Selector.findElement(nextSiblings, expression, index) : + nextSiblings[index || 0]; + }, + + select: function() { + var args = $A(arguments), element = $(args.shift()); + return Selector.findChildElements(element, args); + }, + + adjacent: function() { + var args = $A(arguments), element = $(args.shift()); + return Selector.findChildElements(element.parentNode, args).without(element); + }, + + identify: function(element) { + element = $(element); + var id = element.readAttribute('id'), self = arguments.callee; + if (id) return id; + do { id = 'anonymous_element_' + self.counter++ } while ($(id)); + element.writeAttribute('id', id); + return id; + }, + + readAttribute: function(element, name) { + element = $(element); + if (Prototype.Browser.IE) { + var t = Element._attributeTranslations.read; + if (t.values[name]) return t.values[name](element, name); + if (t.names[name]) name = t.names[name]; + if (name.include(':')) { + return (!element.attributes || !element.attributes[name]) ? null : + element.attributes[name].value; + } + } + return element.getAttribute(name); + }, + + writeAttribute: function(element, name, value) { + element = $(element); + var attributes = { }, t = Element._attributeTranslations.write; + + if (typeof name == 'object') attributes = name; + else attributes[name] = value === undefined ? true : value; + + for (var attr in attributes) { + var name = t.names[attr] || attr, value = attributes[attr]; + if (t.values[attr]) name = t.values[attr](element, value); + if (value === false || value === null) + element.removeAttribute(name); + else if (value === true) + element.setAttribute(name, name); + else element.setAttribute(name, value); + } + return element; + }, + + getHeight: function(element) { + return $(element).getDimensions().height; + }, + + getWidth: function(element) { + return $(element).getDimensions().width; + }, + + classNames: function(element) { + return new Element.ClassNames(element); + }, + + hasClassName: function(element, className) { + if (!(element = $(element))) return; + var elementClassName = element.className; + return (elementClassName.length > 0 && (elementClassName == className || + elementClassName.match(new RegExp("(^|\\s)" + className + "(\\s|$)")))); + }, + + addClassName: function(element, className) { + if (!(element = $(element))) return; + if (!element.hasClassName(className)) + element.className += (element.className ? ' ' : '') + className; + return element; + }, + + removeClassName: function(element, className) { + if (!(element = $(element))) return; + element.className = element.className.replace( + new RegExp("(^|\\s+)" + className + "(\\s+|$)"), ' ').strip(); + return element; + }, + + toggleClassName: function(element, className) { + if (!(element = $(element))) return; + return element[element.hasClassName(className) ? + 'removeClassName' : 'addClassName'](className); + }, + + // removes whitespace-only text node children + cleanWhitespace: function(element) { + element = $(element); + var node = element.firstChild; + while (node) { + var nextNode = node.nextSibling; + if (node.nodeType == 3 && !/\S/.test(node.nodeValue)) + element.removeChild(node); + node = nextNode; + } + return element; + }, + + empty: function(element) { + return $(element).innerHTML.blank(); + }, + + descendantOf: function(element, ancestor) { + element = $(element), ancestor = $(ancestor); + while (element = element.parentNode) + if (element == ancestor) return true; + return false; + }, + + scrollTo: function(element) { + element = $(element); + var pos = element.cumulativeOffset(); + window.scrollTo(pos[0], pos[1]); + return element; + }, + + getStyle: function(element, style) { + element = $(element); + style = style == 'float' ? 'cssFloat' : style.camelize(); + var value = element.style[style]; + if (!value) { + var css = document.defaultView.getComputedStyle(element, null); + value = css ? css[style] : null; + } + if (style == 'opacity') return value ? parseFloat(value) : 1.0; + return value == 'auto' ? null : value; + }, + + getOpacity: function(element) { + return $(element).getStyle('opacity'); + }, + + setStyle: function(element, styles) { + element = $(element); + var elementStyle = element.style, match; + if (Object.isString(styles)) { + element.style.cssText += ';' + styles; + return styles.include('opacity') ? + element.setOpacity(styles.match(/opacity:\s*(\d?\.?\d*)/)[1]) : element; + } + for (var property in styles) + if (property == 'opacity') element.setOpacity(styles[property]); + else + elementStyle[(property == 'float' || property == 'cssFloat') ? + (elementStyle.styleFloat === undefined ? 'cssFloat' : 'styleFloat') : + property] = styles[property]; + + return element; + }, + + setOpacity: function(element, value) { + element = $(element); + element.style.opacity = (value == 1 || value === '') ? '' : + (value < 0.00001) ? 0 : value; + return element; + }, + + getDimensions: function(element) { + element = $(element); + var display = $(element).getStyle('display'); + if (display != 'none' && display != null) // Safari bug + return {width: element.offsetWidth, height: element.offsetHeight}; + + // All *Width and *Height properties give 0 on elements with display none, + // so enable the element temporarily + var els = element.style; + var originalVisibility = els.visibility; + var originalPosition = els.position; + var originalDisplay = els.display; + els.visibility = 'hidden'; + els.position = 'absolute'; + els.display = 'block'; + var originalWidth = element.clientWidth; + var originalHeight = element.clientHeight; + els.display = originalDisplay; + els.position = originalPosition; + els.visibility = originalVisibility; + return {width: originalWidth, height: originalHeight}; + }, + + makePositioned: function(element) { + element = $(element); + var pos = Element.getStyle(element, 'position'); + if (pos == 'static' || !pos) { + element._madePositioned = true; + element.style.position = 'relative'; + // Opera returns the offset relative to the positioning context, when an + // element is position relative but top and left have not been defined + if (window.opera) { + element.style.top = 0; + element.style.left = 0; + } + } + return element; + }, + + undoPositioned: function(element) { + element = $(element); + if (element._madePositioned) { + element._madePositioned = undefined; + element.style.position = + element.style.top = + element.style.left = + element.style.bottom = + element.style.right = ''; + } + return element; + }, + + makeClipping: function(element) { + element = $(element); + if (element._overflow) return element; + element._overflow = element.style.overflow || 'auto'; + if ((Element.getStyle(element, 'overflow') || 'visible') != 'hidden') + element.style.overflow = 'hidden'; + return element; + }, + + undoClipping: function(element) { + element = $(element); + if (!element._overflow) return element; + element.style.overflow = element._overflow == 'auto' ? '' : element._overflow; + element._overflow = null; + return element; + }, + + cumulativeOffset: function(element) { + var valueT = 0, valueL = 0; + do { + valueT += element.offsetTop || 0; + valueL += element.offsetLeft || 0; + element = element.offsetParent; + } while (element); + return Element._returnOffset(valueL, valueT); + }, + + positionedOffset: function(element) { + var valueT = 0, valueL = 0; + do { + valueT += element.offsetTop || 0; + valueL += element.offsetLeft || 0; + element = element.offsetParent; + if (element) { + if (element.tagName == 'BODY') break; + var p = Element.getStyle(element, 'position'); + if (p == 'relative' || p == 'absolute') break; + } + } while (element); + return Element._returnOffset(valueL, valueT); + }, + + absolutize: function(element) { + element = $(element); + if (element.getStyle('position') == 'absolute') return; + // Position.prepare(); // To be done manually by Scripty when it needs it. + + var offsets = element.positionedOffset(); + var top = offsets[1]; + var left = offsets[0]; + var width = element.clientWidth; + var height = element.clientHeight; + + element._originalLeft = left - parseFloat(element.style.left || 0); + element._originalTop = top - parseFloat(element.style.top || 0); + element._originalWidth = element.style.width; + element._originalHeight = element.style.height; + + element.style.position = 'absolute'; + element.style.top = top + 'px'; + element.style.left = left + 'px'; + element.style.width = width + 'px'; + element.style.height = height + 'px'; + return element; + }, + + relativize: function(element) { + element = $(element); + if (element.getStyle('position') == 'relative') return; + // Position.prepare(); // To be done manually by Scripty when it needs it. + + element.style.position = 'relative'; + var top = parseFloat(element.style.top || 0) - (element._originalTop || 0); + var left = parseFloat(element.style.left || 0) - (element._originalLeft || 0); + + element.style.top = top + 'px'; + element.style.left = left + 'px'; + element.style.height = element._originalHeight; + element.style.width = element._originalWidth; + return element; + }, + + cumulativeScrollOffset: function(element) { + var valueT = 0, valueL = 0; + do { + valueT += element.scrollTop || 0; + valueL += element.scrollLeft || 0; + element = element.parentNode; + } while (element); + return Element._returnOffset(valueL, valueT); + }, + + getOffsetParent: function(element) { + if (element.offsetParent) return $(element.offsetParent); + if (element == document.body) return $(element); + + while ((element = element.parentNode) && element != document.body) + if (Element.getStyle(element, 'position') != 'static') + return $(element); + + return $(document.body); + }, + + viewportOffset: function(forElement) { + var valueT = 0, valueL = 0; + + var element = forElement; + do { + valueT += element.offsetTop || 0; + valueL += element.offsetLeft || 0; + + // Safari fix + if (element.offsetParent == document.body && + Element.getStyle(element, 'position') == 'absolute') break; + + } while (element = element.offsetParent); + + element = forElement; + do { + if (!Prototype.Browser.Opera || element.tagName == 'BODY') { + valueT -= element.scrollTop || 0; + valueL -= element.scrollLeft || 0; + } + } while (element = element.parentNode); + + return Element._returnOffset(valueL, valueT); + }, + + clonePosition: function(element, source) { + var options = Object.extend({ + setLeft: true, + setTop: true, + setWidth: true, + setHeight: true, + offsetTop: 0, + offsetLeft: 0 + }, arguments[2] || { }); + + // find page position of source + source = $(source); + var p = source.viewportOffset(); + + // find coordinate system to use + element = $(element); + var delta = [0, 0]; + var parent = null; + // delta [0,0] will do fine with position: fixed elements, + // position:absolute needs offsetParent deltas + if (Element.getStyle(element, 'position') == 'absolute') { + parent = element.getOffsetParent(); + delta = parent.viewportOffset(); + } + + // correct by body offsets (fixes Safari) + if (parent == document.body) { + delta[0] -= document.body.offsetLeft; + delta[1] -= document.body.offsetTop; + } + + // set position + if (options.setLeft) element.style.left = (p[0] - delta[0] + options.offsetLeft) + 'px'; + if (options.setTop) element.style.top = (p[1] - delta[1] + options.offsetTop) + 'px'; + if (options.setWidth) element.style.width = source.offsetWidth + 'px'; + if (options.setHeight) element.style.height = source.offsetHeight + 'px'; + return element; + } +}; + +Element.Methods.identify.counter = 1; + +Object.extend(Element.Methods, { + getElementsBySelector: Element.Methods.select, + childElements: Element.Methods.immediateDescendants +}); + +Element._attributeTranslations = { + write: { + names: { + className: 'class', + htmlFor: 'for' + }, + values: { } + } +}; + + +if (!document.createRange || Prototype.Browser.Opera) { + Element.Methods.insert = function(element, insertions) { + element = $(element); + + if (Object.isString(insertions) || Object.isNumber(insertions) || + Object.isElement(insertions) || (insertions && (insertions.toElement || insertions.toHTML))) + insertions = { bottom: insertions }; + + var t = Element._insertionTranslations, content, position, pos, tagName; + + for (position in insertions) { + content = insertions[position]; + position = position.toLowerCase(); + pos = t[position]; + + if (content && content.toElement) content = content.toElement(); + if (Object.isElement(content)) { + pos.insert(element, content); + continue; + } + + content = Object.toHTML(content); + tagName = ((position == 'before' || position == 'after') + ? element.parentNode : element).tagName.toUpperCase(); + + if (t.tags[tagName]) { + var fragments = Element._getContentFromAnonymousElement(tagName, content.stripScripts()); + if (position == 'top' || position == 'after') fragments.reverse(); + fragments.each(pos.insert.curry(element)); + } + else element.insertAdjacentHTML(pos.adjacency, content.stripScripts()); + + content.evalScripts.bind(content).defer(); + } + + return element; + }; +} + +if (Prototype.Browser.Opera) { + Element.Methods._getStyle = Element.Methods.getStyle; + Element.Methods.getStyle = function(element, style) { + switch(style) { + case 'left': + case 'top': + case 'right': + case 'bottom': + if (Element._getStyle(element, 'position') == 'static') return null; + default: return Element._getStyle(element, style); + } + }; + Element.Methods._readAttribute = Element.Methods.readAttribute; + Element.Methods.readAttribute = function(element, attribute) { + if (attribute == 'title') return element.title; + return Element._readAttribute(element, attribute); + }; +} + +else if (Prototype.Browser.IE) { + $w('positionedOffset getOffsetParent viewportOffset').each(function(method) { + Element.Methods[method] = Element.Methods[method].wrap( + function(proceed, element) { + element = $(element); + var position = element.getStyle('position'); + if (position != 'static') return proceed(element); + element.setStyle({ position: 'relative' }); + var value = proceed(element); + element.setStyle({ position: position }); + return value; + } + ); + }); + + Element.Methods.getStyle = function(element, style) { + element = $(element); + style = (style == 'float' || style == 'cssFloat') ? 'styleFloat' : style.camelize(); + var value = element.style[style]; + if (!value && element.currentStyle) value = element.currentStyle[style]; + + if (style == 'opacity') { + if (value = (element.getStyle('filter') || '').match(/alpha\(opacity=(.*)\)/)) + if (value[1]) return parseFloat(value[1]) / 100; + return 1.0; + } + + if (value == 'auto') { + if ((style == 'width' || style == 'height') && (element.getStyle('display') != 'none')) + return element['offset' + style.capitalize()] + 'px'; + return null; + } + return value; + }; + + Element.Methods.setOpacity = function(element, value) { + function stripAlpha(filter){ + return filter.replace(/alpha\([^\)]*\)/gi,''); + } + element = $(element); + if (!element.currentStyle.hasLayout) element.style.zoom = 1; + var filter = element.getStyle('filter'), style = element.style; + if (value == 1 || value === '') { + (filter = stripAlpha(filter)) ? + style.filter = filter : style.removeAttribute('filter'); + return element; + } else if (value < 0.00001) value = 0; + style.filter = stripAlpha(filter) + + 'alpha(opacity=' + (value * 100) + ')'; + return element; + }; + + Element._attributeTranslations = { + read: { + names: { + 'class': 'className', + 'for': 'htmlFor' + }, + values: { + _getAttr: function(element, attribute) { + return element.getAttribute(attribute, 2); + }, + _getAttrNode: function(element, attribute) { + var node = element.getAttributeNode(attribute); + return node ? node.value : ""; + }, + _getEv: function(element, attribute) { + var attribute = element.getAttribute(attribute); + return attribute ? attribute.toString().slice(23, -2) : null; + }, + _flag: function(element, attribute) { + return $(element).hasAttribute(attribute) ? attribute : null; + }, + style: function(element) { + return element.style.cssText.toLowerCase(); + }, + title: function(element) { + return element.title; + } + } + } + }; + + Element._attributeTranslations.write = { + names: Object.clone(Element._attributeTranslations.read.names), + values: { + checked: function(element, value) { + element.checked = !!value; + }, + + style: function(element, value) { + element.style.cssText = value ? value : ''; + } + } + }; + + Element._attributeTranslations.has = {}; + + $w('colSpan rowSpan vAlign dateTime accessKey tabIndex ' + + 'encType maxLength readOnly longDesc').each(function(attr) { + Element._attributeTranslations.write.names[attr.toLowerCase()] = attr; + Element._attributeTranslations.has[attr.toLowerCase()] = attr; + }); + + (function(v) { + Object.extend(v, { + href: v._getAttr, + src: v._getAttr, + type: v._getAttr, + action: v._getAttrNode, + disabled: v._flag, + checked: v._flag, + readonly: v._flag, + multiple: v._flag, + onload: v._getEv, + onunload: v._getEv, + onclick: v._getEv, + ondblclick: v._getEv, + onmousedown: v._getEv, + onmouseup: v._getEv, + onmouseover: v._getEv, + onmousemove: v._getEv, + onmouseout: v._getEv, + onfocus: v._getEv, + onblur: v._getEv, + onkeypress: v._getEv, + onkeydown: v._getEv, + onkeyup: v._getEv, + onsubmit: v._getEv, + onreset: v._getEv, + onselect: v._getEv, + onchange: v._getEv + }); + })(Element._attributeTranslations.read.values); +} + +else if (Prototype.Browser.Gecko) { + Element.Methods.setOpacity = function(element, value) { + element = $(element); + element.style.opacity = (value == 1) ? 0.999999 : + (value === '') ? '' : (value < 0.00001) ? 0 : value; + return element; + }; +} + +else if (Prototype.Browser.WebKit) { + Element.Methods.setOpacity = function(element, value) { + element = $(element); + element.style.opacity = (value == 1 || value === '') ? '' : + (value < 0.00001) ? 0 : value; + + if (value == 1) + if(element.tagName == 'IMG' && element.width) { + element.width++; element.width--; + } else try { + var n = document.createTextNode(' '); + element.appendChild(n); + element.removeChild(n); + } catch (e) { } + + return element; + }; + + // Safari returns margins on body which is incorrect if the child is absolutely + // positioned. For performance reasons, redefine Position.cumulativeOffset for + // KHTML/WebKit only. + Element.Methods.cumulativeOffset = function(element) { + var valueT = 0, valueL = 0; + do { + valueT += element.offsetTop || 0; + valueL += element.offsetLeft || 0; + if (element.offsetParent == document.body) + if (Element.getStyle(element, 'position') == 'absolute') break; + + element = element.offsetParent; + } while (element); + + return Element._returnOffset(valueL, valueT); + }; +} + +if (Prototype.Browser.IE || Prototype.Browser.Opera) { + // IE and Opera are missing .innerHTML support for TABLE-related and SELECT elements + Element.Methods.update = function(element, content) { + element = $(element); + + if (content && content.toElement) content = content.toElement(); + if (Object.isElement(content)) return element.update().insert(content); + + content = Object.toHTML(content); + var tagName = element.tagName.toUpperCase(); + + if (tagName in Element._insertionTranslations.tags) { + $A(element.childNodes).each(function(node) { element.removeChild(node) }); + Element._getContentFromAnonymousElement(tagName, content.stripScripts()) + .each(function(node) { element.appendChild(node) }); + } + else element.innerHTML = content.stripScripts(); + + content.evalScripts.bind(content).defer(); + return element; + }; +} + +if (document.createElement('div').outerHTML) { + Element.Methods.replace = function(element, content) { + element = $(element); + + if (content && content.toElement) content = content.toElement(); + if (Object.isElement(content)) { + element.parentNode.replaceChild(content, element); + return element; + } + + content = Object.toHTML(content); + var parent = element.parentNode, tagName = parent.tagName.toUpperCase(); + + if (Element._insertionTranslations.tags[tagName]) { + var nextSibling = element.next(); + var fragments = Element._getContentFromAnonymousElement(tagName, content.stripScripts()); + parent.removeChild(element); + if (nextSibling) + fragments.each(function(node) { parent.insertBefore(node, nextSibling) }); + else + fragments.each(function(node) { parent.appendChild(node) }); + } + else element.outerHTML = content.stripScripts(); + + content.evalScripts.bind(content).defer(); + return element; + }; +} + +Element._returnOffset = function(l, t) { + var result = [l, t]; + result.left = l; + result.top = t; + return result; +}; + +Element._getContentFromAnonymousElement = function(tagName, html) { + var div = new Element('div'), t = Element._insertionTranslations.tags[tagName]; + div.innerHTML = t[0] + html + t[1]; + t[2].times(function() { div = div.firstChild }); + return $A(div.childNodes); +}; + +Element._insertionTranslations = { + before: { + adjacency: 'beforeBegin', + insert: function(element, node) { + element.parentNode.insertBefore(node, element); + }, + initializeRange: function(element, range) { + range.setStartBefore(element); + } + }, + top: { + adjacency: 'afterBegin', + insert: function(element, node) { + element.insertBefore(node, element.firstChild); + }, + initializeRange: function(element, range) { + range.selectNodeContents(element); + range.collapse(true); + } + }, + bottom: { + adjacency: 'beforeEnd', + insert: function(element, node) { + element.appendChild(node); + } + }, + after: { + adjacency: 'afterEnd', + insert: function(element, node) { + element.parentNode.insertBefore(node, element.nextSibling); + }, + initializeRange: function(element, range) { + range.setStartAfter(element); + } + }, + tags: { + TABLE: ['
      ', '
      ', 1], + TBODY: ['', '
      ', 2], + TR: ['', '
      ', 3], + TD: ['
      ', '
      ', 4], + SELECT: ['', 1] + } +}; + +(function() { + this.bottom.initializeRange = this.top.initializeRange; + Object.extend(this.tags, { + THEAD: this.tags.TBODY, + TFOOT: this.tags.TBODY, + TH: this.tags.TD + }); +}).call(Element._insertionTranslations); + +Element.Methods.Simulated = { + hasAttribute: function(element, attribute) { + attribute = Element._attributeTranslations.has[attribute] || attribute; + var node = $(element).getAttributeNode(attribute); + return node && node.specified; + } +}; + +Element.Methods.ByTag = { }; + +Object.extend(Element, Element.Methods); + +if (!Prototype.BrowserFeatures.ElementExtensions && + document.createElement('div').__proto__) { + window.HTMLElement = { }; + window.HTMLElement.prototype = document.createElement('div').__proto__; + Prototype.BrowserFeatures.ElementExtensions = true; +} + +Element.extend = (function() { + if (Prototype.BrowserFeatures.SpecificElementExtensions) + return Prototype.K; + + var Methods = { }, ByTag = Element.Methods.ByTag; + + var extend = Object.extend(function(element) { + if (!element || element._extendedByPrototype || + element.nodeType != 1 || element == window) return element; + + var methods = Object.clone(Methods), + tagName = element.tagName, property, value; + + // extend methods for specific tags + if (ByTag[tagName]) Object.extend(methods, ByTag[tagName]); + + for (property in methods) { + value = methods[property]; + if (Object.isFunction(value) && !(property in element)) + element[property] = value.methodize(); + } + + element._extendedByPrototype = Prototype.emptyFunction; + return element; + + }, { + refresh: function() { + // extend methods for all tags (Safari doesn't need this) + if (!Prototype.BrowserFeatures.ElementExtensions) { + Object.extend(Methods, Element.Methods); + Object.extend(Methods, Element.Methods.Simulated); + } + } + }); + + extend.refresh(); + return extend; +})(); + +Element.hasAttribute = function(element, attribute) { + if (element.hasAttribute) return element.hasAttribute(attribute); + return Element.Methods.Simulated.hasAttribute(element, attribute); +}; + +Element.addMethods = function(methods) { + var F = Prototype.BrowserFeatures, T = Element.Methods.ByTag; + + if (!methods) { + Object.extend(Form, Form.Methods); + Object.extend(Form.Element, Form.Element.Methods); + Object.extend(Element.Methods.ByTag, { + "FORM": Object.clone(Form.Methods), + "INPUT": Object.clone(Form.Element.Methods), + "SELECT": Object.clone(Form.Element.Methods), + "TEXTAREA": Object.clone(Form.Element.Methods) + }); + } + + if (arguments.length == 2) { + var tagName = methods; + methods = arguments[1]; + } + + if (!tagName) Object.extend(Element.Methods, methods || { }); + else { + if (Object.isArray(tagName)) tagName.each(extend); + else extend(tagName); + } + + function extend(tagName) { + tagName = tagName.toUpperCase(); + if (!Element.Methods.ByTag[tagName]) + Element.Methods.ByTag[tagName] = { }; + Object.extend(Element.Methods.ByTag[tagName], methods); + } + + function copy(methods, destination, onlyIfAbsent) { + onlyIfAbsent = onlyIfAbsent || false; + for (var property in methods) { + var value = methods[property]; + if (!Object.isFunction(value)) continue; + if (!onlyIfAbsent || !(property in destination)) + destination[property] = value.methodize(); + } + } + + function findDOMClass(tagName) { + var klass; + var trans = { + "OPTGROUP": "OptGroup", "TEXTAREA": "TextArea", "P": "Paragraph", + "FIELDSET": "FieldSet", "UL": "UList", "OL": "OList", "DL": "DList", + "DIR": "Directory", "H1": "Heading", "H2": "Heading", "H3": "Heading", + "H4": "Heading", "H5": "Heading", "H6": "Heading", "Q": "Quote", + "INS": "Mod", "DEL": "Mod", "A": "Anchor", "IMG": "Image", "CAPTION": + "TableCaption", "COL": "TableCol", "COLGROUP": "TableCol", "THEAD": + "TableSection", "TFOOT": "TableSection", "TBODY": "TableSection", "TR": + "TableRow", "TH": "TableCell", "TD": "TableCell", "FRAMESET": + "FrameSet", "IFRAME": "IFrame" + }; + if (trans[tagName]) klass = 'HTML' + trans[tagName] + 'Element'; + if (window[klass]) return window[klass]; + klass = 'HTML' + tagName + 'Element'; + if (window[klass]) return window[klass]; + klass = 'HTML' + tagName.capitalize() + 'Element'; + if (window[klass]) return window[klass]; + + window[klass] = { }; + window[klass].prototype = document.createElement(tagName).__proto__; + return window[klass]; + } + + if (F.ElementExtensions) { + copy(Element.Methods, HTMLElement.prototype); + copy(Element.Methods.Simulated, HTMLElement.prototype, true); + } + + if (F.SpecificElementExtensions) { + for (var tag in Element.Methods.ByTag) { + var klass = findDOMClass(tag); + if (Object.isUndefined(klass)) continue; + copy(T[tag], klass.prototype); + } + } + + Object.extend(Element, Element.Methods); + delete Element.ByTag; + + if (Element.extend.refresh) Element.extend.refresh(); + Element.cache = { }; +}; + +document.viewport = { + getDimensions: function() { + var dimensions = { }; + $w('width height').each(function(d) { + var D = d.capitalize(); + dimensions[d] = self['inner' + D] || + (document.documentElement['client' + D] || document.body['client' + D]); + }); + return dimensions; + }, + + getWidth: function() { + return this.getDimensions().width; + }, + + getHeight: function() { + return this.getDimensions().height; + }, + + getScrollOffsets: function() { + return Element._returnOffset( + window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft, + window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop); + } +}; +/* Portions of the Selector class are derived from Jack Slocum’s DomQuery, + * part of YUI-Ext version 0.40, distributed under the terms of an MIT-style + * license. Please see http://www.yui-ext.com/ for more information. */ + +var Selector = Class.create({ + initialize: function(expression) { + this.expression = expression.strip(); + this.compileMatcher(); + }, + + compileMatcher: function() { + // Selectors with namespaced attributes can't use the XPath version + if (Prototype.BrowserFeatures.XPath && !(/\[[\w-]*?:/).test(this.expression)) + return this.compileXPathMatcher(); + + var e = this.expression, ps = Selector.patterns, h = Selector.handlers, + c = Selector.criteria, le, p, m; + + if (Selector._cache[e]) { + this.matcher = Selector._cache[e]; + return; + } + + this.matcher = ["this.matcher = function(root) {", + "var r = root, h = Selector.handlers, c = false, n;"]; + + while (e && le != e && (/\S/).test(e)) { + le = e; + for (var i in ps) { + p = ps[i]; + if (m = e.match(p)) { + this.matcher.push(Object.isFunction(c[i]) ? c[i](m) : + new Template(c[i]).evaluate(m)); + e = e.replace(m[0], ''); + break; + } + } + } + + this.matcher.push("return h.unique(n);\n}"); + eval(this.matcher.join('\n')); + Selector._cache[this.expression] = this.matcher; + }, + + compileXPathMatcher: function() { + var e = this.expression, ps = Selector.patterns, + x = Selector.xpath, le, m; + + if (Selector._cache[e]) { + this.xpath = Selector._cache[e]; return; + } + + this.matcher = ['.//*']; + while (e && le != e && (/\S/).test(e)) { + le = e; + for (var i in ps) { + if (m = e.match(ps[i])) { + this.matcher.push(Object.isFunction(x[i]) ? x[i](m) : + new Template(x[i]).evaluate(m)); + e = e.replace(m[0], ''); + break; + } + } + } + + this.xpath = this.matcher.join(''); + Selector._cache[this.expression] = this.xpath; + }, + + findElements: function(root) { + root = root || document; + if (this.xpath) return document._getElementsByXPath(this.xpath, root); + return this.matcher(root); + }, + + match: function(element) { + this.tokens = []; + + var e = this.expression, ps = Selector.patterns, as = Selector.assertions; + var le, p, m; + + while (e && le !== e && (/\S/).test(e)) { + le = e; + for (var i in ps) { + p = ps[i]; + if (m = e.match(p)) { + // use the Selector.assertions methods unless the selector + // is too complex. + if (as[i]) { + this.tokens.push([i, Object.clone(m)]); + e = e.replace(m[0], ''); + } else { + // reluctantly do a document-wide search + // and look for a match in the array + return this.findElements(document).include(element); + } + } + } + } + + var match = true, name, matches; + for (var i = 0, token; token = this.tokens[i]; i++) { + name = token[0], matches = token[1]; + if (!Selector.assertions[name](element, matches)) { + match = false; break; + } + } + + return match; + }, + + toString: function() { + return this.expression; + }, + + inspect: function() { + return "#"; + } +}); + +Object.extend(Selector, { + _cache: { }, + + xpath: { + descendant: "//*", + child: "/*", + adjacent: "/following-sibling::*[1]", + laterSibling: '/following-sibling::*', + tagName: function(m) { + if (m[1] == '*') return ''; + return "[local-name()='" + m[1].toLowerCase() + + "' or local-name()='" + m[1].toUpperCase() + "']"; + }, + className: "[contains(concat(' ', @class, ' '), ' #{1} ')]", + id: "[@id='#{1}']", + attrPresence: "[@#{1}]", + attr: function(m) { + m[3] = m[5] || m[6]; + return new Template(Selector.xpath.operators[m[2]]).evaluate(m); + }, + pseudo: function(m) { + var h = Selector.xpath.pseudos[m[1]]; + if (!h) return ''; + if (Object.isFunction(h)) return h(m); + return new Template(Selector.xpath.pseudos[m[1]]).evaluate(m); + }, + operators: { + '=': "[@#{1}='#{3}']", + '!=': "[@#{1}!='#{3}']", + '^=': "[starts-with(@#{1}, '#{3}')]", + '$=': "[substring(@#{1}, (string-length(@#{1}) - string-length('#{3}') + 1))='#{3}']", + '*=': "[contains(@#{1}, '#{3}')]", + '~=': "[contains(concat(' ', @#{1}, ' '), ' #{3} ')]", + '|=': "[contains(concat('-', @#{1}, '-'), '-#{3}-')]" + }, + pseudos: { + 'first-child': '[not(preceding-sibling::*)]', + 'last-child': '[not(following-sibling::*)]', + 'only-child': '[not(preceding-sibling::* or following-sibling::*)]', + 'empty': "[count(*) = 0 and (count(text()) = 0 or translate(text(), ' \t\r\n', '') = '')]", + 'checked': "[@checked]", + 'disabled': "[@disabled]", + 'enabled': "[not(@disabled)]", + 'not': function(m) { + var e = m[6], p = Selector.patterns, + x = Selector.xpath, le, m, v; + + var exclusion = []; + while (e && le != e && (/\S/).test(e)) { + le = e; + for (var i in p) { + if (m = e.match(p[i])) { + v = Object.isFunction(x[i]) ? x[i](m) : new Template(x[i]).evaluate(m); + exclusion.push("(" + v.substring(1, v.length - 1) + ")"); + e = e.replace(m[0], ''); + break; + } + } + } + return "[not(" + exclusion.join(" and ") + ")]"; + }, + 'nth-child': function(m) { + return Selector.xpath.pseudos.nth("(count(./preceding-sibling::*) + 1) ", m); + }, + 'nth-last-child': function(m) { + return Selector.xpath.pseudos.nth("(count(./following-sibling::*) + 1) ", m); + }, + 'nth-of-type': function(m) { + return Selector.xpath.pseudos.nth("position() ", m); + }, + 'nth-last-of-type': function(m) { + return Selector.xpath.pseudos.nth("(last() + 1 - position()) ", m); + }, + 'first-of-type': function(m) { + m[6] = "1"; return Selector.xpath.pseudos['nth-of-type'](m); + }, + 'last-of-type': function(m) { + m[6] = "1"; return Selector.xpath.pseudos['nth-last-of-type'](m); + }, + 'only-of-type': function(m) { + var p = Selector.xpath.pseudos; return p['first-of-type'](m) + p['last-of-type'](m); + }, + nth: function(fragment, m) { + var mm, formula = m[6], predicate; + if (formula == 'even') formula = '2n+0'; + if (formula == 'odd') formula = '2n+1'; + if (mm = formula.match(/^(\d+)$/)) // digit only + return '[' + fragment + "= " + mm[1] + ']'; + if (mm = formula.match(/^(-?\d*)?n(([+-])(\d+))?/)) { // an+b + if (mm[1] == "-") mm[1] = -1; + var a = mm[1] ? Number(mm[1]) : 1; + var b = mm[2] ? Number(mm[2]) : 0; + predicate = "[((#{fragment} - #{b}) mod #{a} = 0) and " + + "((#{fragment} - #{b}) div #{a} >= 0)]"; + return new Template(predicate).evaluate({ + fragment: fragment, a: a, b: b }); + } + } + } + }, + + criteria: { + tagName: 'n = h.tagName(n, r, "#{1}", c); c = false;', + className: 'n = h.className(n, r, "#{1}", c); c = false;', + id: 'n = h.id(n, r, "#{1}", c); c = false;', + attrPresence: 'n = h.attrPresence(n, r, "#{1}"); c = false;', + attr: function(m) { + m[3] = (m[5] || m[6]); + return new Template('n = h.attr(n, r, "#{1}", "#{3}", "#{2}"); c = false;').evaluate(m); + }, + pseudo: function(m) { + if (m[6]) m[6] = m[6].replace(/"/g, '\\"'); + return new Template('n = h.pseudo(n, "#{1}", "#{6}", r, c); c = false;').evaluate(m); + }, + descendant: 'c = "descendant";', + child: 'c = "child";', + adjacent: 'c = "adjacent";', + laterSibling: 'c = "laterSibling";' + }, + + patterns: { + // combinators must be listed first + // (and descendant needs to be last combinator) + laterSibling: /^\s*~\s*/, + child: /^\s*>\s*/, + adjacent: /^\s*\+\s*/, + descendant: /^\s/, + + // selectors follow + tagName: /^\s*(\*|[\w\-]+)(\b|$)?/, + id: /^#([\w\-\*]+)(\b|$)/, + className: /^\.([\w\-\*]+)(\b|$)/, + pseudo: /^:((first|last|nth|nth-last|only)(-child|-of-type)|empty|checked|(en|dis)abled|not)(\((.*?)\))?(\b|$|\s|(?=:))/, + attrPresence: /^\[([\w]+)\]/, + attr: /\[((?:[\w-]*:)?[\w-]+)\s*(?:([!^$*~|]?=)\s*((['"])([^\4]*?)\4|([^'"][^\]]*?)))?\]/ + }, + + // for Selector.match and Element#match + assertions: { + tagName: function(element, matches) { + return matches[1].toUpperCase() == element.tagName.toUpperCase(); + }, + + className: function(element, matches) { + return Element.hasClassName(element, matches[1]); + }, + + id: function(element, matches) { + return element.id === matches[1]; + }, + + attrPresence: function(element, matches) { + return Element.hasAttribute(element, matches[1]); + }, + + attr: function(element, matches) { + var nodeValue = Element.readAttribute(element, matches[1]); + return Selector.operators[matches[2]](nodeValue, matches[3]); + } + }, + + handlers: { + // UTILITY FUNCTIONS + // joins two collections + concat: function(a, b) { + for (var i = 0, node; node = b[i]; i++) + a.push(node); + return a; + }, + + // marks an array of nodes for counting + mark: function(nodes) { + for (var i = 0, node; node = nodes[i]; i++) + node._counted = true; + return nodes; + }, + + unmark: function(nodes) { + for (var i = 0, node; node = nodes[i]; i++) + node._counted = undefined; + return nodes; + }, + + // mark each child node with its position (for nth calls) + // "ofType" flag indicates whether we're indexing for nth-of-type + // rather than nth-child + index: function(parentNode, reverse, ofType) { + parentNode._counted = true; + if (reverse) { + for (var nodes = parentNode.childNodes, i = nodes.length - 1, j = 1; i >= 0; i--) { + var node = nodes[i]; + if (node.nodeType == 1 && (!ofType || node._counted)) node.nodeIndex = j++; + } + } else { + for (var i = 0, j = 1, nodes = parentNode.childNodes; node = nodes[i]; i++) + if (node.nodeType == 1 && (!ofType || node._counted)) node.nodeIndex = j++; + } + }, + + // filters out duplicates and extends all nodes + unique: function(nodes) { + if (nodes.length == 0) return nodes; + var results = [], n; + for (var i = 0, l = nodes.length; i < l; i++) + if (!(n = nodes[i])._counted) { + n._counted = true; + results.push(Element.extend(n)); + } + return Selector.handlers.unmark(results); + }, + + // COMBINATOR FUNCTIONS + descendant: function(nodes) { + var h = Selector.handlers; + for (var i = 0, results = [], node; node = nodes[i]; i++) + h.concat(results, node.getElementsByTagName('*')); + return results; + }, + + child: function(nodes) { + var h = Selector.handlers; + for (var i = 0, results = [], node; node = nodes[i]; i++) { + for (var j = 0, children = [], child; child = node.childNodes[j]; j++) + if (child.nodeType == 1 && child.tagName != '!') results.push(child); + } + return results; + }, + + adjacent: function(nodes) { + for (var i = 0, results = [], node; node = nodes[i]; i++) { + var next = this.nextElementSibling(node); + if (next) results.push(next); + } + return results; + }, + + laterSibling: function(nodes) { + var h = Selector.handlers; + for (var i = 0, results = [], node; node = nodes[i]; i++) + h.concat(results, Element.nextSiblings(node)); + return results; + }, + + nextElementSibling: function(node) { + while (node = node.nextSibling) + if (node.nodeType == 1) return node; + return null; + }, + + previousElementSibling: function(node) { + while (node = node.previousSibling) + if (node.nodeType == 1) return node; + return null; + }, + + // TOKEN FUNCTIONS + tagName: function(nodes, root, tagName, combinator) { + tagName = tagName.toUpperCase(); + var results = [], h = Selector.handlers; + if (nodes) { + if (combinator) { + // fastlane for ordinary descendant combinators + if (combinator == "descendant") { + for (var i = 0, node; node = nodes[i]; i++) + h.concat(results, node.getElementsByTagName(tagName)); + return results; + } else nodes = this[combinator](nodes); + if (tagName == "*") return nodes; + } + for (var i = 0, node; node = nodes[i]; i++) + if (node.tagName.toUpperCase() == tagName) results.push(node); + return results; + } else return root.getElementsByTagName(tagName); + }, + + id: function(nodes, root, id, combinator) { + var targetNode = $(id), h = Selector.handlers; + if (!targetNode) return []; + if (!nodes && root == document) return [targetNode]; + if (nodes) { + if (combinator) { + if (combinator == 'child') { + for (var i = 0, node; node = nodes[i]; i++) + if (targetNode.parentNode == node) return [targetNode]; + } else if (combinator == 'descendant') { + for (var i = 0, node; node = nodes[i]; i++) + if (Element.descendantOf(targetNode, node)) return [targetNode]; + } else if (combinator == 'adjacent') { + for (var i = 0, node; node = nodes[i]; i++) + if (Selector.handlers.previousElementSibling(targetNode) == node) + return [targetNode]; + } else nodes = h[combinator](nodes); + } + for (var i = 0, node; node = nodes[i]; i++) + if (node == targetNode) return [targetNode]; + return []; + } + return (targetNode && Element.descendantOf(targetNode, root)) ? [targetNode] : []; + }, + + className: function(nodes, root, className, combinator) { + if (nodes && combinator) nodes = this[combinator](nodes); + return Selector.handlers.byClassName(nodes, root, className); + }, + + byClassName: function(nodes, root, className) { + if (!nodes) nodes = Selector.handlers.descendant([root]); + var needle = ' ' + className + ' '; + for (var i = 0, results = [], node, nodeClassName; node = nodes[i]; i++) { + nodeClassName = node.className; + if (nodeClassName.length == 0) continue; + if (nodeClassName == className || (' ' + nodeClassName + ' ').include(needle)) + results.push(node); + } + return results; + }, + + attrPresence: function(nodes, root, attr) { + var results = []; + for (var i = 0, node; node = nodes[i]; i++) + if (Element.hasAttribute(node, attr)) results.push(node); + return results; + }, + + attr: function(nodes, root, attr, value, operator) { + if (!nodes) nodes = root.getElementsByTagName("*"); + var handler = Selector.operators[operator], results = []; + for (var i = 0, node; node = nodes[i]; i++) { + var nodeValue = Element.readAttribute(node, attr); + if (nodeValue === null) continue; + if (handler(nodeValue, value)) results.push(node); + } + return results; + }, + + pseudo: function(nodes, name, value, root, combinator) { + if (nodes && combinator) nodes = this[combinator](nodes); + if (!nodes) nodes = root.getElementsByTagName("*"); + return Selector.pseudos[name](nodes, value, root); + } + }, + + pseudos: { + 'first-child': function(nodes, value, root) { + for (var i = 0, results = [], node; node = nodes[i]; i++) { + if (Selector.handlers.previousElementSibling(node)) continue; + results.push(node); + } + return results; + }, + 'last-child': function(nodes, value, root) { + for (var i = 0, results = [], node; node = nodes[i]; i++) { + if (Selector.handlers.nextElementSibling(node)) continue; + results.push(node); + } + return results; + }, + 'only-child': function(nodes, value, root) { + var h = Selector.handlers; + for (var i = 0, results = [], node; node = nodes[i]; i++) + if (!h.previousElementSibling(node) && !h.nextElementSibling(node)) + results.push(node); + return results; + }, + 'nth-child': function(nodes, formula, root) { + return Selector.pseudos.nth(nodes, formula, root); + }, + 'nth-last-child': function(nodes, formula, root) { + return Selector.pseudos.nth(nodes, formula, root, true); + }, + 'nth-of-type': function(nodes, formula, root) { + return Selector.pseudos.nth(nodes, formula, root, false, true); + }, + 'nth-last-of-type': function(nodes, formula, root) { + return Selector.pseudos.nth(nodes, formula, root, true, true); + }, + 'first-of-type': function(nodes, formula, root) { + return Selector.pseudos.nth(nodes, "1", root, false, true); + }, + 'last-of-type': function(nodes, formula, root) { + return Selector.pseudos.nth(nodes, "1", root, true, true); + }, + 'only-of-type': function(nodes, formula, root) { + var p = Selector.pseudos; + return p['last-of-type'](p['first-of-type'](nodes, formula, root), formula, root); + }, + + // handles the an+b logic + getIndices: function(a, b, total) { + if (a == 0) return b > 0 ? [b] : []; + return $R(1, total).inject([], function(memo, i) { + if (0 == (i - b) % a && (i - b) / a >= 0) memo.push(i); + return memo; + }); + }, + + // handles nth(-last)-child, nth(-last)-of-type, and (first|last)-of-type + nth: function(nodes, formula, root, reverse, ofType) { + if (nodes.length == 0) return []; + if (formula == 'even') formula = '2n+0'; + if (formula == 'odd') formula = '2n+1'; + var h = Selector.handlers, results = [], indexed = [], m; + h.mark(nodes); + for (var i = 0, node; node = nodes[i]; i++) { + if (!node.parentNode._counted) { + h.index(node.parentNode, reverse, ofType); + indexed.push(node.parentNode); + } + } + if (formula.match(/^\d+$/)) { // just a number + formula = Number(formula); + for (var i = 0, node; node = nodes[i]; i++) + if (node.nodeIndex == formula) results.push(node); + } else if (m = formula.match(/^(-?\d*)?n(([+-])(\d+))?/)) { // an+b + if (m[1] == "-") m[1] = -1; + var a = m[1] ? Number(m[1]) : 1; + var b = m[2] ? Number(m[2]) : 0; + var indices = Selector.pseudos.getIndices(a, b, nodes.length); + for (var i = 0, node, l = indices.length; node = nodes[i]; i++) { + for (var j = 0; j < l; j++) + if (node.nodeIndex == indices[j]) results.push(node); + } + } + h.unmark(nodes); + h.unmark(indexed); + return results; + }, + + 'empty': function(nodes, value, root) { + for (var i = 0, results = [], node; node = nodes[i]; i++) { + // IE treats comments as element nodes + if (node.tagName == '!' || (node.firstChild && !node.innerHTML.match(/^\s*$/))) continue; + results.push(node); + } + return results; + }, + + 'not': function(nodes, selector, root) { + var h = Selector.handlers, selectorType, m; + var exclusions = new Selector(selector).findElements(root); + h.mark(exclusions); + for (var i = 0, results = [], node; node = nodes[i]; i++) + if (!node._counted) results.push(node); + h.unmark(exclusions); + return results; + }, + + 'enabled': function(nodes, value, root) { + for (var i = 0, results = [], node; node = nodes[i]; i++) + if (!node.disabled) results.push(node); + return results; + }, + + 'disabled': function(nodes, value, root) { + for (var i = 0, results = [], node; node = nodes[i]; i++) + if (node.disabled) results.push(node); + return results; + }, + + 'checked': function(nodes, value, root) { + for (var i = 0, results = [], node; node = nodes[i]; i++) + if (node.checked) results.push(node); + return results; + } + }, + + operators: { + '=': function(nv, v) { return nv == v; }, + '!=': function(nv, v) { return nv != v; }, + '^=': function(nv, v) { return nv.startsWith(v); }, + '$=': function(nv, v) { return nv.endsWith(v); }, + '*=': function(nv, v) { return nv.include(v); }, + '~=': function(nv, v) { return (' ' + nv + ' ').include(' ' + v + ' '); }, + '|=': function(nv, v) { return ('-' + nv.toUpperCase() + '-').include('-' + v.toUpperCase() + '-'); } + }, + + matchElements: function(elements, expression) { + var matches = new Selector(expression).findElements(), h = Selector.handlers; + h.mark(matches); + for (var i = 0, results = [], element; element = elements[i]; i++) + if (element._counted) results.push(element); + h.unmark(matches); + return results; + }, + + findElement: function(elements, expression, index) { + if (Object.isNumber(expression)) { + index = expression; expression = false; + } + return Selector.matchElements(elements, expression || '*')[index || 0]; + }, + + findChildElements: function(element, expressions) { + var exprs = expressions.join(','), expressions = []; + exprs.scan(/(([\w#:.~>+()\s-]+|\*|\[.*?\])+)\s*(,|$)/, function(m) { + expressions.push(m[1].strip()); + }); + var results = [], h = Selector.handlers; + for (var i = 0, l = expressions.length, selector; i < l; i++) { + selector = new Selector(expressions[i].strip()); + h.concat(results, selector.findElements(element)); + } + return (l > 1) ? h.unique(results) : results; + } +}); + +function $$() { + return Selector.findChildElements(document, $A(arguments)); +} +var Form = { + reset: function(form) { + $(form).reset(); + return form; + }, + + serializeElements: function(elements, options) { + if (typeof options != 'object') options = { hash: !!options }; + else if (options.hash === undefined) options.hash = true; + var key, value, submitted = false, submit = options.submit; + + var data = elements.inject({ }, function(result, element) { + if (!element.disabled && element.name) { + key = element.name; value = $(element).getValue(); + if (value != null && (element.type != 'submit' || (!submitted && + submit !== false && (!submit || key == submit) && (submitted = true)))) { + if (key in result) { + // a key is already present; construct an array of values + if (!Object.isArray(result[key])) result[key] = [result[key]]; + result[key].push(value); + } + else result[key] = value; + } + } + return result; + }); + + return options.hash ? data : Hash.toQueryString(data); + } +}; + +Form.Methods = { + serialize: function(form, options) { + return Form.serializeElements(Form.getElements(form), options); + }, + + getElements: function(form) { + return $A($(form).getElementsByTagName('*')).inject([], + function(elements, child) { + if (Form.Element.Serializers[child.tagName.toLowerCase()]) + elements.push(Element.extend(child)); + return elements; + } + ); + }, + + getInputs: function(form, typeName, name) { + form = $(form); + var inputs = form.getElementsByTagName('input'); + + if (!typeName && !name) return $A(inputs).map(Element.extend); + + for (var i = 0, matchingInputs = [], length = inputs.length; i < length; i++) { + var input = inputs[i]; + if ((typeName && input.type != typeName) || (name && input.name != name)) + continue; + matchingInputs.push(Element.extend(input)); + } + + return matchingInputs; + }, + + disable: function(form) { + form = $(form); + Form.getElements(form).invoke('disable'); + return form; + }, + + enable: function(form) { + form = $(form); + Form.getElements(form).invoke('enable'); + return form; + }, + + findFirstElement: function(form) { + var elements = $(form).getElements().findAll(function(element) { + return 'hidden' != element.type && !element.disabled; + }); + var firstByIndex = elements.findAll(function(element) { + return element.hasAttribute('tabIndex') && element.tabIndex >= 0; + }).sortBy(function(element) { return element.tabIndex }).first(); + + return firstByIndex ? firstByIndex : elements.find(function(element) { + return ['input', 'select', 'textarea'].include(element.tagName.toLowerCase()); + }); + }, + + focusFirstElement: function(form) { + form = $(form); + form.findFirstElement().activate(); + return form; + }, + + request: function(form, options) { + form = $(form), options = Object.clone(options || { }); + + var params = options.parameters, action = form.readAttribute('action') || ''; + if (action.blank()) action = window.location.href; + options.parameters = form.serialize(true); + + if (params) { + if (Object.isString(params)) params = params.toQueryParams(); + Object.extend(options.parameters, params); + } + + if (form.hasAttribute('method') && !options.method) + options.method = form.method; + + return new Ajax.Request(action, options); + } +}; + +/*--------------------------------------------------------------------------*/ + +Form.Element = { + focus: function(element) { + $(element).focus(); + return element; + }, + + select: function(element) { + $(element).select(); + return element; + } +}; + +Form.Element.Methods = { + serialize: function(element) { + element = $(element); + if (!element.disabled && element.name) { + var value = element.getValue(); + if (value != undefined) { + var pair = { }; + pair[element.name] = value; + return Hash.toQueryString(pair); + } + } + return ''; + }, + + getValue: function(element) { + element = $(element); + var method = element.tagName.toLowerCase(); + return Form.Element.Serializers[method](element); + }, + + setValue: function(element, value) { + element = $(element); + var method = element.tagName.toLowerCase(); + Form.Element.Serializers[method](element, value); + return element; + }, + + clear: function(element) { + $(element).value = ''; + return element; + }, + + present: function(element) { + return $(element).value != ''; + }, + + activate: function(element) { + element = $(element); + try { + element.focus(); + if (element.select && (element.tagName.toLowerCase() != 'input' || + !['button', 'reset', 'submit'].include(element.type))) + element.select(); + } catch (e) { } + return element; + }, + + disable: function(element) { + element = $(element); + element.blur(); + element.disabled = true; + return element; + }, + + enable: function(element) { + element = $(element); + element.disabled = false; + return element; + } +}; + +/*--------------------------------------------------------------------------*/ + +var Field = Form.Element; +var $F = Form.Element.Methods.getValue; + +/*--------------------------------------------------------------------------*/ + +Form.Element.Serializers = { + input: function(element, value) { + switch (element.type.toLowerCase()) { + case 'checkbox': + case 'radio': + return Form.Element.Serializers.inputSelector(element, value); + default: + return Form.Element.Serializers.textarea(element, value); + } + }, + + inputSelector: function(element, value) { + if (value === undefined) return element.checked ? element.value : null; + else element.checked = !!value; + }, + + textarea: function(element, value) { + if (value === undefined) return element.value; + else element.value = value; + }, + + select: function(element, index) { + if (index === undefined) + return this[element.type == 'select-one' ? + 'selectOne' : 'selectMany'](element); + else { + var opt, value, single = !Object.isArray(index); + for (var i = 0, length = element.length; i < length; i++) { + opt = element.options[i]; + value = this.optionValue(opt); + if (single) { + if (value == index) { + opt.selected = true; + return; + } + } + else opt.selected = index.include(value); + } + } + }, + + selectOne: function(element) { + var index = element.selectedIndex; + return index >= 0 ? this.optionValue(element.options[index]) : null; + }, + + selectMany: function(element) { + var values, length = element.length; + if (!length) return null; + + for (var i = 0, values = []; i < length; i++) { + var opt = element.options[i]; + if (opt.selected) values.push(this.optionValue(opt)); + } + return values; + }, + + optionValue: function(opt) { + // extend element because hasAttribute may not be native + return Element.extend(opt).hasAttribute('value') ? opt.value : opt.text; + } +}; + +/*--------------------------------------------------------------------------*/ + +Abstract.TimedObserver = Class.create(PeriodicalExecuter, { + initialize: function($super, element, frequency, callback) { + $super(callback, frequency); + this.element = $(element); + this.lastValue = this.getValue(); + }, + + execute: function() { + var value = this.getValue(); + if (Object.isString(this.lastValue) && Object.isString(value) ? + this.lastValue != value : String(this.lastValue) != String(value)) { + this.callback(this.element, value); + this.lastValue = value; + } + } +}); + +Form.Element.Observer = Class.create(Abstract.TimedObserver, { + getValue: function() { + return Form.Element.getValue(this.element); + } +}); + +Form.Observer = Class.create(Abstract.TimedObserver, { + getValue: function() { + return Form.serialize(this.element); + } +}); + +/*--------------------------------------------------------------------------*/ + +Abstract.EventObserver = Class.create({ + initialize: function(element, callback) { + this.element = $(element); + this.callback = callback; + + this.lastValue = this.getValue(); + if (this.element.tagName.toLowerCase() == 'form') + this.registerFormCallbacks(); + else + this.registerCallback(this.element); + }, + + onElementEvent: function() { + var value = this.getValue(); + if (this.lastValue != value) { + this.callback(this.element, value); + this.lastValue = value; + } + }, + + registerFormCallbacks: function() { + Form.getElements(this.element).each(this.registerCallback, this); + }, + + registerCallback: function(element) { + if (element.type) { + switch (element.type.toLowerCase()) { + case 'checkbox': + case 'radio': + Event.observe(element, 'click', this.onElementEvent.bind(this)); + break; + default: + Event.observe(element, 'change', this.onElementEvent.bind(this)); + break; + } + } + } +}); + +Form.Element.EventObserver = Class.create(Abstract.EventObserver, { + getValue: function() { + return Form.Element.getValue(this.element); + } +}); + +Form.EventObserver = Class.create(Abstract.EventObserver, { + getValue: function() { + return Form.serialize(this.element); + } +}); +if (!window.Event) var Event = { }; + +Object.extend(Event, { + KEY_BACKSPACE: 8, + KEY_TAB: 9, + KEY_RETURN: 13, + KEY_ESC: 27, + KEY_LEFT: 37, + KEY_UP: 38, + KEY_RIGHT: 39, + KEY_DOWN: 40, + KEY_DELETE: 46, + KEY_HOME: 36, + KEY_END: 35, + KEY_PAGEUP: 33, + KEY_PAGEDOWN: 34, + KEY_INSERT: 45, + + cache: { }, + + relatedTarget: function(event) { + var element; + switch(event.type) { + case 'mouseover': element = event.fromElement; break; + case 'mouseout': element = event.toElement; break; + default: return null; + } + return Element.extend(element); + } +}); + +Event.Methods = { + element: function(event) { + var node = event.target; + return Element.extend(node.nodeType == Node.TEXT_NODE ? node.parentNode : node); + }, + + findElement: function(event, expression) { + var element = Event.element(event); + return element.match(expression) ? element : element.up(expression); + }, + + isLeftClick: function(event) { + return (((event.which) && (event.which == 1)) || + ((event.button) && (event.button == 1))); + }, + + pointer: function(event) { + return { + x: event.pageX || (event.clientX + + (document.documentElement.scrollLeft || document.body.scrollLeft)), + y: event.pageY || (event.clientY + + (document.documentElement.scrollTop || document.body.scrollTop)) + }; + }, + + pointerX: function(event) { return Event.pointer(event).x }, + pointerY: function(event) { return Event.pointer(event).y }, + + stop: function(event) { + event.preventDefault(); + event.stopPropagation(); + } +}; + +Event.extend = (function() { + var methods = Object.keys(Event.Methods).inject({ }, function(m, name) { + m[name] = Event.Methods[name].methodize(); + return m; + }); + + if (Prototype.Browser.IE) { + Object.extend(methods, { + stopPropagation: function() { this.cancelBubble = true }, + preventDefault: function() { this.returnValue = false }, + inspect: function() { return "[object Event]" } + }); + + return function(event) { + if (!event) return false; + if (event._extendedByPrototype) return event; + + event._extendedByPrototype = Prototype.emptyFunction; + var pointer = Event.pointer(event); + Object.extend(event, { + target: event.srcElement, + relatedTarget: Event.relatedTarget(event), + pageX: pointer.x, + pageY: pointer.y + }); + return Object.extend(event, methods); + }; + + } else { + Event.prototype = Event.prototype || document.createEvent("HTMLEvents").__proto__; + Object.extend(Event.prototype, methods); + return Prototype.K; + } +})(); + +Object.extend(Event, (function() { + var cache = Event.cache; + + function getEventID(element) { + if (element._eventID) return element._eventID; + arguments.callee.id = arguments.callee.id || 1; + return element._eventID = ++arguments.callee.id; + } + + function getDOMEventName(eventName) { + if (eventName && eventName.match(/:/)) return "dataavailable"; + return { keypress: "keydown" }[eventName] || eventName; + } + + function getCacheForID(id) { + return cache[id] = cache[id] || { }; + } + + function getWrappersForEventName(id, eventName) { + var c = getCacheForID(id); + return c[eventName] = c[eventName] || []; + } + + function createWrapper(element, eventName, handler) { + var id = getEventID(element); + var c = getWrappersForEventName(id, eventName); + if (c.pluck("handler").include(handler)) return false; + + var wrapper = function(event) { + if (event.eventName && event.eventName != eventName) + return false; + + Event.extend(event); + handler.call(element, event) + }; + + wrapper.handler = handler; + c.push(wrapper); + return wrapper; + } + + function findWrapper(id, eventName, handler) { + var c = getWrappersForEventName(id, eventName); + return c.find(function(wrapper) { return wrapper.handler == handler }); + } + + function destroyWrapper(id, eventName, handler) { + var c = getCacheForID(id); + if (!c[eventName]) return false; + c[eventName] = c[eventName].without(findWrapper(id, eventName, handler)); + } + + function destroyCache() { + for (var id in cache) + for (var eventName in cache[id]) + cache[id][eventName] = null; + } + + if (window.attachEvent) { + window.attachEvent("onunload", destroyCache); + } + + return { + observe: function(element, eventName, handler) { + element = $(element); + var name = getDOMEventName(eventName); + + var wrapper = createWrapper(element, eventName, handler); + if (!wrapper) return element; + + if (element.addEventListener) { + element.addEventListener(name, wrapper, false); + } else { + element.attachEvent("on" + name, wrapper); + } + + return element; + }, + + stopObserving: function(element, eventName, handler) { + element = $(element); + var id = getEventID(element), name = getDOMEventName(eventName); + + if (!handler && eventName) { + getWrappersForEventName(id, eventName).each(function(wrapper) { + element.stopObserving(eventName, wrapper.handler); + }); + return element; + + } else if (!eventName) { + Object.keys(getCacheForID(id)).each(function(eventName) { + element.stopObserving(eventName); + }); + return element; + } + + var wrapper = findWrapper(id, eventName, handler); + if (!wrapper) return element; + + if (element.removeEventListener) { + element.removeEventListener(name, wrapper, false); + } else { + element.detachEvent("on" + name, wrapper); + } + + destroyWrapper(id, eventName, handler); + + return element; + }, + + fire: function(element, eventName, memo) { + element = $(element); + if (element == document && document.createEvent && !element.dispatchEvent) + element = document.documentElement; + + if (document.createEvent) { + var event = document.createEvent("HTMLEvents"); + event.initEvent("dataavailable", true, true); + } else { + var event = document.createEventObject(); + event.eventType = "ondataavailable"; + } + + event.eventName = eventName; + event.memo = memo || { }; + + if (document.createEvent) { + element.dispatchEvent(event); + } else { + element.fireEvent(event.eventType, event); + } + + return event; + } + }; +})()); + +Object.extend(Event, Event.Methods); + +Element.addMethods({ + fire: Event.fire, + observe: Event.observe, + stopObserving: Event.stopObserving +}); + +Object.extend(document, { + fire: Element.Methods.fire.methodize(), + observe: Element.Methods.observe.methodize(), + stopObserving: Element.Methods.stopObserving.methodize() +}); + +(function() { + /* Support for the DOMContentLoaded event is based on work by Dan Webb, + Matthias Miller, Dean Edwards and John Resig. */ + + var timer, fired = false; + + function fireContentLoadedEvent() { + if (fired) return; + if (timer) window.clearInterval(timer); + document.fire("dom:loaded"); + fired = true; + } + + if (document.addEventListener) { + if (Prototype.Browser.WebKit) { + timer = window.setInterval(function() { + if (/loaded|complete/.test(document.readyState)) + fireContentLoadedEvent(); + }, 0); + + Event.observe(window, "load", fireContentLoadedEvent); + + } else { + document.addEventListener("DOMContentLoaded", + fireContentLoadedEvent, false); + } + + } else { + document.write("'); + }, + REQUIRED_PROTOTYPE: '1.6.0', + load: function() { + function convertVersionString(versionString){ + var r = versionString.split('.'); + return parseInt(r[0])*100000 + parseInt(r[1])*1000 + parseInt(r[2]); + } + + if((typeof Prototype=='undefined') || + (typeof Element == 'undefined') || + (typeof Element.Methods=='undefined') || + (convertVersionString(Prototype.Version) < + convertVersionString(Scriptaculous.REQUIRED_PROTOTYPE))) + throw("script.aculo.us requires the Prototype JavaScript framework >= " + + Scriptaculous.REQUIRED_PROTOTYPE); + + $A(document.getElementsByTagName("script")).findAll( function(s) { + return (s.src && s.src.match(/scriptaculous\.js(\?.*)?$/)) + }).each( function(s) { + var path = s.src.replace(/scriptaculous\.js(\?.*)?$/,''); + var includes = s.src.match(/\?.*load=([a-z,]*)/); + (includes ? includes[1] : 'builder,effects,dragdrop,controls,slider,sound').split(',').each( + function(include) { Scriptaculous.require(path+include+'.js') }); + }); + } +} + +Scriptaculous.load(); \ No newline at end of file diff -Nur mephisto-0.7.3/vendor/plugins/rspec/story_server/prototype/javascripts/slider.js technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/story_server/prototype/javascripts/slider.js --- mephisto-0.7.3/vendor/plugins/rspec/story_server/prototype/javascripts/slider.js 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/story_server/prototype/javascripts/slider.js 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,276 @@ +// script.aculo.us slider.js v1.8.0_pre1, Fri Oct 12 21:34:51 +0200 2007 + +// Copyright (c) 2005-2007 Marty Haught, Thomas Fuchs +// +// script.aculo.us is freely distributable under the terms of an MIT-style license. +// For details, see the script.aculo.us web site: http://script.aculo.us/ + +if (!Control) var Control = { }; +Control.Slider = Class.create(); + +// options: +// axis: 'vertical', or 'horizontal' (default) +// +// callbacks: +// onChange(value) +// onSlide(value) +Control.Slider.prototype = { + initialize: function(handle, track, options) { + var slider = this; + + if (Object.isArray(handle)) { + this.handles = handle.collect( function(e) { return $(e) }); + } else { + this.handles = [$(handle)]; + } + + this.track = $(track); + this.options = options || { }; + + this.axis = this.options.axis || 'horizontal'; + this.increment = this.options.increment || 1; + this.step = parseInt(this.options.step || '1'); + this.range = this.options.range || $R(0,1); + + this.value = 0; // assure backwards compat + this.values = this.handles.map( function() { return 0 }); + this.spans = this.options.spans ? this.options.spans.map(function(s){ return $(s) }) : false; + this.options.startSpan = $(this.options.startSpan || null); + this.options.endSpan = $(this.options.endSpan || null); + + this.restricted = this.options.restricted || false; + + this.maximum = this.options.maximum || this.range.end; + this.minimum = this.options.minimum || this.range.start; + + // Will be used to align the handle onto the track, if necessary + this.alignX = parseInt(this.options.alignX || '0'); + this.alignY = parseInt(this.options.alignY || '0'); + + this.trackLength = this.maximumOffset() - this.minimumOffset(); + + this.handleLength = this.isVertical() ? + (this.handles[0].offsetHeight != 0 ? + this.handles[0].offsetHeight : this.handles[0].style.height.replace(/px$/,"")) : + (this.handles[0].offsetWidth != 0 ? this.handles[0].offsetWidth : + this.handles[0].style.width.replace(/px$/,"")); + + this.active = false; + this.dragging = false; + this.disabled = false; + + if (this.options.disabled) this.setDisabled(); + + // Allowed values array + this.allowedValues = this.options.values ? this.options.values.sortBy(Prototype.K) : false; + if (this.allowedValues) { + this.minimum = this.allowedValues.min(); + this.maximum = this.allowedValues.max(); + } + + this.eventMouseDown = this.startDrag.bindAsEventListener(this); + this.eventMouseUp = this.endDrag.bindAsEventListener(this); + this.eventMouseMove = this.update.bindAsEventListener(this); + + // Initialize handles in reverse (make sure first handle is active) + this.handles.each( function(h,i) { + i = slider.handles.length-1-i; + slider.setValue(parseFloat( + (Object.isArray(slider.options.sliderValue) ? + slider.options.sliderValue[i] : slider.options.sliderValue) || + slider.range.start), i); + h.makePositioned().observe("mousedown", slider.eventMouseDown); + }); + + this.track.observe("mousedown", this.eventMouseDown); + document.observe("mouseup", this.eventMouseUp); + document.observe("mousemove", this.eventMouseMove); + + this.initialized = true; + }, + dispose: function() { + var slider = this; + Event.stopObserving(this.track, "mousedown", this.eventMouseDown); + Event.stopObserving(document, "mouseup", this.eventMouseUp); + Event.stopObserving(document, "mousemove", this.eventMouseMove); + this.handles.each( function(h) { + Event.stopObserving(h, "mousedown", slider.eventMouseDown); + }); + }, + setDisabled: function(){ + this.disabled = true; + }, + setEnabled: function(){ + this.disabled = false; + }, + getNearestValue: function(value){ + if (this.allowedValues){ + if (value >= this.allowedValues.max()) return(this.allowedValues.max()); + if (value <= this.allowedValues.min()) return(this.allowedValues.min()); + + var offset = Math.abs(this.allowedValues[0] - value); + var newValue = this.allowedValues[0]; + this.allowedValues.each( function(v) { + var currentOffset = Math.abs(v - value); + if (currentOffset <= offset){ + newValue = v; + offset = currentOffset; + } + }); + return newValue; + } + if (value > this.range.end) return this.range.end; + if (value < this.range.start) return this.range.start; + return value; + }, + setValue: function(sliderValue, handleIdx){ + if (!this.active) { + this.activeHandleIdx = handleIdx || 0; + this.activeHandle = this.handles[this.activeHandleIdx]; + this.updateStyles(); + } + handleIdx = handleIdx || this.activeHandleIdx || 0; + if (this.initialized && this.restricted) { + if ((handleIdx>0) && (sliderValuethis.values[handleIdx+1])) + sliderValue = this.values[handleIdx+1]; + } + sliderValue = this.getNearestValue(sliderValue); + this.values[handleIdx] = sliderValue; + this.value = this.values[0]; // assure backwards compat + + this.handles[handleIdx].style[this.isVertical() ? 'top' : 'left'] = + this.translateToPx(sliderValue); + + this.drawSpans(); + if (!this.dragging || !this.event) this.updateFinished(); + }, + setValueBy: function(delta, handleIdx) { + this.setValue(this.values[handleIdx || this.activeHandleIdx || 0] + delta, + handleIdx || this.activeHandleIdx || 0); + }, + translateToPx: function(value) { + return Math.round( + ((this.trackLength-this.handleLength)/(this.range.end-this.range.start)) * + (value - this.range.start)) + "px"; + }, + translateToValue: function(offset) { + return ((offset/(this.trackLength-this.handleLength) * + (this.range.end-this.range.start)) + this.range.start); + }, + getRange: function(range) { + var v = this.values.sortBy(Prototype.K); + range = range || 0; + return $R(v[range],v[range+1]); + }, + minimumOffset: function(){ + return(this.isVertical() ? this.alignY : this.alignX); + }, + maximumOffset: function(){ + return(this.isVertical() ? + (this.track.offsetHeight != 0 ? this.track.offsetHeight : + this.track.style.height.replace(/px$/,"")) - this.alignY : + (this.track.offsetWidth != 0 ? this.track.offsetWidth : + this.track.style.width.replace(/px$/,"")) - this.alignY); + }, + isVertical: function(){ + return (this.axis == 'vertical'); + }, + drawSpans: function() { + var slider = this; + if (this.spans) + $R(0, this.spans.length-1).each(function(r) { slider.setSpan(slider.spans[r], slider.getRange(r)) }); + if (this.options.startSpan) + this.setSpan(this.options.startSpan, + $R(0, this.values.length>1 ? this.getRange(0).min() : this.value )); + if (this.options.endSpan) + this.setSpan(this.options.endSpan, + $R(this.values.length>1 ? this.getRange(this.spans.length-1).max() : this.value, this.maximum)); + }, + setSpan: function(span, range) { + if (this.isVertical()) { + span.style.top = this.translateToPx(range.start); + span.style.height = this.translateToPx(range.end - range.start + this.range.start); + } else { + span.style.left = this.translateToPx(range.start); + span.style.width = this.translateToPx(range.end - range.start + this.range.start); + } + }, + updateStyles: function() { + this.handles.each( function(h){ Element.removeClassName(h, 'selected') }); + Element.addClassName(this.activeHandle, 'selected'); + }, + startDrag: function(event) { + if (Event.isLeftClick(event)) { + if (!this.disabled){ + this.active = true; + + var handle = Event.element(event); + var pointer = [Event.pointerX(event), Event.pointerY(event)]; + var track = handle; + if (track==this.track) { + var offsets = Position.cumulativeOffset(this.track); + this.event = event; + this.setValue(this.translateToValue( + (this.isVertical() ? pointer[1]-offsets[1] : pointer[0]-offsets[0])-(this.handleLength/2) + )); + var offsets = Position.cumulativeOffset(this.activeHandle); + this.offsetX = (pointer[0] - offsets[0]); + this.offsetY = (pointer[1] - offsets[1]); + } else { + // find the handle (prevents issues with Safari) + while((this.handles.indexOf(handle) == -1) && handle.parentNode) + handle = handle.parentNode; + + if (this.handles.indexOf(handle)!=-1) { + this.activeHandle = handle; + this.activeHandleIdx = this.handles.indexOf(this.activeHandle); + this.updateStyles(); + + var offsets = Position.cumulativeOffset(this.activeHandle); + this.offsetX = (pointer[0] - offsets[0]); + this.offsetY = (pointer[1] - offsets[1]); + } + } + } + Event.stop(event); + } + }, + update: function(event) { + if (this.active) { + if (!this.dragging) this.dragging = true; + this.draw(event); + if (Prototype.Browser.WebKit) window.scrollBy(0,0); + Event.stop(event); + } + }, + draw: function(event) { + var pointer = [Event.pointerX(event), Event.pointerY(event)]; + var offsets = Position.cumulativeOffset(this.track); + pointer[0] -= this.offsetX + offsets[0]; + pointer[1] -= this.offsetY + offsets[1]; + this.event = event; + this.setValue(this.translateToValue( this.isVertical() ? pointer[1] : pointer[0] )); + if (this.initialized && this.options.onSlide) + this.options.onSlide(this.values.length>1 ? this.values : this.value, this); + }, + endDrag: function(event) { + if (this.active && this.dragging) { + this.finishDrag(event, true); + Event.stop(event); + } + this.active = false; + this.dragging = false; + }, + finishDrag: function(event, success) { + this.active = false; + this.dragging = false; + this.updateFinished(); + }, + updateFinished: function() { + if (this.initialized && this.options.onChange) + this.options.onChange(this.values.length>1 ? this.values : this.value, this); + this.event = null; + } +} \ No newline at end of file diff -Nur mephisto-0.7.3/vendor/plugins/rspec/story_server/prototype/javascripts/sound.js technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/story_server/prototype/javascripts/sound.js --- mephisto-0.7.3/vendor/plugins/rspec/story_server/prototype/javascripts/sound.js 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/story_server/prototype/javascripts/sound.js 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,55 @@ +// script.aculo.us sound.js v1.8.0_pre1, Fri Oct 12 21:34:51 +0200 2007 + +// Copyright (c) 2005-2007 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) +// +// Based on code created by Jules Gravinese (http://www.webveteran.com/) +// +// script.aculo.us is freely distributable under the terms of an MIT-style license. +// For details, see the script.aculo.us web site: http://script.aculo.us/ + +Sound = { + tracks: {}, + _enabled: true, + template: + new Template(''), + enable: function(){ + Sound._enabled = true; + }, + disable: function(){ + Sound._enabled = false; + }, + play: function(url){ + if(!Sound._enabled) return; + var options = Object.extend({ + track: 'global', url: url, replace: false + }, arguments[1] || {}); + + if(options.replace && this.tracks[options.track]) { + $R(0, this.tracks[options.track].id).each(function(id){ + var sound = $('sound_'+options.track+'_'+id); + sound.Stop && sound.Stop(); + sound.remove(); + }) + this.tracks[options.track] = null; + } + + if(!this.tracks[options.track]) + this.tracks[options.track] = { id: 0 } + else + this.tracks[options.track].id++; + + options.id = this.tracks[options.track].id; + $$('body')[0].insert( + Prototype.Browser.IE ? new Element('bgsound',{ + id: 'sound_'+options.track+'_'+options.id, + src: options.url, loop: 1, autostart: true + }) : Sound.template.evaluate(options)); + } +}; + +if(Prototype.Browser.Gecko && navigator.userAgent.indexOf("Win") > 0){ + if(navigator.plugins && $A(navigator.plugins).detect(function(p){ return p.name.indexOf('QuickTime') != -1 })) + Sound.template = new Template('') + else + Sound.play = function(){} +} diff -Nur mephisto-0.7.3/vendor/plugins/rspec/story_server/prototype/javascripts/unittest.js technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/story_server/prototype/javascripts/unittest.js --- mephisto-0.7.3/vendor/plugins/rspec/story_server/prototype/javascripts/unittest.js 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/story_server/prototype/javascripts/unittest.js 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,568 @@ +// script.aculo.us unittest.js v1.8.0_pre1, Fri Oct 12 21:34:51 +0200 2007 + +// Copyright (c) 2005-2007 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) +// (c) 2005-2007 Jon Tirsen (http://www.tirsen.com) +// (c) 2005-2007 Michael Schuerig (http://www.schuerig.de/michael/) +// +// script.aculo.us is freely distributable under the terms of an MIT-style license. +// For details, see the script.aculo.us web site: http://script.aculo.us/ + +// experimental, Firefox-only +Event.simulateMouse = function(element, eventName) { + var options = Object.extend({ + pointerX: 0, + pointerY: 0, + buttons: 0, + ctrlKey: false, + altKey: false, + shiftKey: false, + metaKey: false + }, arguments[2] || {}); + var oEvent = document.createEvent("MouseEvents"); + oEvent.initMouseEvent(eventName, true, true, document.defaultView, + options.buttons, options.pointerX, options.pointerY, options.pointerX, options.pointerY, + options.ctrlKey, options.altKey, options.shiftKey, options.metaKey, 0, $(element)); + + if(this.mark) Element.remove(this.mark); + this.mark = document.createElement('div'); + this.mark.appendChild(document.createTextNode(" ")); + document.body.appendChild(this.mark); + this.mark.style.position = 'absolute'; + this.mark.style.top = options.pointerY + "px"; + this.mark.style.left = options.pointerX + "px"; + this.mark.style.width = "5px"; + this.mark.style.height = "5px;"; + this.mark.style.borderTop = "1px solid red;" + this.mark.style.borderLeft = "1px solid red;" + + if(this.step) + alert('['+new Date().getTime().toString()+'] '+eventName+'/'+Test.Unit.inspect(options)); + + $(element).dispatchEvent(oEvent); +}; + +// Note: Due to a fix in Firefox 1.0.5/6 that probably fixed "too much", this doesn't work in 1.0.6 or DP2. +// You need to downgrade to 1.0.4 for now to get this working +// See https://bugzilla.mozilla.org/show_bug.cgi?id=289940 for the fix that fixed too much +Event.simulateKey = function(element, eventName) { + var options = Object.extend({ + ctrlKey: false, + altKey: false, + shiftKey: false, + metaKey: false, + keyCode: 0, + charCode: 0 + }, arguments[2] || {}); + + var oEvent = document.createEvent("KeyEvents"); + oEvent.initKeyEvent(eventName, true, true, window, + options.ctrlKey, options.altKey, options.shiftKey, options.metaKey, + options.keyCode, options.charCode ); + $(element).dispatchEvent(oEvent); +}; + +Event.simulateKeys = function(element, command) { + for(var i=0; i' + + '' + + '' + + '' + + '
      StatusTestMessage
      '; + this.logsummary = $('logsummary') + this.loglines = $('loglines'); + }, + _toHTML: function(txt) { + return txt.escapeHTML().replace(/\n/g,"
      "); + }, + addLinksToResults: function(){ + $$("tr.failed .nameCell").each( function(td){ // todo: limit to children of this.log + td.title = "Run only this test" + Event.observe(td, 'click', function(){ window.location.search = "?tests=" + td.innerHTML;}); + }); + $$("tr.passed .nameCell").each( function(td){ // todo: limit to children of this.log + td.title = "Run all tests" + Event.observe(td, 'click', function(){ window.location.search = "";}); + }); + } +} + +Test.Unit.Runner = Class.create(); +Test.Unit.Runner.prototype = { + initialize: function(testcases) { + this.options = Object.extend({ + testLog: 'testlog' + }, arguments[1] || {}); + this.options.resultsURL = this.parseResultsURLQueryParameter(); + this.options.tests = this.parseTestsQueryParameter(); + if (this.options.testLog) { + this.options.testLog = $(this.options.testLog) || null; + } + if(this.options.tests) { + this.tests = []; + for(var i = 0; i < this.options.tests.length; i++) { + if(/^test/.test(this.options.tests[i])) { + this.tests.push(new Test.Unit.Testcase(this.options.tests[i], testcases[this.options.tests[i]], testcases["setup"], testcases["teardown"])); + } + } + } else { + if (this.options.test) { + this.tests = [new Test.Unit.Testcase(this.options.test, testcases[this.options.test], testcases["setup"], testcases["teardown"])]; + } else { + this.tests = []; + for(var testcase in testcases) { + if(/^test/.test(testcase)) { + this.tests.push( + new Test.Unit.Testcase( + this.options.context ? ' -> ' + this.options.titles[testcase] : testcase, + testcases[testcase], testcases["setup"], testcases["teardown"] + )); + } + } + } + } + this.currentTest = 0; + this.logger = new Test.Unit.Logger(this.options.testLog); + setTimeout(this.runTests.bind(this), 1000); + }, + parseResultsURLQueryParameter: function() { + return window.location.search.parseQuery()["resultsURL"]; + }, + parseTestsQueryParameter: function(){ + if (window.location.search.parseQuery()["tests"]){ + return window.location.search.parseQuery()["tests"].split(','); + }; + }, + // Returns: + // "ERROR" if there was an error, + // "FAILURE" if there was a failure, or + // "SUCCESS" if there was neither + getResult: function() { + var hasFailure = false; + for(var i=0;i 0) { + return "ERROR"; + } + if (this.tests[i].failures > 0) { + hasFailure = true; + } + } + if (hasFailure) { + return "FAILURE"; + } else { + return "SUCCESS"; + } + }, + postResults: function() { + if (this.options.resultsURL) { + new Ajax.Request(this.options.resultsURL, + { method: 'get', parameters: 'result=' + this.getResult(), asynchronous: false }); + } + }, + runTests: function() { + var test = this.tests[this.currentTest]; + if (!test) { + // finished! + this.postResults(); + this.logger.summary(this.summary()); + return; + } + if(!test.isWaiting) { + this.logger.start(test.name); + } + test.run(); + if(test.isWaiting) { + this.logger.message("Waiting for " + test.timeToWait + "ms"); + setTimeout(this.runTests.bind(this), test.timeToWait || 1000); + } else { + this.logger.finish(test.status(), test.summary()); + this.currentTest++; + // tail recursive, hopefully the browser will skip the stackframe + this.runTests(); + } + }, + summary: function() { + var assertions = 0; + var failures = 0; + var errors = 0; + var messages = []; + for(var i=0;i 0) return 'failed'; + if (this.errors > 0) return 'error'; + return 'passed'; + }, + assert: function(expression) { + var message = arguments[1] || 'assert: got "' + Test.Unit.inspect(expression) + '"'; + try { expression ? this.pass() : + this.fail(message); } + catch(e) { this.error(e); } + }, + assertEqual: function(expected, actual) { + var message = arguments[2] || "assertEqual"; + try { (expected == actual) ? this.pass() : + this.fail(message + ': expected "' + Test.Unit.inspect(expected) + + '", actual "' + Test.Unit.inspect(actual) + '"'); } + catch(e) { this.error(e); } + }, + assertInspect: function(expected, actual) { + var message = arguments[2] || "assertInspect"; + try { (expected == actual.inspect()) ? this.pass() : + this.fail(message + ': expected "' + Test.Unit.inspect(expected) + + '", actual "' + Test.Unit.inspect(actual) + '"'); } + catch(e) { this.error(e); } + }, + assertEnumEqual: function(expected, actual) { + var message = arguments[2] || "assertEnumEqual"; + try { $A(expected).length == $A(actual).length && + expected.zip(actual).all(function(pair) { return pair[0] == pair[1] }) ? + this.pass() : this.fail(message + ': expected ' + Test.Unit.inspect(expected) + + ', actual ' + Test.Unit.inspect(actual)); } + catch(e) { this.error(e); } + }, + assertNotEqual: function(expected, actual) { + var message = arguments[2] || "assertNotEqual"; + try { (expected != actual) ? this.pass() : + this.fail(message + ': got "' + Test.Unit.inspect(actual) + '"'); } + catch(e) { this.error(e); } + }, + assertIdentical: function(expected, actual) { + var message = arguments[2] || "assertIdentical"; + try { (expected === actual) ? this.pass() : + this.fail(message + ': expected "' + Test.Unit.inspect(expected) + + '", actual "' + Test.Unit.inspect(actual) + '"'); } + catch(e) { this.error(e); } + }, + assertNotIdentical: function(expected, actual) { + var message = arguments[2] || "assertNotIdentical"; + try { !(expected === actual) ? this.pass() : + this.fail(message + ': expected "' + Test.Unit.inspect(expected) + + '", actual "' + Test.Unit.inspect(actual) + '"'); } + catch(e) { this.error(e); } + }, + assertNull: function(obj) { + var message = arguments[1] || 'assertNull' + try { (obj==null) ? this.pass() : + this.fail(message + ': got "' + Test.Unit.inspect(obj) + '"'); } + catch(e) { this.error(e); } + }, + assertMatch: function(expected, actual) { + var message = arguments[2] || 'assertMatch'; + var regex = new RegExp(expected); + try { (regex.exec(actual)) ? this.pass() : + this.fail(message + ' : regex: "' + Test.Unit.inspect(expected) + ' did not match: ' + Test.Unit.inspect(actual) + '"'); } + catch(e) { this.error(e); } + }, + assertHidden: function(element) { + var message = arguments[1] || 'assertHidden'; + this.assertEqual("none", element.style.display, message); + }, + assertNotNull: function(object) { + var message = arguments[1] || 'assertNotNull'; + this.assert(object != null, message); + }, + assertType: function(expected, actual) { + var message = arguments[2] || 'assertType'; + try { + (actual.constructor == expected) ? this.pass() : + this.fail(message + ': expected "' + Test.Unit.inspect(expected) + + '", actual "' + (actual.constructor) + '"'); } + catch(e) { this.error(e); } + }, + assertNotOfType: function(expected, actual) { + var message = arguments[2] || 'assertNotOfType'; + try { + (actual.constructor != expected) ? this.pass() : + this.fail(message + ': expected "' + Test.Unit.inspect(expected) + + '", actual "' + (actual.constructor) + '"'); } + catch(e) { this.error(e); } + }, + assertInstanceOf: function(expected, actual) { + var message = arguments[2] || 'assertInstanceOf'; + try { + (actual instanceof expected) ? this.pass() : + this.fail(message + ": object was not an instance of the expected type"); } + catch(e) { this.error(e); } + }, + assertNotInstanceOf: function(expected, actual) { + var message = arguments[2] || 'assertNotInstanceOf'; + try { + !(actual instanceof expected) ? this.pass() : + this.fail(message + ": object was an instance of the not expected type"); } + catch(e) { this.error(e); } + }, + assertRespondsTo: function(method, obj) { + var message = arguments[2] || 'assertRespondsTo'; + try { + (obj[method] && typeof obj[method] == 'function') ? this.pass() : + this.fail(message + ": object doesn't respond to [" + method + "]"); } + catch(e) { this.error(e); } + }, + assertReturnsTrue: function(method, obj) { + var message = arguments[2] || 'assertReturnsTrue'; + try { + var m = obj[method]; + if(!m) m = obj['is'+method.charAt(0).toUpperCase()+method.slice(1)]; + m() ? this.pass() : + this.fail(message + ": method returned false"); } + catch(e) { this.error(e); } + }, + assertReturnsFalse: function(method, obj) { + var message = arguments[2] || 'assertReturnsFalse'; + try { + var m = obj[method]; + if(!m) m = obj['is'+method.charAt(0).toUpperCase()+method.slice(1)]; + !m() ? this.pass() : + this.fail(message + ": method returned true"); } + catch(e) { this.error(e); } + }, + assertRaise: function(exceptionName, method) { + var message = arguments[2] || 'assertRaise'; + try { + method(); + this.fail(message + ": exception expected but none was raised"); } + catch(e) { + ((exceptionName == null) || (e.name==exceptionName)) ? this.pass() : this.error(e); + } + }, + assertElementsMatch: function() { + var expressions = $A(arguments), elements = $A(expressions.shift()); + if (elements.length != expressions.length) { + this.fail('assertElementsMatch: size mismatch: ' + elements.length + ' elements, ' + expressions.length + ' expressions'); + return false; + } + elements.zip(expressions).all(function(pair, index) { + var element = $(pair.first()), expression = pair.last(); + if (element.match(expression)) return true; + this.fail('assertElementsMatch: (in index ' + index + ') expected ' + expression.inspect() + ' but got ' + element.inspect()); + }.bind(this)) && this.pass(); + }, + assertElementMatches: function(element, expression) { + this.assertElementsMatch([element], expression); + }, + benchmark: function(operation, iterations) { + var startAt = new Date(); + (iterations || 1).times(operation); + var timeTaken = ((new Date())-startAt); + this.info((arguments[2] || 'Operation') + ' finished ' + + iterations + ' iterations in ' + (timeTaken/1000)+'s' ); + return timeTaken; + }, + _isVisible: function(element) { + element = $(element); + if(!element.parentNode) return true; + this.assertNotNull(element); + if(element.style && Element.getStyle(element, 'display') == 'none') + return false; + + return this._isVisible(element.parentNode); + }, + assertNotVisible: function(element) { + this.assert(!this._isVisible(element), Test.Unit.inspect(element) + " was not hidden and didn't have a hidden parent either. " + ("" || arguments[1])); + }, + assertVisible: function(element) { + this.assert(this._isVisible(element), Test.Unit.inspect(element) + " was not visible. " + ("" || arguments[1])); + }, + benchmark: function(operation, iterations) { + var startAt = new Date(); + (iterations || 1).times(operation); + var timeTaken = ((new Date())-startAt); + this.info((arguments[2] || 'Operation') + ' finished ' + + iterations + ' iterations in ' + (timeTaken/1000)+'s' ); + return timeTaken; + } +} + +Test.Unit.Testcase = Class.create(); +Object.extend(Object.extend(Test.Unit.Testcase.prototype, Test.Unit.Assertions.prototype), { + initialize: function(name, test, setup, teardown) { + Test.Unit.Assertions.prototype.initialize.bind(this)(); + this.name = name; + + if(typeof test == 'string') { + test = test.gsub(/(\.should[^\(]+\()/,'#{0}this,'); + test = test.gsub(/(\.should[^\(]+)\(this,\)/,'#{1}(this)'); + this.test = function() { + eval('with(this){'+test+'}'); + } + } else { + this.test = test || function() {}; + } + + this.setup = setup || function() {}; + this.teardown = teardown || function() {}; + this.isWaiting = false; + this.timeToWait = 1000; + }, + wait: function(time, nextPart) { + this.isWaiting = true; + this.test = nextPart; + this.timeToWait = time; + }, + run: function() { + try { + try { + if (!this.isWaiting) this.setup.bind(this)(); + this.isWaiting = false; + this.test.bind(this)(); + } finally { + if(!this.isWaiting) { + this.teardown.bind(this)(); + } + } + } + catch(e) { this.error(e); } + } +}); + +// *EXPERIMENTAL* BDD-style testing to please non-technical folk +// This draws many ideas from RSpec http://rspec.rubyforge.org/ + +Test.setupBDDExtensionMethods = function(){ + var METHODMAP = { + shouldEqual: 'assertEqual', + shouldNotEqual: 'assertNotEqual', + shouldEqualEnum: 'assertEnumEqual', + shouldBeA: 'assertType', + shouldNotBeA: 'assertNotOfType', + shouldBeAn: 'assertType', + shouldNotBeAn: 'assertNotOfType', + shouldBeNull: 'assertNull', + shouldNotBeNull: 'assertNotNull', + + shouldBe: 'assertReturnsTrue', + shouldNotBe: 'assertReturnsFalse', + shouldRespondTo: 'assertRespondsTo' + }; + var makeAssertion = function(assertion, args, object) { + this[assertion].apply(this,(args || []).concat([object])); + } + + Test.BDDMethods = {}; + $H(METHODMAP).each(function(pair) { + Test.BDDMethods[pair.key] = function() { + var args = $A(arguments); + var scope = args.shift(); + makeAssertion.apply(scope, [pair.value, args, this]); }; + }); + + [Array.prototype, String.prototype, Number.prototype, Boolean.prototype].each( + function(p){ Object.extend(p, Test.BDDMethods) } + ); +} + +Test.context = function(name, spec, log){ + Test.setupBDDExtensionMethods(); + + var compiledSpec = {}; + var titles = {}; + for(specName in spec) { + switch(specName){ + case "setup": + case "teardown": + compiledSpec[specName] = spec[specName]; + break; + default: + var testName = 'test'+specName.gsub(/\s+/,'-').camelize(); + var body = spec[specName].toString().split('\n').slice(1); + if(/^\{/.test(body[0])) body = body.slice(1); + body.pop(); + body = body.map(function(statement){ + return statement.strip() + }); + compiledSpec[testName] = body.join('\n'); + titles[testName] = specName; + } + } + new Test.Unit.Runner(compiledSpec, { titles: titles, testLog: log || 'testlog', context: name }); +}; \ No newline at end of file diff -Nur mephisto-0.7.3/vendor/plugins/rspec/story_server/prototype/lib/server.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/story_server/prototype/lib/server.rb --- mephisto-0.7.3/vendor/plugins/rspec/story_server/prototype/lib/server.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/story_server/prototype/lib/server.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,24 @@ +require 'webrick' + +class DispatchServlet < WEBrick::HTTPServlet::AbstractServlet + def do_POST(request, response) + File.open('story', 'w') do |io| + io.write(request.body) + end + + response.status = 200 + response['Content-Type'] = 'text/html' + response.body = "body" + end +end + +params = { :Port => 4000, + :ServerType => WEBrick::SimpleServer, + :BindAddress => "0.0.0.0", + :MimeTypes => WEBrick::HTTPUtils::DefaultMimeTypes } +server = WEBrick::HTTPServer.new(params) +server.mount('/stories', DispatchServlet) +server.mount('/', WEBrick::HTTPServlet::FileHandler, File.dirname(__FILE__) + '/..', { :FancyIndexing => true }) + +trap("INT") { server.shutdown } +server.start \ No newline at end of file diff -Nur mephisto-0.7.3/vendor/plugins/rspec/story_server/prototype/stories.html technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/story_server/prototype/stories.html --- mephisto-0.7.3/vendor/plugins/rspec/story_server/prototype/stories.html 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/story_server/prototype/stories.html 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,176 @@ + + + + + Stories + + + + + + + + + + + + + + +
      + +
      +
      transfer to cash account
      +
      +

      + As a savings account holder
      + I want to transfer money from my savings account
      + So that I can get cash easily from an ATM
      +

      +
      +
      savings account is in credit
      +
      +
        +
      • Given my savings account balance is 100 dollars
      • +
      • Given my cash account balance is 10 dollars
      • +
      • When I transfer 20 dollars
      • +
      • Then my savings account balance should be 80 dollars
      • +
      • Then my cash account balance should be 30 dollars
      • +
      +
      +
      + +
      +
      savings account is overdrawn
      +
      +
        +
      • Given my savings account balance is -20 dollars
      • +
      • Given my cash account balance is 10 dollars
      • +
      • When I transfer 20 dollars
      • +
      • Then my savings account balance should be -20 dollars
      • +
      • Then my cash account balance should be 10 dollars
      • +
      • Then I should still be poor
      • +
      +
      +
      +
      +
      + + + +
      + + +
      + + diff -Nur mephisto-0.7.3/vendor/plugins/rspec/story_server/prototype/stylesheets/style.css technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/story_server/prototype/stylesheets/style.css --- mephisto-0.7.3/vendor/plugins/rspec/story_server/prototype/stylesheets/style.css 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/story_server/prototype/stylesheets/style.css 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,136 @@ +body { + background: #fff; + font-size: 80%; + margin:0pt; + padding:0pt; +} + +#nav { + border-bottom:1px solid #222222; + border-top-style:solid; + border-top-width:0.5em; + font-family:Helvetica,Arial,sans-serif; + font-size:1.1em; + padding:0.2em 0pt; + position:fixed; + text-align:center; + width:100%; + z-index:50; + + background-color: #000000; + opacity: 0.6; +} + +#container { + background:white none repeat scroll 0%; + font-family:Helvetica,Arial,sans-serif; + margin:0pt auto; + position:relative; + text-align:left; + top:4.0em; + width:78em; +} + +dl { + font: normal 11px "Lucida Grande", Helvetica, sans-serif; +} + +dt { + color: #fff; +} + +dl.passed { + border-left: 5px solid #65C400; +} + +dl.failed { + border-left: 5px solid #C20000; +} + +dt { + padding: 3px; + font-weight: bold; +} + +dd { + margin: 0px 0px 0px 0px; +} + +dd p { + padding: 5px; + margin-top: 0; + margin-bottom: 5px; +} + +dd > dl { + margin-left: 5px; +} + +dl.passed > dt { + background: #65C400; +} + +dl.failed > dt { + background: #C20000; +} + +dl.passed > dd > p, li.passed { + background: #DBFFB4; color: #3D7700; + border-bottom: 1px solid #65C400; +} + +dl.failed > dd > p, li.failed { + color: #C20000; background: #FFFBD3; + border-bottom: 1px solid #C20000; +} + +dl.pending > dd > p, li.pending { + color: #131313; background: #FCFB98; + border-bottom: 1px solid #FAF834; +} + +dl.new > dd > p, li.new { + color: #444444; background: #DDDDDD; + border-bottom: 1px solid #444444; +} + +dl > dd > p.wastebin { + background-color: black; +} + +span.param, span.param_editor { + font-weight: bold; +} + +input { + width: 100%; +} + +ul.steps { + padding: 0px; + list-style: none; +} + +ul.steps > li { + margin: 5px 0px 5px 5px; + padding: 3px 3px 3px 5px; +} + +div.auto_complete ul { + list-style-type: none; + border: 2px solid #F0F0F0; + margin: 0px; + padding: 0px; +} + +div.auto_complete ul li { + background-color: white; + list-style-type: none; + display: block; + margin: 0; + padding: 2px; +} + +div.auto_complete ul li.selected { + color: #444444; background: #DDDDDD; +} diff -Nur mephisto-0.7.3/vendor/plugins/rspec/story_server/prototype/stylesheets/test.css technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/story_server/prototype/stylesheets/test.css --- mephisto-0.7.3/vendor/plugins/rspec/story_server/prototype/stylesheets/test.css 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec/story_server/prototype/stylesheets/test.css 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,90 @@ +body, div, p, h1, h2, h3, ul, ol, span, a, table, td, form, img, li { + font-family: sans-serif; +} + +body { + font-size:0.8em; +} + +.navigation { + background: #9DC569; + color: #fff; +} + +.navigation h1 { + font-size: 20px; +} + +.navigation h2 { + font-size: 16px; + font-weight: normal; + margin: 0; + border: 1px solid #e8a400; + border-bottom: 0; + background: #ffc; + color: #E8A400; + padding: 8px; + padding-bottom: 0; +} + +.navigation ul { + margin-top: 0; + border: 1px solid #E8A400; + border-top: none; + background: #ffc; + padding: 8px; + margin-left: 0; +} + +.navigation ul li { + font-size: 12px; + list-style-type: none; + margin-top: 1px; + margin-bottom: 1px; + color: #555; +} + +.navigation a { + color: #ffc; +} + +.navigation ul li a { + color: #000; +} + +#log { + padding-bottom: 1em; + border-bottom: 2px solid #000; + margin-bottom: 2em; +} + +#logsummary { + margin-bottom: 1em; + padding: 1ex; + border: 1px solid #000; + font-weight: bold; +} + +#logtable { + width:100%; + border-collapse: collapse; + border: 1px dotted #666; +} + +#logtable td, #logtable th { + text-align: left; + padding: 3px 8px; + border: 1px dotted #666; +} + +#logtable .passed { + background-color: #cfc; +} + +#logtable .failed, #logtable .error { + background-color: #fcc; +} + +#logtable .nameCell { + cursor: pointer; +} \ No newline at end of file diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/MIT-LICENSE technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/MIT-LICENSE --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/MIT-LICENSE 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/MIT-LICENSE 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,31 @@ +==================================================================== +== RSpec +Copyright (c) 2005-2007 The RSpec Development Team +==================================================================== +== ARTS +Copyright (c) 2006 Kevin Clark, Jake Howerton +==================================================================== +== ZenTest +Copyright (c) 2001-2006 Ryan Davis, Eric Hodel, Zen Spider Software +==================================================================== +== AssertSelect +Copyright (c) 2006 Assaf Arkin +==================================================================== + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/README technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/README --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/README 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/README 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1 @@ +See Spec::Rails \ No newline at end of file diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/Rakefile technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/Rakefile --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/Rakefile 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/Rakefile 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,9 @@ +require 'rake' +require 'rake/rdoctask' + +desc 'Generate RDoc' +rd = Rake::RDocTask.new do |rdoc| + rdoc.rdoc_dir = '../doc/output/rdoc-rails' + rdoc.options << '--title' << 'Spec::Rails' << '--line-numbers' << '--inline-source' << '--main' << 'Spec::Rails' + rdoc.rdoc_files.include('MIT-LICENSE', 'lib/**/*.rb') +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/generators/rspec/CHANGES technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/generators/rspec/CHANGES --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/generators/rspec/CHANGES 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/generators/rspec/CHANGES 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1 @@ +Please refer to the CHANGES file for RSpec's core \ No newline at end of file diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/generators/rspec/rspec_generator.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/generators/rspec/rspec_generator.rb --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/generators/rspec/rspec_generator.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/generators/rspec/rspec_generator.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,35 @@ +require 'rbconfig' + +# This generator bootstraps a Rails project for use with RSpec +class RspecGenerator < Rails::Generator::Base + DEFAULT_SHEBANG = File.join(Config::CONFIG['bindir'], + Config::CONFIG['ruby_install_name']) + + def initialize(runtime_args, runtime_options = {}) + super + end + + def manifest + record do |m| + script_options = { :chmod => 0755, :shebang => options[:shebang] == DEFAULT_SHEBANG ? nil : options[:shebang] } + + m.directory 'spec' + m.template 'spec_helper.rb', 'spec/spec_helper.rb' + m.file 'spec.opts', 'spec/spec.opts' + m.file 'rcov.opts', 'spec/rcov.opts' + m.file 'script/spec_server', 'script/spec_server', script_options + m.file 'script/spec', 'script/spec', script_options + + m.directory 'stories' + m.file 'all_stories.rb', 'stories/all.rb' + m.file 'stories_helper.rb', 'stories/helper.rb' + end + end + +protected + + def banner + "Usage: #{$0} rspec" + end + +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/generators/rspec/templates/all_stories.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/generators/rspec/templates/all_stories.rb --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/generators/rspec/templates/all_stories.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/generators/rspec/templates/all_stories.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,4 @@ +dir = File.dirname(__FILE__) +Dir[File.expand_path("#{dir}/**/*.rb")].uniq.each do |file| + require file +end \ No newline at end of file diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/generators/rspec/templates/rcov.opts technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/generators/rspec/templates/rcov.opts --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/generators/rspec/templates/rcov.opts 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/generators/rspec/templates/rcov.opts 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,2 @@ +--exclude "spec/*,gems/*" +--rails \ No newline at end of file diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/generators/rspec/templates/script/spec technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/generators/rspec/templates/script/spec --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/generators/rspec/templates/script/spec 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/generators/rspec/templates/script/spec 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,4 @@ +#!/usr/bin/env ruby +$LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__) + "/../vendor/plugins/rspec/lib")) +require 'spec' +exit ::Spec::Runner::CommandLine.run(::Spec::Runner::OptionParser.parse(ARGV, STDERR, STDOUT)) diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/generators/rspec/templates/script/spec_server technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/generators/rspec/templates/script/spec_server --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/generators/rspec/templates/script/spec_server 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/generators/rspec/templates/script/spec_server 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,99 @@ +#!/usr/bin/env ruby +$LOAD_PATH.unshift File.dirname(__FILE__) + '/../../rspec/lib' # For svn +$LOAD_PATH.unshift File.dirname(__FILE__) + '/../vendor/plugins/rspec/lib' # For rspec installed as plugin +require 'rubygems' +require 'drb/drb' +require 'rbconfig' +require 'spec' +require 'optparse' + +# This is based on Florian Weber's TDDMate +module Spec + module Runner + class RailsSpecServer + def run(argv, stderr, stdout) + $stdout = stdout + $stderr = stderr + + base = ActiveRecord::Base + def base.clear_reloadable_connections! + active_connections.each do |name, conn| + if conn.requires_reloading? + conn.disconnect! + active_connections.delete(name) + end + end + end + + if ::Dispatcher.respond_to?(:cleanup_application) + ::Dispatcher.cleanup_application + elsif ::Dispatcher.respond_to?(:reset_application!) + ::Dispatcher.reset_application! + end + ::Dependencies.mechanism = :load + require_dependency('application.rb') unless Object.const_defined?(:ApplicationController) + load File.dirname(__FILE__) + '/../spec/spec_helper.rb' + + ::Spec::Runner::CommandLine.run( + ::Spec::Runner::OptionParser.parse( + argv, + $stderr, + $stdout + ) + ) + end + end + end +end +puts "Loading Rails environment" + +ENV["RAILS_ENV"] = "test" +require File.expand_path(File.dirname(__FILE__) + "/../config/environment") +require 'dispatcher' + +def restart_test_server + puts "restarting" + config = ::Config::CONFIG + ruby = File::join(config['bindir'], config['ruby_install_name']) + config['EXEEXT'] + command_line = [ruby, $0, ARGV].flatten.join(' ') + exec(command_line) +end + +def daemonize(pid_file = nil) + return yield if $DEBUG + pid = Process.fork{ + Process.setsid + Dir.chdir(RAILS_ROOT) + trap("SIGINT"){ exit! 0 } + trap("SIGTERM"){ exit! 0 } + trap("SIGHUP"){ restart_test_server } + File.open("/dev/null"){|f| + STDERR.reopen f + STDIN.reopen f + STDOUT.reopen f + } + yield + } + puts "spec_server launched. (PID: %d)" % pid + File.open(pid_file,"w"){|f| f.puts pid } if pid_file + exit! 0 +end + +options = Hash.new +opts = OptionParser.new +opts.on("-d", "--daemon"){|v| options[:daemon] = true } +opts.on("-p", "--pid PIDFILE"){|v| options[:pid] = v } +opts.parse!(ARGV) + +puts "Ready" +exec_server = lambda { + trap("USR2") { restart_test_server } if Signal.list.has_key?("USR2") + DRb.start_service("druby://localhost:8989", Spec::Runner::RailsSpecServer.new) + DRb.thread.join +} + +if options[:daemon] + daemonize(options[:pid], &exec_server) +else + exec_server.call +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/generators/rspec/templates/spec.opts technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/generators/rspec/templates/spec.opts --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/generators/rspec/templates/spec.opts 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/generators/rspec/templates/spec.opts 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,7 @@ +--colour +--format +progress +--loadby +mtime +--reverse +--backtrace \ No newline at end of file diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/generators/rspec/templates/spec_helper.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/generators/rspec/templates/spec_helper.rb --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/generators/rspec/templates/spec_helper.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/generators/rspec/templates/spec_helper.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,24 @@ +# This file is copied to ~/spec when you run 'ruby script/generate rspec' +# from the project root directory. +ENV["RAILS_ENV"] = "test" +require File.expand_path(File.dirname(__FILE__) + "/../config/environment") +require 'spec' +require 'spec/rails' + +Spec::Runner.configure do |config| + config.use_transactional_fixtures = true + config.use_instantiated_fixtures = false + config.fixture_path = RAILS_ROOT + '/spec/fixtures/' + + # You can declare fixtures for each behaviour like this: + # describe "...." do + # fixtures :table_a, :table_b + # + # Alternatively, if you prefer to declare them only once, you can + # do so here, like so ... + # + # config.global_fixtures = :table_a, :table_b + # + # If you declare global fixtures, be aware that they will be declared + # for all of your examples, even those that don't use them. +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/generators/rspec/templates/stories_helper.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/generators/rspec/templates/stories_helper.rb --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/generators/rspec/templates/stories_helper.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/generators/rspec/templates/stories_helper.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,3 @@ +ENV["RAILS_ENV"] = "test" +require File.expand_path(File.dirname(__FILE__) + "/../config/environment") +require 'spec/rails/story_adapter' \ No newline at end of file diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/generators/rspec_controller/USAGE technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/generators/rspec_controller/USAGE --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/generators/rspec_controller/USAGE 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/generators/rspec_controller/USAGE 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,33 @@ +Description: + The rspec_controller generator creates stub specs and files for a new + controller and its views. + + The generator takes a controller name and a list of views as arguments. + The controller name may be given in CamelCase or under_score and should + not be suffixed with 'Controller'. To create a controller within a + module, specify the controller name as 'module/controller'. + + The generator creates stubs for a controller (and spec), a view (and spec) + for each view in the argument list, plus a helper. + +Example: + ./script/generate rspec_controller dog bark fetch + ... + create spec/controllers/dog_controller_spec.rb + create app/controllers/dog_controller.rb + create app/helpers/dog_helper.rb + create spec/views/dog/bark_view_spec.rb + create app/views/dog/bark.rhtml + create spec/views/dog/fetch_view_spec.rb + create app/views/dog/fetch.rhtml + +Modules Example: + ./script/generate rspec_controller 'pets/dog' bark fetch + ... + create spec/controllers/pets/dog_controller_spec.rb + create app/controllers/pets/dog_controller.rb + create app/helpers/pets/dog_helper.rb + create spec/views/pets/dog/bark_view_spec.rb + create app/views/pets/dog/bark.rhtml + create spec/views/pets/dog/fetch_view_spec.rb + create app/views/pets/dog/fetch.rhtml diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/generators/rspec_controller/rspec_controller_generator.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/generators/rspec_controller/rspec_controller_generator.rb --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/generators/rspec_controller/rspec_controller_generator.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/generators/rspec_controller/rspec_controller_generator.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,49 @@ +require 'rails_generator/generators/components/controller/controller_generator' + +class RspecControllerGenerator < ControllerGenerator + def manifest + record do |m| + # Check for class naming collisions. + m.class_collisions class_path, "#{class_name}Controller", "#{class_name}Helper" + + # Controller, helper, views, and spec directories. + m.directory File.join('app/controllers', class_path) + m.directory File.join('app/helpers', class_path) + m.directory File.join('app/views', class_path, file_name) + m.directory File.join('spec/controllers', class_path) + m.directory File.join('spec/helpers', class_path) + m.directory File.join('spec/views', class_path, file_name) + + if ActionView::Base.const_defined?('DEFAULT_TEMPLATE_HANDLER_PREFERENCE') && + ActionView::Base::DEFAULT_TEMPLATE_HANDLER_PREFERENCE.include?(:erb) then + @default_file_extension = "html.erb" + else + @default_file_extension = "rhtml" + end + + # Controller spec, class, and helper. + m.template 'controller_spec.rb', + File.join('spec/controllers', class_path, "#{file_name}_controller_spec.rb") + + m.template 'helper_spec.rb', + File.join('spec/helpers', class_path, "#{file_name}_helper_spec.rb") + + m.template 'controller:controller.rb', + File.join('app/controllers', class_path, "#{file_name}_controller.rb") + + m.template 'controller:helper.rb', + File.join('app/helpers', class_path, "#{file_name}_helper.rb") + + # Spec and view template for each action. + actions.each do |action| + m.template 'view_spec.rb', + File.join('spec/views', class_path, file_name, "#{action}.#{@default_file_extension}_spec.rb"), + :assigns => { :action => action, :model => file_name } + path = File.join('app/views', class_path, file_name, "#{action}.#{@default_file_extension}") + m.template "controller:view.#{@default_file_extension}", + path, + :assigns => { :action => action, :path => path } + end + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/generators/rspec_controller/templates/controller_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/generators/rspec_controller/templates/controller_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/generators/rspec_controller/templates/controller_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/generators/rspec_controller/templates/controller_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,23 @@ +require File.dirname(__FILE__) + '<%= '/..' * class_nesting_depth %>/../spec_helper' + +describe <%= class_name %>Controller do + +<% if actions.empty? -%> + #Delete this example and add some real ones +<% else -%> + #Delete these examples and add some real ones +<% end -%> + it "should use <%= class_name %>Controller" do + controller.should be_an_instance_of(<%= class_name %>Controller) + end + +<% unless actions.empty? -%> +<% for action in actions -%> + + it "GET '<%= action %>' should be successful" do + get '<%= action %>' + response.should be_success + end +<% end -%> +<% end -%> +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/generators/rspec_controller/templates/helper_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/generators/rspec_controller/templates/helper_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/generators/rspec_controller/templates/helper_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/generators/rspec_controller/templates/helper_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,11 @@ +require File.dirname(__FILE__) + '<%= '/..' * class_nesting_depth %>/../spec_helper' + +describe <%= class_name %>Helper do + + #Delete this example and add some real ones or delete this file + it "should include the <%= class_name %>Helper" do + included_modules = self.metaclass.send :included_modules + included_modules.should include(<%= class_name %>Helper) + end + +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/generators/rspec_controller/templates/view_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/generators/rspec_controller/templates/view_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/generators/rspec_controller/templates/view_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/generators/rspec_controller/templates/view_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,12 @@ +require File.dirname(__FILE__) + '<%= '/..' * class_nesting_depth %>/../../spec_helper' + +describe "/<%= class_name.underscore %>/<%= action %>" do + before do + render '<%= class_name.underscore %>/<%= action %>' + end + + #Delete this example and add some real ones or delete this file + it "should tell you where to find the file" do + response.should have_tag('p', /Find me in app\/views\/<%= class_name.underscore %>\/<%= action %>/) + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/generators/rspec_model/USAGE technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/generators/rspec_model/USAGE --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/generators/rspec_model/USAGE 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/generators/rspec_model/USAGE 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,18 @@ +Description: + The rspec_model generator creates stubs for a new model. + + The generator takes a model name as its argument. The model name may be + given in CamelCase or under_score and should not be suffixed with 'Model'. + + The generator creates a model class in app/models, an RSpec spec in + spec/models, database fixtures in spec/fixtures/plural_name.yml, and a migration + in db/migrate. + +Example: + ./script/generate rspec_model Account + + This will create an Account model: + Model: app/models/account.rb + Spec: spec/models/account_spec.rb + Fixtures: spec/fixtures/accounts.yml + Migration: db/migrate/XXX_add_accounts.rb diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/generators/rspec_model/rspec_model_generator.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/generators/rspec_model/rspec_model_generator.rb --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/generators/rspec_model/rspec_model_generator.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/generators/rspec_model/rspec_model_generator.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,30 @@ +require 'rails_generator/generators/components/model/model_generator' + +class RspecModelGenerator < ModelGenerator + + def manifest + + record do |m| + # Check for class naming collisions. + m.class_collisions class_path, class_name + + # Model, spec, and fixture directories. + m.directory File.join('app/models', class_path) + m.directory File.join('spec/models', class_path) + m.directory File.join('spec/fixtures', class_path) + + # Model class, spec and fixtures. + m.template 'model:model.rb', File.join('app/models', class_path, "#{file_name}.rb") + m.template 'model:fixtures.yml', File.join('spec/fixtures', class_path, "#{table_name}.yml") + m.template 'model_spec.rb', File.join('spec/models', class_path, "#{file_name}_spec.rb") + + unless options[:skip_migration] + m.migration_template 'model:migration.rb', 'db/migrate', :assigns => { + :migration_name => "Create#{class_name.pluralize.gsub(/::/, '')}" + }, :migration_file_name => "create_#{file_path.gsub(/\//, '_').pluralize}" + end + + end + end + +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/generators/rspec_model/templates/model_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/generators/rspec_model/templates/model_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/generators/rspec_model/templates/model_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/generators/rspec_model/templates/model_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,11 @@ +require File.dirname(__FILE__) + '<%= '/..' * class_nesting_depth %>/../spec_helper' + +describe <%= class_name %> do + before(:each) do + @<%= file_name %> = <%= class_name %>.new + end + + it "should be valid" do + @<%= file_name %>.should be_valid + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/generators/rspec_scaffold/rspec_scaffold_generator.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/generators/rspec_scaffold/rspec_scaffold_generator.rb --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/generators/rspec_scaffold/rspec_scaffold_generator.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/generators/rspec_scaffold/rspec_scaffold_generator.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,165 @@ +class RspecScaffoldGenerator < Rails::Generator::NamedBase + default_options :skip_migration => false + + attr_reader :controller_name, + :controller_class_path, + :controller_file_path, + :controller_class_nesting, + :controller_class_nesting_depth, + :controller_class_name, + :controller_singular_name, + :controller_plural_name, + :resource_edit_path, + :default_file_extension + alias_method :controller_file_name, :controller_singular_name + alias_method :controller_table_name, :controller_plural_name + + def initialize(runtime_args, runtime_options = {}) + super + + @controller_name = @name.pluralize + + base_name, @controller_class_path, @controller_file_path, @controller_class_nesting, @controller_class_nesting_depth = extract_modules(@controller_name) + @controller_class_name_without_nesting, @controller_singular_name, @controller_plural_name = inflect_names(base_name) + + if @controller_class_nesting.empty? + @controller_class_name = @controller_class_name_without_nesting + else + @controller_class_name = "#{@controller_class_nesting}::#{@controller_class_name_without_nesting}" + end + + if ActionView::Base.const_defined?('DEFAULT_TEMPLATE_HANDLER_PREFERENCE') && + ActionView::Base::DEFAULT_TEMPLATE_HANDLER_PREFERENCE.include?(:erb) then + @resource_generator = "scaffold" + @default_file_extension = "html.erb" + else + @resource_generator = "scaffold_resource" + @default_file_extension = "rhtml" + end + + if ActionController::Base.respond_to?(:resource_action_separator) + @resource_edit_path = "/edit" + else + @resource_edit_path = ";edit" + end + end + + def manifest + record do |m| + + # Check for class naming collisions. + m.class_collisions(controller_class_path, "#{controller_class_name}Controller", "#{controller_class_name}Helper") + m.class_collisions(class_path, "#{class_name}") + + # Controller, helper, views, and spec directories. + m.directory(File.join('app/models', class_path)) + m.directory(File.join('app/controllers', controller_class_path)) + m.directory(File.join('app/helpers', controller_class_path)) + m.directory(File.join('app/views', controller_class_path, controller_file_name)) + m.directory(File.join('spec/controllers', controller_class_path)) + m.directory(File.join('spec/models', class_path)) + m.directory(File.join('spec/helpers', class_path)) + m.directory File.join('spec/fixtures', class_path) + m.directory File.join('spec/views', controller_class_path, controller_file_name) + + # Controller spec, class, and helper. + m.template 'rspec_scaffold:controller_spec.rb', + File.join('spec/controllers', controller_class_path, "#{controller_file_name}_controller_spec.rb") + + m.template "#{@resource_generator}:controller.rb", + File.join('app/controllers', controller_class_path, "#{controller_file_name}_controller.rb") + + m.template 'rspec_scaffold:helper_spec.rb', + File.join('spec/helpers', class_path, "#{controller_file_name}_helper_spec.rb") + + m.template "#{@resource_generator}:helper.rb", + File.join('app/helpers', controller_class_path, "#{controller_file_name}_helper.rb") + + for action in scaffold_views + m.template( + "#{@resource_generator}:view_#{action}.#{@default_file_extension}", + File.join('app/views', controller_class_path, controller_file_name, "#{action}.#{default_file_extension}") + ) + end + + # Model class, unit test, and fixtures. + m.template 'model:model.rb', File.join('app/models', class_path, "#{file_name}.rb") + m.template 'model:fixtures.yml', File.join('spec/fixtures', class_path, "#{table_name}.yml") + m.template 'rspec_model:model_spec.rb', File.join('spec/models', class_path, "#{file_name}_spec.rb") + + # View specs + m.template "rspec_scaffold:edit_erb_spec.rb", + File.join('spec/views', controller_class_path, controller_file_name, "edit.#{default_file_extension}_spec.rb") + m.template "rspec_scaffold:index_erb_spec.rb", + File.join('spec/views', controller_class_path, controller_file_name, "index.#{default_file_extension}_spec.rb") + m.template "rspec_scaffold:new_erb_spec.rb", + File.join('spec/views', controller_class_path, controller_file_name, "new.#{default_file_extension}_spec.rb") + m.template "rspec_scaffold:show_erb_spec.rb", + File.join('spec/views', controller_class_path, controller_file_name, "show.#{default_file_extension}_spec.rb") + + unless options[:skip_migration] + m.migration_template( + 'model:migration.rb', 'db/migrate', + :assigns => { + :migration_name => "Create#{class_name.pluralize.gsub(/::/, '')}", + :attributes => attributes + }, + :migration_file_name => "create_#{file_path.gsub(/\//, '_').pluralize}" + ) + end + + m.route_resources controller_file_name + + end + end + + protected + # Override with your own usage banner. + def banner + "Usage: #{$0} rspec_scaffold ModelName [field:type field:type]" + end + + def add_options!(opt) + opt.separator '' + opt.separator 'Options:' + opt.on("--skip-migration", + "Don't generate a migration file for this model") { |v| options[:skip_migration] = v } + end + + def scaffold_views + %w[ index show new edit ] + end + + def model_name + class_name.demodulize + end +end + +module Rails + module Generator + class GeneratedAttribute + def default_value + @default_value ||= case type + when :int, :integer then "\"1\"" + when :float then "\"1.5\"" + when :decimal then "\"9.99\"" + when :datetime, :timestamp, :time then "Time.now" + when :date then "Date.today" + when :string then "\"MyString\"" + when :text then "\"MyText\"" + when :boolean then "false" + else + "" + end + end + + def input_type + @input_type ||= case type + when :text then "textarea" + else + "input" + end + end + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/generators/rspec_scaffold/templates/controller_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/generators/rspec_scaffold/templates/controller_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/generators/rspec_scaffold/templates/controller_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/generators/rspec_scaffold/templates/controller_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,355 @@ +require File.dirname(__FILE__) + '<%= '/..' * class_nesting_depth %>/../spec_helper' + +describe <%= controller_class_name %>Controller, "#route_for" do + + it "should map { :controller => '<%= table_name %>', :action => 'index' } to /<%= table_name %>" do + route_for(:controller => "<%= table_name %>", :action => "index").should == "/<%= table_name %>" + end + + it "should map { :controller => '<%= table_name %>', :action => 'new' } to /<%= table_name %>/new" do + route_for(:controller => "<%= table_name %>", :action => "new").should == "/<%= table_name %>/new" + end + + it "should map { :controller => '<%= table_name %>', :action => 'show', :id => 1 } to /<%= table_name %>/1" do + route_for(:controller => "<%= table_name %>", :action => "show", :id => 1).should == "/<%= table_name %>/1" + end + + it "should map { :controller => '<%= table_name %>', :action => 'edit', :id => 1 } to /<%= table_name %>/1<%= resource_edit_path %>" do + route_for(:controller => "<%= table_name %>", :action => "edit", :id => 1).should == "/<%= table_name %>/1<%= resource_edit_path %>" + end + + it "should map { :controller => '<%= table_name %>', :action => 'update', :id => 1} to /<%= table_name %>/1" do + route_for(:controller => "<%= table_name %>", :action => "update", :id => 1).should == "/<%= table_name %>/1" + end + + it "should map { :controller => '<%= table_name %>', :action => 'destroy', :id => 1} to /<%= table_name %>/1" do + route_for(:controller => "<%= table_name %>", :action => "destroy", :id => 1).should == "/<%= table_name %>/1" + end + +end + +describe <%= controller_class_name %>Controller, "#params_from" do + + it "should generate params { :controller => '<%= table_name %>', action => 'index' } from GET /<%= table_name %>" do + params_from(:get, "/<%= table_name %>").should == {:controller => "<%= table_name %>", :action => "index"} + end + + it "should generate params { :controller => '<%= table_name %>', action => 'new' } from GET /<%= table_name %>/new" do + params_from(:get, "/<%= table_name %>/new").should == {:controller => "<%= table_name %>", :action => "new"} + end + + it "should generate params { :controller => '<%= table_name %>', action => 'create' } from POST /<%= table_name %>" do + params_from(:post, "/<%= table_name %>").should == {:controller => "<%= table_name %>", :action => "create"} + end + + it "should generate params { :controller => '<%= table_name %>', action => 'show', id => '1' } from GET /<%= table_name %>/1" do + params_from(:get, "/<%= table_name %>/1").should == {:controller => "<%= table_name %>", :action => "show", :id => "1"} + end + + it "should generate params { :controller => '<%= table_name %>', action => 'edit', id => '1' } from GET /<%= table_name %>/1;edit" do + params_from(:get, "/<%= table_name %>/1<%= resource_edit_path %>").should == {:controller => "<%= table_name %>", :action => "edit", :id => "1"} + end + + it "should generate params { :controller => '<%= table_name %>', action => 'update', id => '1' } from PUT /<%= table_name %>/1" do + params_from(:put, "/<%= table_name %>/1").should == {:controller => "<%= table_name %>", :action => "update", :id => "1"} + end + + it "should generate params { :controller => '<%= table_name %>', action => 'destroy', id => '1' } from DELETE /<%= table_name %>/1" do + params_from(:delete, "/<%= table_name %>/1").should == {:controller => "<%= table_name %>", :action => "destroy", :id => "1"} + end + +end + +describe <%= controller_class_name %>Controller, "handling GET /<%= table_name %>" do + + before do + @<%= file_name %> = mock_model(<%= class_name %>) + <%= class_name %>.stub!(:find).and_return([@<%= file_name %>]) + end + + def do_get + get :index + end + + it "should be successful" do + do_get + response.should be_success + end + + it "should render index template" do + do_get + response.should render_template('index') + end + + it "should find all <%= table_name %>" do + <%= class_name %>.should_receive(:find).with(:all).and_return([@<%= file_name %>]) + do_get + end + + it "should assign the found <%= table_name %> for the view" do + do_get + assigns[:<%= table_name %>].should == [@<%= file_name %>] + end +end + +describe <%= controller_class_name %>Controller, "handling GET /<%= table_name %>.xml" do + + before do + @<%= file_name %> = mock_model(<%= class_name %>, :to_xml => "XML") + <%= class_name %>.stub!(:find).and_return(@<%= file_name %>) + end + + def do_get + @request.env["HTTP_ACCEPT"] = "application/xml" + get :index + end + + it "should be successful" do + do_get + response.should be_success + end + + it "should find all <%= table_name %>" do + <%= class_name %>.should_receive(:find).with(:all).and_return([@<%= file_name %>]) + do_get + end + + it "should render the found <%= table_name %> as xml" do + @<%= file_name %>.should_receive(:to_xml).and_return("XML") + do_get + response.body.should == "XML" + end +end + +describe <%= controller_class_name %>Controller, "handling GET /<%= table_name %>/1" do + + before do + @<%= file_name %> = mock_model(<%= class_name %>) + <%= class_name %>.stub!(:find).and_return(@<%= file_name %>) + end + + def do_get + get :show, :id => "1" + end + + it "should be successful" do + do_get + response.should be_success + end + + it "should render show template" do + do_get + response.should render_template('show') + end + + it "should find the <%= file_name %> requested" do + <%= class_name %>.should_receive(:find).with("1").and_return(@<%= file_name %>) + do_get + end + + it "should assign the found <%= file_name %> for the view" do + do_get + assigns[:<%= file_name %>].should equal(@<%= file_name %>) + end +end + +describe <%= controller_class_name %>Controller, "handling GET /<%= table_name %>/1.xml" do + + before do + @<%= file_name %> = mock_model(<%= class_name %>, :to_xml => "XML") + <%= class_name %>.stub!(:find).and_return(@<%= file_name %>) + end + + def do_get + @request.env["HTTP_ACCEPT"] = "application/xml" + get :show, :id => "1" + end + + it "should be successful" do + do_get + response.should be_success + end + + it "should find the <%= file_name %> requested" do + <%= class_name %>.should_receive(:find).with("1").and_return(@<%= file_name %>) + do_get + end + + it "should render the found <%= file_name %> as xml" do + @<%= file_name %>.should_receive(:to_xml).and_return("XML") + do_get + response.body.should == "XML" + end +end + +describe <%= controller_class_name %>Controller, "handling GET /<%= table_name %>/new" do + + before do + @<%= file_name %> = mock_model(<%= class_name %>) + <%= class_name %>.stub!(:new).and_return(@<%= file_name %>) + end + + def do_get + get :new + end + + it "should be successful" do + do_get + response.should be_success + end + + it "should render new template" do + do_get + response.should render_template('new') + end + + it "should create an new <%= file_name %>" do + <%= class_name %>.should_receive(:new).and_return(@<%= file_name %>) + do_get + end + + it "should not save the new <%= file_name %>" do + @<%= file_name %>.should_not_receive(:save) + do_get + end + + it "should assign the new <%= file_name %> for the view" do + do_get + assigns[:<%= file_name %>].should equal(@<%= file_name %>) + end +end + +describe <%= controller_class_name %>Controller, "handling GET /<%= table_name %>/1/edit" do + + before do + @<%= file_name %> = mock_model(<%= class_name %>) + <%= class_name %>.stub!(:find).and_return(@<%= file_name %>) + end + + def do_get + get :edit, :id => "1" + end + + it "should be successful" do + do_get + response.should be_success + end + + it "should render edit template" do + do_get + response.should render_template('edit') + end + + it "should find the <%= file_name %> requested" do + <%= class_name %>.should_receive(:find).and_return(@<%= file_name %>) + do_get + end + + it "should assign the found <%= class_name %> for the view" do + do_get + assigns[:<%= file_name %>].should equal(@<%= file_name %>) + end +end + +describe <%= controller_class_name %>Controller, "handling POST /<%= table_name %>" do + + before do + @<%= file_name %> = mock_model(<%= class_name %>, :to_param => "1") + <%= class_name %>.stub!(:new).and_return(@<%= file_name %>) + end + + def post_with_successful_save + @<%= file_name %>.should_receive(:save).and_return(true) + post :create, :<%= file_name %> => {} + end + + def post_with_failed_save + @<%= file_name %>.should_receive(:save).and_return(false) + post :create, :<%= file_name %> => {} + end + + it "should create a new <%= file_name %>" do + <%= class_name %>.should_receive(:new).with({}).and_return(@<%= file_name %>) + post_with_successful_save + end + + it "should redirect to the new <%= file_name %> on successful save" do + post_with_successful_save + response.should redirect_to(<%= table_name.singularize %>_url("1")) + end + + it "should re-render 'new' on failed save" do + post_with_failed_save + response.should render_template('new') + end +end + +describe <%= controller_class_name %>Controller, "handling PUT /<%= table_name %>/1" do + + before do + @<%= file_name %> = mock_model(<%= class_name %>, :to_param => "1") + <%= class_name %>.stub!(:find).and_return(@<%= file_name %>) + end + + def put_with_successful_update + @<%= file_name %>.should_receive(:update_attributes).and_return(true) + put :update, :id => "1" + end + + def put_with_failed_update + @<%= file_name %>.should_receive(:update_attributes).and_return(false) + put :update, :id => "1" + end + + it "should find the <%= file_name %> requested" do + <%= class_name %>.should_receive(:find).with("1").and_return(@<%= file_name %>) + put_with_successful_update + end + + it "should update the found <%= file_name %>" do + put_with_successful_update + assigns(:<%= file_name %>).should equal(@<%= file_name %>) + end + + it "should assign the found <%= file_name %> for the view" do + put_with_successful_update + assigns(:<%= file_name %>).should equal(@<%= file_name %>) + end + + it "should redirect to the <%= file_name %> on successful update" do + put_with_successful_update + response.should redirect_to(<%= table_name.singularize %>_url("1")) + end + + it "should re-render 'edit' on failed update" do + put_with_failed_update + response.should render_template('edit') + end +end + +describe <%= controller_class_name %>Controller, "handling DELETE /<%= table_name %>/1" do + + before do + @<%= file_name %> = mock_model(<%= class_name %>, :destroy => true) + <%= class_name %>.stub!(:find).and_return(@<%= file_name %>) + end + + def do_delete + delete :destroy, :id => "1" + end + + it "should find the <%= file_name %> requested" do + <%= class_name %>.should_receive(:find).with("1").and_return(@<%= file_name %>) + do_delete + end + + it "should call destroy on the found <%= file_name %>" do + @<%= file_name %>.should_receive(:destroy) + do_delete + end + + it "should redirect to the <%= table_name %> list" do + do_delete + response.should redirect_to(<%= table_name %>_url) + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/generators/rspec_scaffold/templates/edit_erb_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/generators/rspec_scaffold/templates/edit_erb_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/generators/rspec_scaffold/templates/edit_erb_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/generators/rspec_scaffold/templates/edit_erb_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,25 @@ +require File.dirname(__FILE__) + '<%= '/..' * class_nesting_depth %>/../../spec_helper' + +describe "/<%= table_name %>/edit.<%= default_file_extension %>" do + include <%= controller_class_name %>Helper + + before do + @<%= file_name %> = mock_model(<%= class_name %>) +<% for attribute in attributes -%> + @<%= file_name %>.stub!(:<%= attribute.name %>).and_return(<%= attribute.default_value %>) +<% end -%> + assigns[:<%= file_name %>] = @<%= file_name %> + end + + it "should render edit form" do + render "/<%= table_name %>/edit.<%= default_file_extension %>" + + response.should have_tag("form[action=#{<%= file_name %>_path(@<%= file_name %>)}][method=post]") do +<% for attribute in attributes -%><% unless attribute.name =~ /_id/ || [:datetime, :timestamp, :time, :date].index(attribute.type) -%> + with_tag('<%= attribute.input_type -%>#<%= file_name %>_<%= attribute.name %>[name=?]', "<%= file_name %>[<%= attribute.name %>]") +<% end -%><% end -%> + end + end +end + + diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/generators/rspec_scaffold/templates/helper_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/generators/rspec_scaffold/templates/helper_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/generators/rspec_scaffold/templates/helper_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/generators/rspec_scaffold/templates/helper_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,4 @@ +require File.dirname(__FILE__) + '<%= '/..' * class_nesting_depth %>/../spec_helper' + +describe <%= controller_class_name %>Helper do # Helper methods can be called directly in the examples (it blocks) +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/generators/rspec_scaffold/templates/index_erb_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/generators/rspec_scaffold/templates/index_erb_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/generators/rspec_scaffold/templates/index_erb_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/generators/rspec_scaffold/templates/index_erb_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,22 @@ +require File.dirname(__FILE__) + '<%= '/..' * class_nesting_depth %>/../../spec_helper' + +describe "/<%= table_name %>/index.<%= default_file_extension %>" do + include <%= controller_class_name %>Helper + + before do +<% [98,99].each do |id| -%> + <%= file_name %>_<%= id %> = mock_model(<%= class_name %>) +<% for attribute in attributes -%> + <%= file_name %>_<%= id %>.should_receive(:<%= attribute.name %>).and_return(<%= attribute.default_value %>) +<% end -%><% end %> + assigns[:<%= table_name %>] = [<%= file_name %>_98, <%= file_name %>_99] + end + + it "should render list of <%= table_name %>" do + render "/<%= table_name %>/index.<%= default_file_extension %>" +<% for attribute in attributes -%><% unless attribute.name =~ /_id/ || [:datetime, :timestamp, :time, :date].index(attribute.type) -%> + response.should have_tag("tr>td", <%= attribute.default_value %>, 2) +<% end -%><% end -%> + end +end + diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/generators/rspec_scaffold/templates/new_erb_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/generators/rspec_scaffold/templates/new_erb_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/generators/rspec_scaffold/templates/new_erb_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/generators/rspec_scaffold/templates/new_erb_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,26 @@ +require File.dirname(__FILE__) + '<%= '/..' * class_nesting_depth %>/../../spec_helper' + +describe "/<%= table_name %>/new.<%= default_file_extension %>" do + include <%= controller_class_name %>Helper + + before do + @<%= file_name %> = mock_model(<%= class_name %>) + @<%= file_name %>.stub!(:new_record?).and_return(true) +<% for attribute in attributes -%> + @<%= file_name %>.stub!(:<%= attribute.name %>).and_return(<%= attribute.default_value %>) +<% end -%> + assigns[:<%= file_name %>] = @<%= file_name %> + end + + it "should render new form" do + render "/<%= table_name %>/new.<%= default_file_extension %>" + + response.should have_tag("form[action=?][method=post]", <%= table_name %>_path) do +<% for attribute in attributes -%><% unless attribute.name =~ /_id/ || [:datetime, :timestamp, :time, :date].index(attribute.type) -%> + with_tag("<%= attribute.input_type -%>#<%= file_name %>_<%= attribute.name %>[name=?]", "<%= file_name %>[<%= attribute.name %>]") +<% end -%><% end -%> + end + end +end + + diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/generators/rspec_scaffold/templates/show_erb_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/generators/rspec_scaffold/templates/show_erb_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/generators/rspec_scaffold/templates/show_erb_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/generators/rspec_scaffold/templates/show_erb_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,22 @@ +require File.dirname(__FILE__) + '<%= '/..' * class_nesting_depth %>/../../spec_helper' + +describe "/<%= table_name %>/show.<%= default_file_extension %>" do + include <%= controller_class_name %>Helper + + before do + @<%= file_name %> = mock_model(<%= class_name %>) +<% for attribute in attributes -%> + @<%= file_name %>.stub!(:<%= attribute.name %>).and_return(<%= attribute.default_value %>) +<% end -%> + + assigns[:<%= file_name %>] = @<%= file_name %> + end + + it "should render attributes in

      " do + render "/<%= table_name %>/show.<%= default_file_extension %>" +<% for attribute in attributes -%><% unless attribute.name =~ /_id/ || [:datetime, :timestamp, :time, :date].index(attribute.type) -%> + response.should have_text(/<%= Regexp.escape(attribute.default_value)[1..-2]%>/) +<% end -%><% end -%> + end +end + diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/init.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/init.rb --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/init.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/init.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,9 @@ +# Placeholder to satisfy Rails. +# +# Do NOT add any require statements to this file. Doing +# so will cause Rails to load this plugin all of the time. +# +# Running 'ruby script/generate rspec' will +# generate spec/spec_helper.rb, which includes the necessary +# require statements and configuration. This file should +# be required by all of your spec files. \ No newline at end of file diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/lib/autotest/rails_rspec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/lib/autotest/rails_rspec.rb --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/lib/autotest/rails_rspec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/lib/autotest/rails_rspec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,81 @@ +# (c) Copyright 2006 Nick Sieger +# +# Permission is hereby granted, free of charge, to any person +# obtaining a copy of this software and associated documentation files +# (the "Software"), to deal in the Software without restriction, +# including without limitation the rights to use, copy, modify, merge, +# publish, distribute, sublicense, and/or sell copies of the Software, +# and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +$:.push(*Dir["vendor/rails/*/lib"]) + +require 'active_support' +require 'autotest/rspec' + +class Autotest::RailsRspec < Autotest::Rspec + + def initialize # :nodoc: + super + @exceptions = %r%^\./(?:coverage|db|doc|log|public|script|vendor\/rails|previous_failures.txt)% + @test_mappings = { + %r%^(test|spec)/fixtures/(.*).yml$% => proc { |_, m| + ["spec/models/#{m[2].singularize}_spec.rb"] + files_matching(%r%^spec\/views\/#{m[2]}/.*_spec\.rb$%) + }, + %r%^spec/(models|controllers|views|helpers|lib)/.*rb$% => proc { |filename, _| + filename + }, + %r%^app/models/(.*)\.rb$% => proc { |_, m| + ["spec/models/#{m[1]}_spec.rb"] + }, + %r%^app/views/(.*)$% => proc { |_, m| + files_matching %r%^spec/views/#{m[1]}_spec.rb$% + }, + %r%^app/controllers/(.*)\.rb$% => proc { |_, m| + ["spec/controllers/#{m[1]}_spec.rb"] + }, + %r%^app/helpers/(.*)_helper\.rb$% => proc { |_, m| + if m[1] == "application" then + files_matching(%r%^spec/(views|helpers)/.*_spec\.rb$%) + else + ["spec/helpers/#{m[1]}_helper_spec.rb"] + files_matching(%r%^spec\/views\/#{m[1]}/.*_spec\.rb$%) + end + }, + %r%^app/helpers/application_helper\.rb$% => proc { + files_matching %r%^spec/(views|helpers)/.*_spec\.rb$% + }, + %r%^app/controllers/application\.rb$% => proc { |_, m| + files_matching %r%^spec/controllers/.*_spec\.rb$% + }, + %r%^config/routes\.rb$% => proc { + files_matching %r%^spec/(controllers|views|helpers)/.*_spec\.rb$% + }, + %r%^config/database\.yml$% => proc { |_, m| + files_matching %r%^spec/models/.*_spec\.rb$% + }, + %r%^(spec/(spec_helper|shared/.*)|config/(boot|environment(s/test)?))\.rb$% => proc { + files_matching %r%^spec/(models|controllers|views|helpers)/.*_spec\.rb$% + }, + %r%^lib/(.*)\.rb$% => proc { |_, m| + ["spec/lib/#{m[1]}_spec.rb"] + }, + } + end + + def spec_command + "script/spec" + end + +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/lib/spec/rails/example/assigns_hash_proxy.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/lib/spec/rails/example/assigns_hash_proxy.rb --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/lib/spec/rails/example/assigns_hash_proxy.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/lib/spec/rails/example/assigns_hash_proxy.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,42 @@ +module Spec + module Rails + module Example + class AssignsHashProxy #:nodoc: + def initialize(object) + @object = object + end + + def [](ivar) + if assigns.include?(ivar.to_s) + assigns[ivar.to_s] + elsif assigns.include?(ivar) + assigns[ivar] + else + nil + end + end + + def []=(ivar, val) + assigns[ivar.to_s] = val + end + + def delete(name) + assigns.delete(name.to_s) + end + + def each(&block) + assigns.each &block + end + + def has_key?(key) + assigns.key?(key.to_s) + end + + protected + def assigns + @object.assigns + end + end + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/lib/spec/rails/example/behaviour/controller_example.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/lib/spec/rails/example/behaviour/controller_example.rb --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/lib/spec/rails/example/behaviour/controller_example.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/lib/spec/rails/example/behaviour/controller_example.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,244 @@ +module Spec + module Rails + module Example + # Controller Examples live in $RAILS_ROOT/spec/controllers/. + # + # Controller Examples use Spec::Rails::Example::ControllerExample, which supports running specs for + # Controllers in two modes, which represent the tension between the more granular + # testing common in TDD and the more high level testing built into + # rails. BDD sits somewhere in between: we want to a balance between + # specs that are close enough to the code to enable quick fault + # isolation and far enough away from the code to enable refactoring + # with minimal changes to the existing specs. + # + # == Isolation mode (default) + # + # No dependencies on views because none are ever rendered. The + # benefit of this mode is that can spec the controller completely + # independent of the view, allowing that responsibility to be + # handled later, or by somebody else. Combined w/ separate view + # specs, this also provides better fault isolation. + # + # == Integration mode + # + # To run in this mode, include the +integrate_views+ declaration + # in your controller context: + # + # describe ThingController do + # integrate_views + # ... + # + # In this mode, controller specs are run in the same way that + # rails functional tests run - one set of tests for both the + # controllers and the views. The benefit of this approach is that + # you get wider coverage from each spec. Experienced rails + # developers may find this an easier approach to begin with, however + # we encourage you to explore using the isolation mode and revel + # in its benefits. + # + # == Expecting Errors + # + # Rspec on Rails will raise errors that occur in controller actions. + # In contrast, Rails will swallow errors that are raised in controller + # actions and return an error code in the header. If you wish to override + # Rspec and have Rail's default behaviour,tell the controller to use + # rails error handling ... + # + # before(:each) do + # controller.use_rails_error_handling! + # end + # + # When using Rail's error handling, you can expect error codes in headers ... + # + # it "should return an error in the header" do + # response.should be_error + # end + # + # it "should return a 501" do + # response.response_code.should == 501 + # end + # + # it "should return a 501" do + # response.code.should == "501" + # end + class ControllerExample < FunctionalExample + class << self + # Use this to instruct RSpec to render views in your controller examples (Integration Mode). + # + # describe ThingController do + # integrate_views + # ... + # + # See Spec::Rails::Example::ControllerExample for more information about + # Integration and Isolation modes. + def integrate_views + @integrate_views = true + end + def integrate_views? # :nodoc: + @integrate_views + end + + # You MUST provide a controller_name within the context of + # your controller specs: + # + # describe "ThingController" do + # controller_name :thing + # ... + def controller_name(name) + @controller_class_name = "#{name}_controller".camelize + end + attr_accessor :controller_class_name # :nodoc: + end + + before(:each) do + # Some Rails apps explicitly disable ActionMailer in environment.rb + if defined?(ActionMailer) + @deliveries = [] + ActionMailer::Base.deliveries = @deliveries + end + + unless @controller.class.ancestors.include?(ActionController::Base) + Spec::Expectations.fail_with <<-EOE + You have to declare the controller name in controller specs. For example: + describe "The ExampleController" do + controller_name "example" #invokes the ExampleController + end + EOE + end + @controller.metaclass.class_eval do + def controller_path #:nodoc: + self.class.name.underscore.gsub('_controller', '') + end + include ControllerInstanceMethods + end + @controller.integrate_views! if @integrate_views + @controller.session = session + end + + attr_reader :response, :request, :controller + + def initialize(example) + super + controller_class_name = self.class.controller_class_name + if controller_class_name + @controller_class_name = controller_class_name.to_s + else + @controller_class_name = self.class.described_type.to_s + end + @integrate_views = self.class.integrate_views? + end + + # Uses ActionController::Routing::Routes to generate + # the correct route for a given set of options. + # == Example + # route_for(:controller => 'registrations', :action => 'edit', :id => 1) + # => '/registrations/1;edit' + def route_for(options) + ensure_that_routes_are_loaded + ActionController::Routing::Routes.generate(options) + end + + # Uses ActionController::Routing::Routes to parse + # an incoming path so the parameters it generates can be checked + # == Example + # params_from(:get, '/registrations/1;edit') + # => :controller => 'registrations', :action => 'edit', :id => 1 + def params_from(method, path) + ensure_that_routes_are_loaded + ActionController::Routing::Routes.recognize_path(path, :method => method) + end + + protected + def _controller_ivar_proxy + @controller_ivar_proxy ||= AssignsHashProxy.new @controller + end + + private + def ensure_that_routes_are_loaded + ActionController::Routing::Routes.reload if ActionController::Routing::Routes.empty? + end + + module ControllerInstanceMethods #:nodoc: + include Spec::Rails::Example::RenderObserver + + # === render(options = nil, deprecated_status = nil, &block) + # + # This gets added to the controller's singleton meta class, + # allowing Controller Examples to run in two modes, freely switching + # from context to context. + def render(options=nil, deprecated_status=nil, &block) + unless block_given? + unless integrate_views? + @template.metaclass.class_eval do + define_method :file_exists? do + true + end + define_method :render_file do |*args| + @first_render ||= args[0] + end + end + end + end + + if expect_render_mock_proxy.send(:__mock_proxy).send(:find_matching_expectation, :render, options) + expect_render_mock_proxy.render(options) + @performed_render = true + else + unless expect_render_mock_proxy.send(:__mock_proxy).send(:find_matching_method_stub, :render, options) + super(options, deprecated_status, &block) + end + end + end + + if self.respond_to?(:should_receive) && self.respond_to?(:stub!) + self.send :alias_method, :orig_should_receive, :should_receive + self.send :alias_method, :orig_stub!, :stub! + def raise_with_disable_message(old_method, new_method) + raise %Q| + controller.#{old_method}(:render) has been disabled because it + can often produce unexpected results. Instead, you should + use the following (before the action): + + controller.#{new_method}(*args) + + See the rdoc for #{new_method} for more information. + | + end + def should_receive(*args) + if args[0] == :render + raise_with_disable_message("should_receive", "expect_render") + else + orig_should_receive(*args) + end + end + def stub!(*args) + if args[0] == :render + raise_with_disable_message("stub!", "stub_render") + else + orig_stub!(*args) + end + end + end + + def response(&block) + # NOTE - we're setting @update for the assert_select_spec - kinda weird, huh? + @update = block + @_response || @response + end + + def integrate_views! + @integrate_views = true + end + + private + + def integrate_views? + @integrate_views + end + end + + Spec::Example::ExampleGroupFactory.register(:controller, self) + end + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/lib/spec/rails/example/behaviour/functional_example.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/lib/spec/rails/example/behaviour/functional_example.rb --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/lib/spec/rails/example/behaviour/functional_example.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/lib/spec/rails/example/behaviour/functional_example.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,66 @@ +module Spec + module Rails + module Example + class FunctionalExample < RailsExample + include ActionController::TestProcess + include ActionController::Assertions + + attr_reader :request, :response + before(:each) do + @controller_class = Object.path2class @controller_class_name + raise "Can't determine controller class for #{@controller_class_name}" if @controller_class.nil? + + @controller = @controller_class.new + + @request = ActionController::TestRequest.new + @response = ActionController::TestResponse.new + end + + def params + request.parameters + end + + def flash + response.flash + end + + def session + request.session + end + + # :call-seq: + # assigns() + # + # Hash of instance variables to values that are made available to views. + # == Examples + # + # #in thing_controller.rb + # def new + # @thing = Thing.new + # end + # + # #in thing_controller_spec + # get 'new' + # assigns[:registration].should == Thing.new + #-- + # NOTE - Even though docs say only use assigns[:key] format, but allowing assigns(:key) + # in order to avoid breaking old specs. + #++ + def assigns(key = nil) + if key.nil? + @controller.assigns + _controller_ivar_proxy + else + @controller.assigns[key] + _controller_ivar_proxy[key] + end + end + + protected + def _controller_ivar_proxy + @controller_ivar_proxy ||= IvarProxy.new @controller + end + end + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/lib/spec/rails/example/behaviour/helper_example.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/lib/spec/rails/example/behaviour/helper_example.rb --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/lib/spec/rails/example/behaviour/helper_example.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/lib/spec/rails/example/behaviour/helper_example.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,81 @@ +module Spec + module Rails + module Example + # Helper Specs live in $RAILS_ROOT/spec/helpers/. + # + # Helper Specs use Spec::Rails::Example::HelperExample, which allows you to + # include your Helper directly in the context and write specs directly + # against its methods. + # + # HelperExample also includes the standard lot of ActionView::Helpers in case your + # helpers rely on any of those. + # + # == Example + # + # class ThingHelper + # def number_of_things + # Thing.count + # end + # end + # + # describe "ThingHelper behaviour" do + # include ThingHelper + # it "should tell you the number of things" do + # Thing.should_receive(:count).and_return(37) + # number_of_things.should == 37 + # end + # end + class HelperExample < FunctionalExample + class << self + # The helper name.... + def helper_name(name=nil) + send :include, "#{name}_helper".camelize.constantize + end + end + + ActionView::Base.included_modules.each do |mod| + include mod if mod.parents.include?(ActionView::Helpers) + end + ActionController::Routing::Routes.named_routes.install(self) + + before(:all) do + @controller_class_name = 'Spec::Rails::Example::HelperBehaviourController' + end + + before(:each) do + @controller.request = @request + @controller.url = ActionController::UrlRewriter.new @request, {} # url_for + + @flash = ActionController::Flash::FlashHash.new + session['flash'] = @flash + + ActionView::Helpers::AssetTagHelper::reset_javascript_include_default + end + + def flash + @flash + end + + def eval_erb(text) + ERB.new(text).result(binding) + end + + + # TODO: BT - Helper Examples should proxy method_missing to a Rails View instance. + # When that is done, remove this method + def protect_against_forgery? + false + end + + Spec::Example::ExampleGroupFactory.register(:helper, self) + end + + class HelperBehaviourController < ApplicationController #:nodoc: + attr_accessor :request, :url + + # Re-raise errors + def rescue_action(e); raise e; end + end + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/lib/spec/rails/example/behaviour/model_example.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/lib/spec/rails/example/behaviour/model_example.rb --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/lib/spec/rails/example/behaviour/model_example.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/lib/spec/rails/example/behaviour/model_example.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,14 @@ +module Spec + module Rails + module Example + # Model examples live in $RAILS_ROOT/spec/models/. + # + # Model examples use Spec::Rails::Example::ModelExample, which + # provides support for fixtures and some custom expectations via extensions + # to ActiveRecord::Base. + class ModelExample < RailsExample + Spec::Example::ExampleGroupFactory.register(:model, self) + end + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/lib/spec/rails/example/behaviour/rails_example.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/lib/spec/rails/example/behaviour/rails_example.rb --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/lib/spec/rails/example/behaviour/rails_example.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/lib/spec/rails/example/behaviour/rails_example.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,86 @@ +require 'spec/extensions/test' + +ActionView::Base.cache_template_extensions = false + +module Spec + module Rails + module Example + class RailsExample < Test::Unit::TestCase::ExampleGroup + cattr_accessor( + :fixture_path, + :use_transactional_fixtures, + :use_instantiated_fixtures, + :global_fixtures + ) + + class << self + def before_eval #:nodoc: + super + configure + end + + def configure + self.fixture_table_names = [] + self.fixture_class_names = {} + self.use_transactional_fixtures = Spec::Runner.configuration.use_transactional_fixtures + self.use_instantiated_fixtures = Spec::Runner.configuration.use_instantiated_fixtures + self.fixture_path = Spec::Runner.configuration.fixture_path + self.global_fixtures = Spec::Runner.configuration.global_fixtures + self.fixtures(self.global_fixtures) if self.global_fixtures + end + end + + before(:each) {setup} + after(:each) {teardown} + + include Spec::Rails::Matchers + + @@model_id = 1000 + # Creates a mock object instance for a +model_class+ with common + # methods stubbed out. + # Additional methods may be easily stubbed (via add_stubs) if +stubs+ is passed. + def mock_model(model_class, options_and_stubs = {}) + null = options_and_stubs.delete(:null_object) + stubs = options_and_stubs + id = @@model_id + @@model_id += 1 + m = mock("#{model_class.name}_#{id}", :null_object => null) + m.stub!(:id).and_return(id) + m.stub!(:to_param).and_return(id.to_s) + m.stub!(:new_record?).and_return(false) + m.stub!(:errors).and_return(stub("errors", :count => 0)) + m.send(:__mock_proxy).instance_eval <<-CODE + def @target.is_a?(other) + #{model_class}.ancestors.include?(other) + end + def @target.kind_of?(other) + #{model_class}.ancestors.include?(other) + end + def @target.instance_of?(other) + other == #{model_class} + end + def @target.class + #{model_class} + end + CODE + add_stubs(m, stubs) + yield m if block_given? + m + end + + #-- + # TODO - Shouldn't this just be an extension of stub! ?? + # - object.stub!(:method => return_value, :method2 => return_value2, :etc => etc) + #++ + # Stubs methods on +object+ (if +object+ is a symbol or string a new mock + # with that name will be created). +stubs+ is a Hash of method=>value + def add_stubs(object, stubs = {}) #:nodoc: + m = [String, Symbol].index(object.class) ? mock(object.to_s) : object + stubs.each {|k,v| m.stub!(k).and_return(v)} + m + end + Spec::Example::ExampleGroupFactory.register(:default, self) + end + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/lib/spec/rails/example/behaviour/render_observer.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/lib/spec/rails/example/behaviour/render_observer.rb --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/lib/spec/rails/example/behaviour/render_observer.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/lib/spec/rails/example/behaviour/render_observer.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,90 @@ +require 'spec/mocks' + +module Spec + module Rails + module Example + # Provides specialized mock-like behaviour for controller and view examples, + # allowing you to mock or stub calls to render with specific arguments while + # ignoring all other calls. + module RenderObserver + + # Similar to mocking +render+ with the exception that calls to +render+ with + # any other options are passed on to the receiver (i.e. controller in + # controller examples, template in view examples). + # + # This is necessary because Rails uses the +render+ method on both + # controllers and templates as a dispatcher to render different kinds of + # things, sometimes resulting in many calls to the render method within one + # request. This approach makes it impossible to use a normal mock object, which + # is designed to observe all incoming messages with a given name. + # + # +expect_render+ is auto-verifying, so failures will be reported without + # requiring you to explicitly request verification. + # + # Also, +expect_render+ uses parts of RSpec's mock expectation framework. Because + # it wraps only a subset of the framework, using this will create no conflict with + # other mock frameworks if you choose to use them. Additionally, the object returned + # by expect_render is an RSpec mock object, which means that you can call any of the + # chained methods available in RSpec's mocks. + # + # == Controller Examples + # + # controller.expect_render(:partial => 'thing', :object => thing) + # controller.expect_render(:partial => 'thing', :collection => things).once + # + # controller.stub_render(:partial => 'thing', :object => thing) + # controller.stub_render(:partial => 'thing', :collection => things).twice + # + # == View Examples + # + # template.expect_render(:partial => 'thing', :object => thing) + # template.expect_render(:partial => 'thing', :collection => things) + # + # template.stub_render(:partial => 'thing', :object => thing) + # template.stub_render(:partial => 'thing', :collection => things) + # + def expect_render(opts={}) + register_verify_after_each + expect_render_mock_proxy.should_receive(:render, :expected_from => caller(1)[0]).with(opts) + end + + # This is exactly like expect_render, with the exception that the call to render will not + # be verified. Use this if you are trying to isolate your example from a complicated render + # operation but don't care whether it is called or not. + def stub_render(opts={}) + register_verify_after_each + expect_render_mock_proxy.stub!(:render, :expected_from => caller(1)[0]).with(opts) + end + + def verify_rendered # :nodoc: + expect_render_mock_proxy.rspec_verify + end + + def unregister_verify_after_each #:nodoc: + proc = verify_rendered_proc + Spec::Example::ExampleGroup.remove_after(:each, &proc) + end + + protected + + def verify_rendered_proc #:nodoc: + template = self + @verify_rendered_proc ||= Proc.new do + template.verify_rendered + template.unregister_verify_after_each + end + end + + def register_verify_after_each #:nodoc: + proc = verify_rendered_proc + Spec::Example::ExampleGroup.after(:each, &proc) + end + + def expect_render_mock_proxy #:nodoc: + @expect_render_mock_proxy ||= Spec::Mocks::Mock.new("expect_render_mock_proxy") + end + + end + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/lib/spec/rails/example/behaviour/view_example.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/lib/spec/rails/example/behaviour/view_example.rb --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/lib/spec/rails/example/behaviour/view_example.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/lib/spec/rails/example/behaviour/view_example.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,172 @@ +module Spec + module Rails + module Example + # View Examples live in $RAILS_ROOT/spec/views/. + # + # View Specs use Spec::Rails::Example::ViewExample, + # which provides access to views without invoking any of your controllers. + # See Spec::Rails::Expectations::Matchers for information about specific + # expectations that you can set on views. + # + # == Example + # + # describe "login/login" do + # before do + # render 'login/login' + # end + # + # it "should display login form" do + # response.should have_tag("form[action=/login]") do + # with_tag("input[type=text][name=email]") + # with_tag("input[type=password][name=password]") + # with_tag("input[type=submit][value=Login]") + # end + # end + # end + class ViewExample < FunctionalExample + before(:each) do + ensure_that_flash_and_session_work_properly + end + + def initialize(example) #:nodoc: + super + @controller_class_name = "Spec::Rails::Example::ViewExampleController" + end + + def ensure_that_flash_and_session_work_properly #:nodoc: + @controller.send :initialize_template_class, @response + @controller.send :assign_shortcuts, @request, @response + @session = @controller.session + @controller.class.send :public, :flash + end + + def teardown #:nodoc: + super + ensure_that_base_view_path_is_not_set_across_behaviours + end + + def ensure_that_base_view_path_is_not_set_across_behaviours #:nodoc: + ActionView::Base.base_view_path = nil + end + + def set_base_view_path(options) #:nodoc: + ActionView::Base.base_view_path = base_view_path(options) + end + + def base_view_path(options) #:nodoc: + "/#{derived_controller_name(options)}/" + end + + def derived_controller_name(options) #:nodoc: + parts = subject_of_render(options).split('/').reject { |part| part.empty? } + "#{parts[0..-2].join('/')}" + end + + def derived_action_name(options) #:nodoc: + parts = subject_of_render(options).split('/').reject { |part| part.empty? } + "#{parts.last}" + end + + def subject_of_render(options) #:nodoc: + [:template, :partial, :file].each do |render_type| + if options.has_key?(render_type) + return options[render_type] + end + end + raise Exception.new("Unhandled render type in view spec.") + end + + def add_helpers(options) #:nodoc: + @controller.add_helper("application") + @controller.add_helper(derived_controller_name(options)) + @controller.add_helper(options[:helper]) if options[:helper] + options[:helpers].each { |helper| @controller.add_helper(helper) } if options[:helpers] + end + + # Renders a template for a View Spec, which then provides access to the result + # through the +response+. + # + # == Examples + # + # render('/people/list') + # render('/people/list', :helper => MyHelper) + # render('/people/list', :helpers => [MyHelper, MyOtherHelper]) + # render(:partial => '/people/_address') + # + # See Spec::Rails::Example::ViewExample for more information. + def render(*args) + options = Hash === args.last ? args.pop : {} + options[:template] = args.first.to_s unless args.empty? + + set_base_view_path(options) + add_helpers(options) + + assigns[:action_name] = @action_name + + @request.path_parameters = { + :controller => derived_controller_name(options), + :action => derived_action_name(options) + } + + defaults = { :layout => false } + options = defaults.merge options + + @controller.instance_variable_set :@params, @request.parameters + + @controller.send :initialize_current_url + + @controller.class.instance_eval %{ + def controller_path + "#{derived_controller_name(options)}" + end + + def controller_name + "#{derived_controller_name(options).split('/').last}" + end + } + + @controller.send :forget_variables_added_to_assigns + @controller.send :render, options + @controller.send :process_cleanup + end + + # This provides the template. Use this to set mock + # expectations for dealing with partials + # + # == Example + # + # describe "/person/new" do + # it "should use the form partial" do + # template.should_receive(:render).with(:partial => 'form') + # render "/person/new" + # end + # end + def template + @controller.template + end + + Spec::Example::ExampleGroupFactory.register(:view, self) + end + + class ViewExampleController < ApplicationController #:nodoc: + include Spec::Rails::Example::RenderObserver + attr_reader :template + + def add_helper_for(template_path) + add_helper(template_path.split('/')[0]) + end + + def add_helper(name) + begin + helper_module = "#{name}_helper".camelize.constantize + rescue + return + end + template.metaclass.class_eval do + include helper_module + end + end + end + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/lib/spec/rails/example/behaviour.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/lib/spec/rails/example/behaviour.rb --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/lib/spec/rails/example/behaviour.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/lib/spec/rails/example/behaviour.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,7 @@ +require "spec/rails/example/behaviour/render_observer" +require "spec/rails/example/behaviour/rails_example" +require "spec/rails/example/behaviour/model_example" +require "spec/rails/example/behaviour/functional_example" +require "spec/rails/example/behaviour/controller_example" +require "spec/rails/example/behaviour/helper_example" +require "spec/rails/example/behaviour/view_example" diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/lib/spec/rails/example/ivar_proxy.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/lib/spec/rails/example/ivar_proxy.rb --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/lib/spec/rails/example/ivar_proxy.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/lib/spec/rails/example/ivar_proxy.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,62 @@ +## +# A wrapper that allows instance variables to be manipulated using +[]+ and +# +[]=+ + +module Spec + module Rails + module Example + class IvarProxy #:nodoc: + + ## + # Wraps +object+ allowing its instance variables to be manipulated. + + def initialize(object) + @object = object + end + + ## + # Retrieves +ivar+ from the wrapped object. + + def [](ivar) + get_variable "@#{ivar}" + end + + ## + # Sets +ivar+ to +val+ on the wrapped object. + + def []=(ivar, val) + set_variable "@#{ivar}", val + end + + def each + @object.instance_variables.each do |variable_full_name| + variable_name = variable_full_name[1...variable_full_name.length] + yield variable_name, get_variable(variable_full_name) + end + end + + def delete(key) + var_name = "@#{key}" + if @object.instance_variables.include?(var_name) + @object.send(:remove_instance_variable, var_name) + else + return nil + end + end + + def has_key?(key) + @object.instance_variables.include?("@#{key}") + end + + protected + def get_variable(name) + @object.instance_variable_get name + end + + def set_variable(name, value) + @object.instance_variable_set name, value + end + end + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/lib/spec/rails/example.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/lib/spec/rails/example.rb --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/lib/spec/rails/example.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/lib/spec/rails/example.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,40 @@ +dir = File.dirname(__FILE__) + +require 'spec/rails/example/ivar_proxy' +require 'spec/rails/example/assigns_hash_proxy' +require 'spec/rails/example/behaviour' + +module Spec + module Rails + # Spec::Rails::Example extends Spec::Example (RSpec's core Example module) to provide + # Rails-specific contexts for describing Rails Models, Views, Controllers and Helpers. + # + # == Model Examples + # + # These are the equivalent of unit tests in Rails' built in testing. Ironically (for the traditional TDD'er) these are the only specs that we feel should actually interact with the database. + # + # See Spec::Rails::Example::ModelExample + # + # == Controller Examples + # + # These align somewhat with functional tests in rails, except that they do not actually render views (though you can force rendering of views if you prefer). Instead of setting expectations about what goes on a page, you set expectations about what templates get rendered. + # + # See Spec::Rails::Example::ControllerExample + # + # == View Examples + # + # This is the other half of Rails functional testing. View specs allow you to set up assigns and render + # a template. By assigning mock model data, you can specify view behaviour with no dependency on a database + # or your real models. + # + # See Spec::Rails::Example::ViewExample + # + # == Helper Examples + # + # These let you specify directly methods that live in your helpers. + # + # See Spec::Rails::Example::HelperExample + module Example + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/lib/spec/rails/extensions/action_controller/base.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/lib/spec/rails/extensions/action_controller/base.rb --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/lib/spec/rails/extensions/action_controller/base.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/lib/spec/rails/extensions/action_controller/base.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,14 @@ +module ActionController + class Base + class << self + def set_view_path(path) + [:append_view_path, :view_paths=, :template_root=].each do |method| + if respond_to?(method) + return send(method, path) + end + end + end + end + end +end + diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/lib/spec/rails/extensions/action_controller/rescue.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/lib/spec/rails/extensions/action_controller/rescue.rb --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/lib/spec/rails/extensions/action_controller/rescue.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/lib/spec/rails/extensions/action_controller/rescue.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,21 @@ +module ActionController + module Rescue + def use_rails_error_handling! + @use_rails_error_handling = true + end + + def use_rails_error_handling? + @use_rails_error_handling ||= false + end + + protected + def rescue_action_with_fast_errors(exception) + if use_rails_error_handling? + rescue_action_without_fast_errors exception + else + raise exception + end + end + alias_method_chain :rescue_action, :fast_errors + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/lib/spec/rails/extensions/action_controller/test_response.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/lib/spec/rails/extensions/action_controller/test_response.rb --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/lib/spec/rails/extensions/action_controller/test_response.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/lib/spec/rails/extensions/action_controller/test_response.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,11 @@ +module ActionController #:nodoc: + class TestResponse #:nodoc: + attr_writer :controller_path + + def capture(name) + template.instance_variable_get "@content_for_#{name.to_s}" + end + alias [] capture + + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/lib/spec/rails/extensions/action_view/base.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/lib/spec/rails/extensions/action_view/base.rb --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/lib/spec/rails/extensions/action_view/base.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/lib/spec/rails/extensions/action_view/base.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,27 @@ +module ActionView #:nodoc: + class Base #:nodoc: + include Spec::Rails::Example::RenderObserver + cattr_accessor :base_view_path + def render_partial(partial_path, local_assigns = nil, deprecated_local_assigns = nil) #:nodoc: + if partial_path.is_a?(String) + unless partial_path.include?("/") + unless self.class.base_view_path.nil? + partial_path = "#{self.class.base_view_path}/#{partial_path}" + end + end + end + super(partial_path, local_assigns, deprecated_local_assigns) + end + + alias_method :orig_render, :render + def render(options = {}, old_local_assigns = {}, &block) + if expect_render_mock_proxy.send(:__mock_proxy).send(:find_matching_expectation, :render, options) + expect_render_mock_proxy.render(options) + else + unless expect_render_mock_proxy.send(:__mock_proxy).send(:find_matching_method_stub, :render, options) + orig_render(options, old_local_assigns, &block) + end + end + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/lib/spec/rails/extensions/active_record/base.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/lib/spec/rails/extensions/active_record/base.rb --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/lib/spec/rails/extensions/active_record/base.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/lib/spec/rails/extensions/active_record/base.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,29 @@ +module ActiveRecord #:nodoc: + class Base + + (class << self; self; end).class_eval do + # Extension for should have on AR Model classes + # + # ModelClass.should have(:no).records + # ModelClass.should have(1).record + # ModelClass.should have(n).records + def records + find(:all) + end + alias :record :records + end + + # Extension for should have on AR Model instances + # + # model.should have(:no).errors_on(:attribute) + # model.should have(1).error_on(:attribute) + # model.should have(n).errors_on(:attribute) + def errors_on(attribute) + self.valid? + [self.errors.on(attribute)].flatten.compact + end + alias :error_on :errors_on + + end +end + diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/lib/spec/rails/extensions/object.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/lib/spec/rails/extensions/object.rb --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/lib/spec/rails/extensions/object.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/lib/spec/rails/extensions/object.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,5 @@ +class Object # :nodoc: + def self.path2class(klassname) + klassname.split('::').inject(Object) { |k,n| k.const_get n } + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/lib/spec/rails/extensions/spec/example/configuration.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/lib/spec/rails/extensions/spec/example/configuration.rb --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/lib/spec/rails/extensions/spec/example/configuration.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/lib/spec/rails/extensions/spec/example/configuration.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,33 @@ +require 'spec/example/configuration' + +module Spec + module Example + class Configuration + attr_writer :use_transactional_fixtures, :use_instantiated_fixtures, :global_fixtures + + def initialize + super + Test::Unit::TestCase.fixture_path = RAILS_ROOT + '/spec/fixtures' + end + + def use_transactional_fixtures + @use_transactional_fixtures.nil? ? @use_transactional_fixtures = true : @use_transactional_fixtures + end + + def use_instantiated_fixtures + @use_instantiated_fixtures ||= false + end + + def fixture_path + Test::Unit::TestCase.fixture_path + end + def fixture_path=(path) + Test::Unit::TestCase.fixture_path = path + end + + def global_fixtures + @global_fixtures ||= [] + end + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/lib/spec/rails/extensions/spec/matchers/have.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/lib/spec/rails/extensions/spec/matchers/have.rb --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/lib/spec/rails/extensions/spec/matchers/have.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/lib/spec/rails/extensions/spec/matchers/have.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,21 @@ +require 'spec/matchers/have' + +module Spec #:nodoc: + module Matchers #:nodoc: + class Have #:nodoc: + alias_method :__original_failure_message, :failure_message + def failure_message + return "expected #{relativities[@relativity]}#{@expected} errors on :#{@args[0]}, got #{@actual}" if @collection_name == :errors_on + return "expected #{relativities[@relativity]}#{@expected} error on :#{@args[0]}, got #{@actual}" if @collection_name == :error_on + return __original_failure_message + end + + alias_method :__original_description, :description + def description + return "should have #{relativities[@relativity]}#{@expected} errors on :#{@args[0]}" if @collection_name == :errors_on + return "should have #{relativities[@relativity]}#{@expected} error on :#{@args[0]}" if @collection_name == :error_on + return __original_description + end + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/lib/spec/rails/extensions.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/lib/spec/rails/extensions.rb --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/lib/spec/rails/extensions.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/lib/spec/rails/extensions.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,12 @@ +require 'spec' + +require 'spec/rails/extensions/object' + +require 'spec/rails/extensions/spec/example/configuration' +require 'spec/rails/extensions/spec/matchers/have' + +require 'spec/rails/extensions/active_record/base' +require 'spec/rails/extensions/action_controller/base' +require 'spec/rails/extensions/action_controller/rescue' +require 'spec/rails/extensions/action_controller/test_response' +require 'spec/rails/extensions/action_view/base' diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/lib/spec/rails/matchers/assert_select.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/lib/spec/rails/matchers/assert_select.rb --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/lib/spec/rails/matchers/assert_select.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/lib/spec/rails/matchers/assert_select.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,130 @@ +# This is a wrapper of assert_select for rspec. + +module Spec # :nodoc: + module Rails + module Matchers + + class AssertSelect #:nodoc: + + def initialize(assertion, spec_scope, *args, &block) + @assertion = assertion + @spec_scope = spec_scope + @args = args + @block = block + end + + def matches?(response_or_text, &block) + if ActionController::TestResponse === response_or_text and + response_or_text.headers.key?('Content-Type') and + response_or_text.headers['Content-Type'].to_sym == :xml + @args.unshift(HTML::Document.new(response_or_text.body, false, true).root) + elsif String === response_or_text + @args.unshift(HTML::Document.new(response_or_text).root) + end + @block = block if block + begin + @spec_scope.send(@assertion, *@args, &@block) + rescue ::Test::Unit::AssertionFailedError => @error + end + + @error.nil? + end + + def failure_message; @error.message; end + def negative_failure_message; "should not #{description}, but did"; end + + def description + { + :assert_select => "have tag#{format_args(*@args)}", + :assert_select_email => "send email#{format_args(*@args)}", + }[@assertion] + end + + private + + def format_args(*args) + return "" if args.empty? + return "(#{arg_list(*args)})" + end + + def arg_list(*args) + args.collect do |arg| + arg.respond_to?(:description) ? arg.description : arg.inspect + end.join(", ") + end + + end + + # :call-seq: + # response.should have_tag(*args, &block) + # string.should have_tag(*args, &block) + # + # wrapper for assert_select with additional support for using + # css selectors to set expectation on Strings. Use this in + # helper specs, for example, to set expectations on the results + # of helper methods. + # + # == Examples + # + # # in a controller spec + # response.should have_tag("div", "some text") + # + # # in a helper spec (person_address_tag is a method in the helper) + # person_address_tag.should have_tag("input#person_address") + # + # see documentation for assert_select at http://api.rubyonrails.org/ + def have_tag(*args, &block) + AssertSelect.new(:assert_select, self, *args, &block) + end + + # wrapper for a nested assert_select + # + # response.should have_tag("div#form") do + # with_tag("input#person_name[name=?]", "person[name]") + # end + # + # see documentation for assert_select at http://api.rubyonrails.org/ + def with_tag(*args, &block) + should have_tag(*args, &block) + end + + # wrapper for a nested assert_select with false + # + # response.should have_tag("div#1") do + # without_tag("span", "some text that shouldn't be there") + # end + # + # see documentation for assert_select at http://api.rubyonrails.org/ + def without_tag(*args, &block) + should_not have_tag(*args, &block) + end + + # :call-seq: + # response.should have_rjs(*args, &block) + # + # wrapper for assert_select_rjs + # + # see documentation for assert_select_rjs at http://api.rubyonrails.org/ + def have_rjs(*args, &block) + AssertSelect.new(:assert_select_rjs, self, *args, &block) + end + + # :call-seq: + # response.should send_email(*args, &block) + # + # wrapper for assert_select_email + # + # see documentation for assert_select_email at http://api.rubyonrails.org/ + def send_email(*args, &block) + AssertSelect.new(:assert_select_email, self, *args, &block) + end + + # wrapper for assert_select_encoded + # + # see documentation for assert_select_encoded at http://api.rubyonrails.org/ + def with_encoded(*args, &block) + should AssertSelect.new(:assert_select_encoded, self, *args, &block) + end + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/lib/spec/rails/matchers/have_text.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/lib/spec/rails/matchers/have_text.rb --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/lib/spec/rails/matchers/have_text.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/lib/spec/rails/matchers/have_text.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,55 @@ +module Spec + module Rails + module Matchers + + class HaveText #:nodoc: + + def initialize(expected) + @expected = expected + end + + def matches?(response) + @actual = response.body + return actual =~ expected if Regexp === expected + return actual == expected unless Regexp === expected + end + + def failure_message + "expected #{expected.inspect}, got #{actual.inspect}" + end + + def negative_failure_message + "expected not to have text #{expected.inspect}" + end + + def to_s + "have text #{expected.inspect}" + end + + private + attr_reader :expected + attr_reader :actual + + end + + # :call-seq: + # response.should have_text(expected) + # response.should_not have_text(expected) + # + # Accepts a String or a Regexp, matching a String using == + # and a Regexp using =~. + # + # Use this instead of response.should have_tag() + # when you either don't know or don't care where on the page + # this text appears. + # + # == Examples + # + # response.should have_text("This is the expected text") + def have_text(text) + HaveText.new(text) + end + + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/lib/spec/rails/matchers/redirect_to.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/lib/spec/rails/matchers/redirect_to.rb --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/lib/spec/rails/matchers/redirect_to.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/lib/spec/rails/matchers/redirect_to.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,114 @@ +module Spec + module Rails + module Matchers + + class RedirectTo #:nodoc: + + def initialize(request, expected) + @expected = expected + @request = request + end + + def matches?(response) + @redirected = response.redirect? + @actual = response.redirect_url + return false unless @redirected + if @expected.instance_of? Hash + return false unless @actual =~ %r{^\w+://#{@request.host}} + return false unless actual_redirect_to_valid_route + return actual_hash == expected_hash + else + return @actual == expected_url + end + end + + def actual_hash + hash_from_url @actual + end + + def expected_hash + hash_from_url expected_url + end + + def actual_redirect_to_valid_route + actual_hash + end + + def hash_from_url(url) + query_hash(url).merge(path_hash(url)).with_indifferent_access + end + + def path_hash(url) + path = url.sub(%r{^\w+://#{@request.host}}, "").split("?", 2)[0] + path = path.split("/")[1..-1] if ::Rails::VERSION::MINOR < 2 + ActionController::Routing::Routes.recognize_path path + end + + def query_hash(url) + query = url.split("?", 2)[1] || "" + QueryParameterParser.parse_query_parameters(query, @request) + end + + def expected_url + case @expected + when Hash + return ActionController::UrlRewriter.new(@request, {}).rewrite(@expected) + when :back + return @request.env['HTTP_REFERER'] + when %r{^\w+://.*} + return @expected + else + return "http://#{@request.host}" + (@expected.split('')[0] == '/' ? '' : '/') + @expected + end + end + + def failure_message + if @redirected + return %Q{expected redirect to #{@expected.inspect}, got redirect to #{@actual.inspect}} + else + return %Q{expected redirect to #{@expected.inspect}, got no redirect} + end + end + + def negative_failure_message + return %Q{expected not to be redirected to #{@expected.inspect}, but was} if @redirected + end + + def description + "redirect to #{@actual.inspect}" + end + + class QueryParameterParser + def self.parse_query_parameters(query, request) + if defined?(CGIMethods) + CGIMethods.parse_query_parameters(query) + else + request.class.parse_query_parameters(query) + end + end + end + end + + # :call-seq: + # response.should redirect_to(url) + # response.should redirect_to(:action => action_name) + # response.should redirect_to(:controller => controller_name, :action => action_name) + # response.should_not redirect_to(url) + # response.should_not redirect_to(:action => action_name) + # response.should_not redirect_to(:controller => controller_name, :action => action_name) + # + # Passes if the response is a redirect to the url, action or controller/action. + # Useful in controller specs (integration or isolation mode). + # + # == Examples + # + # response.should redirect_to("path/to/action") + # response.should redirect_to("http://test.host/path/to/action") + # response.should redirect_to(:action => 'list') + def redirect_to(opts) + RedirectTo.new(request, opts) + end + end + + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/lib/spec/rails/matchers/render_template.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/lib/spec/rails/matchers/render_template.rb --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/lib/spec/rails/matchers/render_template.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/lib/spec/rails/matchers/render_template.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,66 @@ +module Spec + module Rails + module Matchers + + class RenderTemplate #:nodoc: + + def initialize(expected, controller) + @controller = controller + @expected = expected + end + + def matches?(response) + @actual = response.rendered_file + full_path(@actual) == full_path(@expected) + end + + def failure_message + "expected #{@expected.inspect}, got #{@actual.inspect}" + end + + def description + "render template #{@expected.inspect}" + end + + private + def full_path(path) + return nil if path.nil? + path.include?('/') ? path : "#{@controller.class.to_s.underscore.gsub('_controller','')}/#{path}" + end + + end + + # :call-seq: + # response.should render_template(path) + # response.should_not render_template(path) + # + # Passes if the specified template is rendered by the response. + # Useful in controller specs (integration or isolation mode). + # + # path can include the controller path or not. It + # can also include an optional extension (no extension assumes .rhtml). + # + # Note that partials must be spelled with the preceding underscore. + # + # == Examples + # + # response.should render_template('list') + # response.should render_template('same_controller/list') + # response.should render_template('other_controller/list') + # + # #rjs + # response.should render_template('list.rjs') + # response.should render_template('same_controller/list.rjs') + # response.should render_template('other_controller/list.rjs') + # + # #partials + # response.should render_template('_a_partial') + # response.should render_template('same_controller/_a_partial') + # response.should render_template('other_controller/_a_partial') + def render_template(path) + RenderTemplate.new(path.to_s, @controller) + end + + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/lib/spec/rails/matchers.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/lib/spec/rails/matchers.rb --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/lib/spec/rails/matchers.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/lib/spec/rails/matchers.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,29 @@ +dir = File.dirname(__FILE__) +require 'spec/rails/matchers/assert_select' +require 'spec/rails/matchers/have_text' +require 'spec/rails/matchers/redirect_to' +require 'spec/rails/matchers/render_template' + +module Spec + module Rails + # Spec::Rails::Expectations::Matchers provides several expectation matchers + # intended to work with Rails components like models and responses. For example: + # + # response.should redirect_to("some/url") #redirect_to(url) is the matcher. + # + # In addition to those you see below, the arbitrary predicate feature of RSpec + # makes the following available as well: + # + # response.should be_success #passes if response.success? + # response.should be_redirect #passes if response.redirect? + # + # Note that many of these matchers are part of a wrapper of assert_select, so + # the documentation comes straight from that with some slight modifications. + # assert_select is a Test::Unit extension originally contributed to the + # Rails community as a plugin by Assaf Arkin and eventually shipped as part of Rails. + # + # For more info on assert_select, see the relevant Rails documentation. + module Matchers + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/lib/spec/rails/story_adapter.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/lib/spec/rails/story_adapter.rb --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/lib/spec/rails/story_adapter.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/lib/spec/rails/story_adapter.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,48 @@ +# WARNING - THIS IS PURELY EXPERIMENTAL AT THIS POINT +# Courtesy of Brian Takita and Yurii Rashkovskii + +$:.unshift File.join(File.dirname(__FILE__), *%w[.. .. .. .. rspec lib]) +require 'test_help' +require 'test/unit/testresult' +require 'spec' +require 'spec/rails' + +Test::Unit.run = true + +class RailsStory < ActionController::IntegrationTest + self.use_transactional_fixtures = true + include Spec::Rails::Matchers + + def initialize #:nodoc: + @_result = Test::Unit::TestResult.new + end +end + +class ActiveRecordSafetyListener + include Singleton + def scenario_started(*args) + ActiveRecord::Base.send :increment_open_transactions unless Rails::VERSION::STRING == "1.1.6" + ActiveRecord::Base.connection.begin_db_transaction + end + def scenario_succeeded(*args) + ActiveRecord::Base.connection.rollback_db_transaction + ActiveRecord::Base.send :decrement_open_transactions unless Rails::VERSION::STRING == "1.1.6" + end + alias :scenario_pending :scenario_succeeded + alias :scenario_failed :scenario_succeeded +end + +class Spec::Story::Runner::ScenarioRunner + def initialize + @listeners = [ActiveRecordSafetyListener.instance] + end +end + +class Spec::Story::GivenScenario + def perform(instance, name = nil) + scenario = Spec::Story::Runner::StoryRunner.scenario_from_current_story @name + runner = Spec::Story::Runner::ScenarioRunner.new + runner.instance_variable_set(:@listeners,[]) + runner.run(scenario, instance) + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/lib/spec/rails/version.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/lib/spec/rails/version.rb --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/lib/spec/rails/version.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/lib/spec/rails/version.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,26 @@ +module Spec + module Rails + module VERSION #:nodoc: + unless defined?(REV) + # RANDOM_TOKEN: 0.885013695004692 + REV = "$LastChangedRevision: 2958 $".match(/LastChangedRevision: (\d+)/)[1] + end + end + end +end + +# Verifies that the plugin has the same revision as RSpec +if Spec::VERSION::REV != Spec::Rails::VERSION::REV + raise <<-EOF + +############################################################################ +Your RSpec on Rails plugin is incompatible with your installed RSpec. + +RSpec : #{Spec::VERSION::FULL_VERSION} +RSpec on Rails : r#{Spec::Rails::VERSION::REV} + +Make sure your RSpec on Rails plugin is compatible with your RSpec gem. +See http://rspec.rubyforge.org/documentation/rails/install.html for details. +############################################################################ +EOF +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/lib/spec/rails.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/lib/spec/rails.rb --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/lib/spec/rails.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/lib/spec/rails.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,52 @@ +silence_warnings { RAILS_ENV = "test" } + +require 'application' +require 'action_controller/test_process' +require 'action_controller/integration' +require 'active_record/base' +require 'active_record/fixtures' +require 'test/unit' + +require 'spec' + +require 'spec/rails/extensions' +require 'spec/rails/example' +require 'spec/rails/version' +require 'spec/rails/matchers' + +module Spec + # = Spec::Rails + # + # Spec::Rails (a.k.a. RSpec on Rails) is a Ruby on Rails plugin that allows you to drive the development + # of your RoR application using RSpec, a framework that aims to enable Example Driven Development + # in Ruby. + # + # == Features + # + # * Use RSpec to independently specify Rails Models, Views, Controllers and Helpers + # * Integrated fixture loading + # * Special generators for Resources, Models, Views and Controllers that generate Specs instead of Tests. + # + # == Vision + # + # For people for whom TDD is a brand new concept, the testing support built into Ruby on Rails + # is a huge leap forward. The fact that it is built right in is fantastic, and Ruby on Rails + # apps are generally much easier to maintain than they might have been without such support. + # + # For those of us coming from a history with TDD, and now BDD, the existing support presents some problems related to dependencies across specs. To that end, RSpec on Rails supports 4 types of specs. We’ve also built in first class mocking and stubbing support in order to break dependencies across these different concerns. + # + # == More Information + # + # See Spec::Rails::Runner for information about the different kinds of contexts + # you can use to spec the different Rails components + # + # See Spec::Rails::Expectations for information about Rails-specific expectations + # you can set on responses and models, etc. + # + # == License + # + # RSpec on Rails is licensed under the same license as RSpec itself, + # the MIT-LICENSE. + module Rails + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec/rails/autotest/mappings_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec/rails/autotest/mappings_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec/rails/autotest/mappings_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec/rails/autotest/mappings_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,39 @@ +require File.dirname(__FILE__) + '/../../spec_helper' +require File.join(File.dirname(__FILE__), "..", "..", "..", "lib", "autotest", "rails_rspec") + +describe Autotest::RailsRspec, "file mapping" do + before(:each) do + @autotest = Autotest::RailsRspec.new + @autotest.output = StringIO.new + @autotest.files.clear + @autotest.last_mtime = Time.at(0) + end + + def ensure_mapping(examples, impl) + @autotest.files[@impl] = Time.at(0) + examples.each do |example| + @autotest.files[example] = Time.at(0) + end + @autotest.tests_for_file(impl).should == examples + end + + it "should map model example to model" do + ensure_mapping(['spec/models/thing_spec.rb'], 'app/models/thing.rb') + end + + it "should map controller example to controller" do + ensure_mapping(['spec/controllers/things_controller_spec.rb'], 'app/controllers/things_controller.rb') + end + + it "should map view.rhtml" do + ensure_mapping(['spec/views/things/index.rhtml_spec.rb'], 'app/views/things/index.rhtml') + end + + it "should map view.rhtml with underscores in example filename" do + ensure_mapping(['spec/views/things/index_rhtml_spec.rb'], 'app/views/things/index.rhtml') + end + + it "should map view.html.erb" do + ensure_mapping(['spec/views/things/index.html.erb_spec.rb'], 'app/views/things/index.html.erb') + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec/rails/autotest/rails_rspec_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec/rails/autotest/rails_rspec_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec/rails/autotest/rails_rspec_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec/rails/autotest/rails_rspec_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,8 @@ +require File.dirname(__FILE__) + '/../../spec_helper' +require File.join(File.dirname(__FILE__), "..", "..", "..", "lib", "autotest", "rails_rspec") + +describe Autotest::RailsRspec do + it "should provide the correct spec_command" do + Autotest::RailsRspec.new.spec_command.should == "script/spec" + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec/rails/dsl/assigns_hash_proxy_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec/rails/dsl/assigns_hash_proxy_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec/rails/dsl/assigns_hash_proxy_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec/rails/dsl/assigns_hash_proxy_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,55 @@ +require File.dirname(__FILE__) + '/../../spec_helper' + +describe "An AssignsHashProxy" do + before(:each) do + @object = Object.new + @assigns = Hash.new + @object.stub!(:assigns).and_return(@assigns) + @proxy = Spec::Rails::Example::AssignsHashProxy.new(@object) + end + + it "has [] accessor" do + @proxy['foo'] = 'bar' + @assigns['foo'].should == 'bar' + @proxy['foo'].should == 'bar' + end + + it "works for symbol key" do + @assigns[:foo] = 2 + @proxy[:foo].should == 2 + end + + it "checks for string key before symbol key" do + @assigns['foo'] = false + @assigns[:foo] = 2 + @proxy[:foo].should == false + end + + it "each method iterates through each element like a Hash" do + values = { + 'foo' => 1, + 'bar' => 2, + 'baz' => 3 + } + @proxy['foo'] = values['foo'] + @proxy['bar'] = values['bar'] + @proxy['baz'] = values['baz'] + + @proxy.each do |key, value| + key.should == key + value.should == values[key] + end + end + + it "delete method deletes the element of passed in key" do + @proxy['foo'] = 'bar' + @proxy.delete('foo').should == 'bar' + @proxy['foo'].should be_nil + end + + it "has_key? detects the presence of a key" do + @proxy['foo'] = 'bar' + @proxy.has_key?('foo').should == true + @proxy.has_key?('bar').should == false + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec/rails/dsl/configuration_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec/rails/dsl/configuration_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec/rails/dsl/configuration_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec/rails/dsl/configuration_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,73 @@ +require File.dirname(__FILE__) + '/../../spec_helper' + +module Spec + module Example + describe Configuration, :shared => true do + before(:each) { @config = Configuration.new } + end + + describe Configuration, "#use_transactional_fixtures" do + it_should_behave_like "Spec::Example::Configuration" + + it "should default to true" do + @config.use_transactional_fixtures.should be(true) + end + + it "should set to false" do + @config.use_transactional_fixtures = false + @config.use_transactional_fixtures.should be(false) + end + + it "should set to true" do + @config.use_transactional_fixtures = true + @config.use_transactional_fixtures.should be(true) + end + end + + describe Configuration, "#use_instantiated_fixtures" do + it_should_behave_like "Spec::Example::Configuration" + + it "should to false" do + @config.use_instantiated_fixtures.should be(false) + end + + it "should set to false" do + @config.use_instantiated_fixtures = false + @config.use_instantiated_fixtures.should be(false) + end + + it "should set to true" do + @config.use_instantiated_fixtures = true + @config.use_instantiated_fixtures.should be(true) + end + end + + describe Configuration, "#fixture_path" do + it_should_behave_like "Spec::Example::Configuration" + + it "should default to RAILS_ROOT + '/spec/fixtures'" do + @config.fixture_path.should == RAILS_ROOT + '/spec/fixtures' + Test::Unit::TestCase.fixture_path.should == RAILS_ROOT + '/spec/fixtures' + end + + it "should set fixture_path" do + @config.fixture_path = "/new/path" + @config.fixture_path.should == "/new/path" + Test::Unit::TestCase.fixture_path.should == "/new/path" + end + end + + describe Configuration, "#global_fixtures" do + it_should_behave_like "Spec::Example::Configuration" + + it "should default to []" do + @config.global_fixtures.should == [] + end + + it "should set to false" do + @config.global_fixtures << :blah + @config.global_fixtures.should == [:blah] + end + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec/rails/dsl/controller_isolation_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec/rails/dsl/controller_isolation_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec/rails/dsl/controller_isolation_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec/rails/dsl/controller_isolation_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,43 @@ +require File.dirname(__FILE__) + '/../../spec_helper' +require 'controller_spec_controller' + +describe "a controller spec running in isolation mode", :behaviour_type => :controller do + controller_name :controller_spec + + it "should not care if the template doesn't exist" do + get 'some_action' + response.should be_success + response.should render_template("template/that/does/not/actually/exist") + end + + it "should not care if the template has errors" do + get 'action_with_errors_in_template' + response.should be_success + response.should render_template("action_with_errors_in_template") + end +end + +describe "a controller spec running in integration mode", :behaviour_type => :controller do + controller_name :controller_spec + integrate_views + + before(:each) do + controller.class.send(:define_method, :rescue_action) { |e| raise e } + end + + it "should render a template" do + get 'action_with_template' + response.should be_success + response.should have_tag('div', 'This is action_with_template.rhtml') + end + + it "should choke if the template doesn't exist" do + lambda { get 'some_action' }.should raise_error(ActionController::MissingTemplate) + response.should_not be_success + end + + it "should choke if the template has errors" do + lambda { get 'action_with_errors_in_template' }.should raise_error(ActionView::TemplateError) + response.should_not be_success + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec/rails/dsl/controller_spec_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec/rails/dsl/controller_spec_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec/rails/dsl/controller_spec_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec/rails/dsl/controller_spec_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,157 @@ +require File.dirname(__FILE__) + '/../../spec_helper' +require 'controller_spec_controller' + +['integration', 'isolation'].each do |mode| + describe "A controller example running in #{mode} mode", :behaviour_type => :controller do + controller_name :controller_spec + integrate_views if mode == 'integration' + + it "should provide controller.session as session" do + get 'action_with_template' + session.should equal(controller.session) + end + + it "should provide the same session object before and after the action" do + session_before = session + get 'action_with_template' + session.should equal(session_before) + end + + it "should ensure controller.session is NOT nil before the action" do + controller.session.should_not be_nil + get 'action_with_template' + end + + it "should ensure controller.session is NOT nil after the action" do + get 'action_with_template' + controller.session.should_not be_nil + end + + it "should allow specifying a partial with partial name only" do + get 'action_with_partial' + response.should render_template("_partial") + end + + it "should allow specifying a partial with expect_render" do + controller.expect_render(:partial => "controller_spec/partial") + get 'action_with_partial' + end + + it "should allow specifying a partial with expect_render with object" do + controller.expect_render(:partial => "controller_spec/partial", :object => "something") + get 'action_with_partial_with_object', :thing => "something" + end + + it "should allow specifying a partial with expect_render with locals" do + controller.expect_render(:partial => "controller_spec/partial", :locals => {:thing => "something"}) + get 'action_with_partial_with_locals', :thing => "something" + end + + it "should allow a path relative to RAILS_ROOT/app/views/ when specifying a partial" do + get 'action_with_partial' + response.should render_template("controller_spec/_partial") + end + + it "should provide access to flash" do + get 'action_with_template' + flash[:flash_key].should == "flash value" + end + + it "should provide access to flash values set after a session reset" do + get 'action_setting_flash_after_session_reset' + flash[:after_reset].should == "available" + end + + it "should not provide access to flash values set before a session reset" do + get 'action_setting_flash_before_session_reset' + flash[:before_reset].should_not == "available" + end + + it "should provide access to session" do + get 'action_with_template' + session[:session_key].should == "session value" + end + + it "should support custom routes" do + route_for(:controller => "custom_route_spec", :action => "custom_route").should == "/custom_route" + end + + it "should support existing routes" do + route_for(:controller => "controller_spec", :action => "some_action").should == "/controller_spec/some_action" + end + + it "should generate params for custom routes" do + params_from(:get, '/custom_route').should == {:controller => "custom_route_spec", :action => "custom_route"} + end + + it "should generate params for existing routes" do + params_from(:get, '/controller_spec/some_action').should == {:controller => "controller_spec", :action => "some_action"} + end + + it "should expose the assigns hash directly" do + get 'action_setting_the_assigns_hash' + assigns[:direct_assigns_key].should == :direct_assigns_key_value + end + + it "should complain when calling should_receive(:render) on the controller" do + lambda { + controller.should_receive(:render) + }.should raise_error(RuntimeError, /should_receive\(:render\) has been disabled/) + end + + it "should complain when calling stub!(:render) on the controller" do + lambda { + controller.stub!(:render) + }.should raise_error(RuntimeError, /stub!\(:render\) has been disabled/) + end + + it "should NOT complain when calling should_receive with arguments other than :render" do + controller.should_receive(:anything_besides_render) + lambda { + controller.rspec_verify + }.should raise_error(Exception, /expected :anything_besides_render/) + end + end + + describe "Given a controller spec for RedirectSpecController running in #{mode} mode", :behaviour_type => :controller do + controller_name :redirect_spec + integrate_views if mode == 'integration' + + it "a redirect should ignore the absence of a template" do + get 'action_with_redirect_to_somewhere' + response.should be_redirect + response.redirect_url.should == "http://test.host/redirect_spec/somewhere" + response.should redirect_to("http://test.host/redirect_spec/somewhere") + end + + it "a call to response.should redirect_to should fail if no redirect" do + get 'action_with_no_redirect' + lambda { + response.redirect?.should be_true + }.should fail + lambda { + response.should redirect_to("http://test.host/redirect_spec/somewhere") + }.should fail_with("expected redirect to \"http://test.host/redirect_spec/somewhere\", got no redirect") + end + end + + describe "Given a controller spec running in #{mode} mode" do + example_group = describe "A controller spec" + # , :behaviour_type => :controller do + # integrate_views if mode == 'integration' + it "a spec in a context without controller_name set should fail with a useful warning" do + pending("need a new way to deal with examples that should_raise") + # , + # :should_raise => [ + # Spec::Expectations::ExpectationNotMetError, + # /You have to declare the controller name in controller specs/ + # ] do + end + end + +end + +describe ControllerSpecController, :behaviour_type => :controller do + it "should not require naming the controller if describe is passed a type" do + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec/rails/dsl/example_group_factory_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec/rails/dsl/example_group_factory_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec/rails/dsl/example_group_factory_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec/rails/dsl/example_group_factory_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,112 @@ +require File.dirname(__FILE__) + '/../../spec_helper' + +module Spec + module Example + describe ExampleGroupFactory do + it "should return a ModelExample when given :behaviour_type => :model" do + behaviour = Spec::Example::ExampleGroupFactory.create_example_group( + "name", :behaviour_type => :model + ) {} + behaviour.superclass.should == Spec::Rails::Example::ModelExample + end + + it "should return a ModelExample when given :spec_path => '/blah/spec/models/'" do + behaviour = Spec::Example::ExampleGroupFactory.create_example_group( + "name", :spec_path => '/blah/spec/models/blah.rb' + ) {} + behaviour.superclass.should == Spec::Rails::Example::ModelExample + end + + it "should return a ModelExample when given :spec_path => '\\blah\\spec\\models\\' (windows format)" do + behaviour = Spec::Example::ExampleGroupFactory.create_example_group( + "name", :spec_path => '\\blah\\spec\\models\\blah.rb' + ) {} + behaviour.superclass.should == Spec::Rails::Example::ModelExample + end + + it "should return a RailsExample when given :spec_path => '/blah/spec/foo/' (anything other than controllers, views and helpers)" do + behaviour = Spec::Example::ExampleGroupFactory.create_example_group( + "name", :spec_path => '/blah/spec/foo/blah.rb' + ) {} + behaviour.superclass.should == Spec::Rails::Example::RailsExample + end + + it "should return a RailsExample when given :spec_path => '\\blah\\spec\\foo\\' (windows format) (anything other than controllers, views and helpers)" do + behaviour = Spec::Example::ExampleGroupFactory.create_example_group( + "name", :spec_path => '\\blah\\spec\\foo\\blah.rb' + ) {} + behaviour.superclass.should == Spec::Rails::Example::RailsExample + end + + it "should return a ViewExample when given :behaviour_type => :model" do + behaviour = Spec::Example::ExampleGroupFactory.create_example_group( + "name", :behaviour_type => :view + ) {} + behaviour.superclass.should == Spec::Rails::Example::ViewExample + end + + it "should return a ViewExample when given :spec_path => '/blah/spec/views/'" do + behaviour = Spec::Example::ExampleGroupFactory.create_example_group( + "name", :spec_path => '/blah/spec/views/blah.rb' + ) {} + behaviour.superclass.should == Spec::Rails::Example::ViewExample + end + + it "should return a ModelExample when given :spec_path => '\\blah\\spec\\views\\' (windows format)" do + behaviour = Spec::Example::ExampleGroupFactory.create_example_group( + "name", :spec_path => '\\blah\\spec\\views\\blah.rb' + ) {} + behaviour.superclass.should == Spec::Rails::Example::ViewExample + end + + it "should return a HelperExample when given :behaviour_type => :helper" do + behaviour = Spec::Example::ExampleGroupFactory.create_example_group( + "name", :behaviour_type => :helper + ) {} + behaviour.superclass.should == Spec::Rails::Example::HelperExample + end + + it "should return a HelperExample when given :spec_path => '/blah/spec/helpers/'" do + behaviour = Spec::Example::ExampleGroupFactory.create_example_group( + "name", :spec_path => '/blah/spec/helpers/blah.rb' + ) {} + behaviour.superclass.should == Spec::Rails::Example::HelperExample + end + + it "should return a ModelExample when given :spec_path => '\\blah\\spec\\helpers\\' (windows format)" do + behaviour = Spec::Example::ExampleGroupFactory.create_example_group( + "name", :spec_path => '\\blah\\spec\\helpers\\blah.rb' + ) {} + behaviour.superclass.should == Spec::Rails::Example::HelperExample + end + + it "should return a ControllerExample when given :behaviour_type => :controller" do + behaviour = Spec::Example::ExampleGroupFactory.create_example_group( + "name", :behaviour_type => :controller + ) {} + behaviour.superclass.should == Spec::Rails::Example::ControllerExample + end + + it "should return a ControllerExample when given :spec_path => '/blah/spec/controllers/'" do + behaviour = Spec::Example::ExampleGroupFactory.create_example_group( + "name", :spec_path => '/blah/spec/controllers/blah.rb' + ) {} + behaviour.superclass.should == Spec::Rails::Example::ControllerExample + end + + it "should return a ModelExample when given :spec_path => '\\blah\\spec\\controllers\\' (windows format)" do + behaviour = Spec::Example::ExampleGroupFactory.create_example_group( + "name", :spec_path => '\\blah\\spec\\controllers\\blah.rb' + ) {} + behaviour.superclass.should == Spec::Rails::Example::ControllerExample + end + + it "should favor the :behaviour_type over the :spec_path" do + behaviour = Spec::Example::ExampleGroupFactory.create_example_group( + "name", :spec_path => '/blah/spec/models/blah.rb', :behaviour_type => :controller + ) {} + behaviour.superclass.should == Spec::Rails::Example::ControllerExample + end + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec/rails/dsl/helper_spec_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec/rails/dsl/helper_spec_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec/rails/dsl/helper_spec_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec/rails/dsl/helper_spec_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,101 @@ +require File.dirname(__FILE__) + '/../../spec_helper' +Spec::Runner.configuration.global_fixtures = :people + +describe ExplicitHelper, :behaviour_type => :helper do + it "should not require naming the helper if describe is passed a type" do + method_in_explicit_helper.should match(/text from a method/) + end +end + +module Spec + module Rails + module Example + describe HelperExample, :behaviour_type => :helper do + helper_name :explicit + + it "should have direct access to methods defined in helpers" do + method_in_explicit_helper.should =~ /text from a method/ + end + + it "should have access to named routes" do + rspec_on_rails_specs_url.should == "http://test.host/rspec_on_rails_specs" + rspec_on_rails_specs_path.should == "/rspec_on_rails_specs" + end + + it "should fail if the helper method deson't exist" do + lambda { non_existant_helper_method }.should raise_error(NameError) + end + end + + + describe HelperExample, "#eval_erb", :behaviour_type => :helper do + helper_name :explicit + + it "should support methods that accept blocks" do + eval_erb("<% prepend 'foo' do %>bar<% end %>").should == "foobar" + end + end + + describe HelperExample, ".fixtures", :behaviour_type => :helper do + helper_name :explicit + fixtures :animals + + it "should load fixtures" do + pig = animals(:pig) + pig.class.should == Animal + end + + it "should load global fixtures" do + lachie = people(:lachie) + lachie.class.should == Person + end + end + + describe HelperExample, "included modules", :behaviour_type => :helper do + helpers = [ + ActionView::Helpers::ActiveRecordHelper, + ActionView::Helpers::AssetTagHelper, + ActionView::Helpers::BenchmarkHelper, + ActionView::Helpers::CacheHelper, + ActionView::Helpers::CaptureHelper, + ActionView::Helpers::DateHelper, + ActionView::Helpers::DebugHelper, + ActionView::Helpers::FormHelper, + ActionView::Helpers::FormOptionsHelper, + ActionView::Helpers::FormTagHelper, + ActionView::Helpers::JavaScriptHelper, + ActionView::Helpers::NumberHelper, + ActionView::Helpers::PrototypeHelper, + ActionView::Helpers::ScriptaculousHelper, + ActionView::Helpers::TagHelper, + ActionView::Helpers::TextHelper, + ActionView::Helpers::UrlHelper + ] + helpers << ActionView::Helpers::PaginationHelper rescue nil #removed for 2.0 + helpers << ActionView::Helpers::JavaScriptMacrosHelper rescue nil #removed for 2.0 + helpers.each do |helper_module| + it "should include #{helper_module}" do + self.class.ancestors.should include(helper_module) + end + end + end + + # TODO: BT - Helper Examples should proxy method_missing to a Rails View instance. + # When that is done, remove this method + describe HelperExample, "#protect_against_forgery?", :behaviour_type => :helper do + it "should return false" do + protect_against_forgery?.should be_false + end + end + end + end +end + +module Bug11223 + # see http://rubyforge.org/tracker/index.php?func=detail&aid=11223&group_id=797&atid=3149 + describe 'Accessing flash from helper spec', :behaviour_type => :helper do + it 'should not raise an error' do + lambda { flash['test'] }.should_not raise_error + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec/rails/dsl/ivar_proxy_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec/rails/dsl/ivar_proxy_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec/rails/dsl/ivar_proxy_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec/rails/dsl/ivar_proxy_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,64 @@ +require File.dirname(__FILE__) + '/../../spec_helper' + +describe "IvarProxy setup", :shared => true do + before do + @object = Object.new + @proxy = Spec::Rails::Example::IvarProxy.new(@object) + end +end + +describe "IvarProxy" do + it_should_behave_like "IvarProxy setup" + + it "has [] accessor" do + @proxy['foo'] = 'bar' + @object.instance_variable_get(:@foo).should == 'bar' + @proxy['foo'].should == 'bar' + end + + it "iterates through each element like a Hash" do + values = { + 'foo' => 1, + 'bar' => 2, + 'baz' => 3 + } + @proxy['foo'] = values['foo'] + @proxy['bar'] = values['bar'] + @proxy['baz'] = values['baz'] + + @proxy.each do |key, value| + key.should == key + value.should == values[key] + end + end + + it "detects the presence of a key" do + @proxy['foo'] = 'bar' + @proxy.has_key?('foo').should == true + @proxy.has_key?('bar').should == false + end +end + +describe "IvarProxy", "#delete" do + it_should_behave_like "IvarProxy setup" + + it "deletes the element with key" do + @proxy['foo'] = 'bar' + @proxy.delete('foo').should == 'bar' + @proxy['foo'].should be_nil + end + + it "deletes nil instance variables" do + @proxy['foo'] = nil + @object.instance_variables.should include("@foo") + @proxy.delete('foo').should == nil + @proxy['foo'].should be_nil + @object.instance_variables.should_not include("@foo") + end + + it "returns nil when key does not exist" do + @proxy['foo'].should be_nil + @proxy.delete('foo').should == nil + @proxy['foo'].should be_nil + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec/rails/dsl/model_spec_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec/rails/dsl/model_spec_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec/rails/dsl/model_spec_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec/rails/dsl/model_spec_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1 @@ +require File.dirname(__FILE__) + '/../../spec_helper' diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec/rails/dsl/shared_behaviour_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec/rails/dsl/shared_behaviour_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec/rails/dsl/shared_behaviour_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec/rails/dsl/shared_behaviour_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,16 @@ +require File.dirname(__FILE__) + '/../../spec_helper' + +describe "A shared view behaviour", :shared => true do + it "should have some tag with some text" do + response.should have_tag('div', 'This is text from a method in the ViewSpecHelper') + end +end + +describe "A view behaviour", :behaviour_type => :view do + it_should_behave_like "A shared view behaviour" + + before(:each) do + render "view_spec/implicit_helper" + end +end + diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec/rails/dsl/test_unit_assertion_accessibility_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec/rails/dsl/test_unit_assertion_accessibility_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec/rails/dsl/test_unit_assertion_accessibility_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec/rails/dsl/test_unit_assertion_accessibility_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,33 @@ +require File.dirname(__FILE__) + '/../../spec_helper' + +describe "assert_equal", :shared => true do + it "like assert_equal" do + assert_equal 1, 1 + lambda { + assert_equal 1, 2 + }.should raise_error(Test::Unit::AssertionFailedError) + end +end + +describe "A model spec should be able to access 'test/unit' assertions", :behaviour_type => :model do + it_should_behave_like "assert_equal" +end + +describe "A view spec should be able to access 'test/unit' assertions", :behaviour_type => :view do + it_should_behave_like "assert_equal" +end + +describe "A helper spec should be able to access 'test/unit' assertions", :behaviour_type => :helper do + it_should_behave_like "assert_equal" +end + +describe "A controller spec with integrated views should be able to access 'test/unit' assertions", :behaviour_type => :controller do + controller_name :controller_spec + integrate_views + it_should_behave_like "assert_equal" +end + +describe "A controller spec should be able to access 'test/unit' assertions", :behaviour_type => :controller do + controller_name :controller_spec + it_should_behave_like "assert_equal" +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec/rails/dsl/view_spec_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec/rails/dsl/view_spec_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec/rails/dsl/view_spec_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec/rails/dsl/view_spec_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,232 @@ +require File.dirname(__FILE__) + '/../../spec_helper' + +describe "A template with an implicit helper", :behaviour_type => :view do + before(:each) do + render "view_spec/implicit_helper" + end + + it "should include the helper" do + response.should have_tag('div', :content => "This is text from a method in the ViewSpecHelper") + end + + it "should include the application helper" do + response.should have_tag('div', :content => "This is text from a method in the ApplicationHelper") + end + + it "should have access to named routes" do + rspec_on_rails_specs_url.should == "http://test.host/rspec_on_rails_specs" + rspec_on_rails_specs_path.should == "/rspec_on_rails_specs" + end +end + +describe "A template requiring an explicit helper", :behaviour_type => :view do + before(:each) do + render "view_spec/explicit_helper", :helper => 'explicit' + end + + it "should include the helper if specified" do + response.should have_tag('div', :content => "This is text from a method in the ExplicitHelper") + end + + it "should include the application helper" do + response.should have_tag('div', :content => "This is text from a method in the ApplicationHelper") + end +end + +describe "A template requiring multiple explicit helpers", :behaviour_type => :view do + before(:each) do + render "view_spec/multiple_helpers", :helpers => ['explicit', 'more_explicit'] + end + + it "should include all specified helpers" do + response.should have_tag('div', :content => "This is text from a method in the ExplicitHelper") + response.should have_tag('div', :content => "This is text from a method in the MoreExplicitHelper") + end + + it "should include the application helper" do + response.should have_tag('div', :content => "This is text from a method in the ApplicationHelper") + end +end + +describe "Message Expectations on helper methods", :behaviour_type => :view do + it "should work" do + template.should_receive(:method_in_plugin_application_helper).and_return('alternate message 1') + render "view_spec/implicit_helper" + response.body.should =~ /alternate message 1/ + end + + it "should work twice" do + template.should_receive(:method_in_plugin_application_helper).and_return('alternate message 2') + render "view_spec/implicit_helper" + response.body.should =~ /alternate message 2/ + end +end + +describe "A template that includes a partial", :behaviour_type => :view do + def render! + render "view_spec/template_with_partial" + end + + it "should render the enclosing template" do + render! + response.should have_tag('div', "method_in_partial in ViewSpecHelper") + end + + it "should render the partial" do + render! + response.should have_tag('div', "method_in_template_with_partial in ViewSpecHelper") + end + + it "should include the application helper" do + render! + response.should have_tag('div', "This is text from a method in the ApplicationHelper") + end + + it "should pass expect_render with the right partial" do + template.expect_render(:partial => 'partial') + render! + template.verify_rendered + end + + it "should fail expect_render with the wrong partial" do + template.expect_render(:partial => 'non_existent') + render! + begin + template.verify_rendered + rescue Spec::Mocks::MockExpectationError => e + ensure + e.backtrace.find{|line| line =~ /view_spec_spec\.rb\:92/}.should_not be_nil + end + end + + it "should pass expect_render when a partial is expected twice and happens twice" do + template.expect_render(:partial => 'partial_used_twice').twice + render! + template.verify_rendered + end + + it "should pass expect_render when a partial is expected once and happens twice" do + template.expect_render(:partial => 'partial_used_twice') + render! + begin + template.verify_rendered + rescue Spec::Mocks::MockExpectationError => e + ensure + e.backtrace.find{|line| line =~ /view_spec_spec\.rb\:109/}.should_not be_nil + end + end + + it "should fail expect_render with the right partial but wrong options" do + template.expect_render(:partial => 'partial', :locals => {:thing => Object.new}) + render! + lambda {template.verify_rendered}.should raise_error(Spec::Mocks::MockExpectationError) + end +end + +describe "A partial that includes a partial", :behaviour_type => :view do + it "should support expect_render with nested partial" do + obj = Object.new + template.expect_render(:partial => 'partial', :object => obj) + render :partial => "view_spec/partial_with_sub_partial", :locals => { :partial => obj } + end +end + +describe "A view that includes a partial using :collection and :spacer_template", :behaviour_type => :view do + it "should render the partial w/ spacer_tamplate" do + render "view_spec/template_with_partial_using_collection" + response.should have_tag('div',/method_in_partial/) + response.should have_tag('div',/ApplicationHelper/) + response.should have_tag('div',/ViewSpecHelper/) + response.should have_tag('hr#spacer') + end + + it "should render the partial" do + template.expect_render(:partial => 'partial', + :collection => ['Alice', 'Bob'], + :spacer_template => 'spacer') + render "view_spec/template_with_partial_using_collection" + end + +end + +describe "A view that includes a partial using an array as partial_path", :behaviour_type => :view do + before(:each) do + module ActionView::Partials + def render_template_with_partial_with_array_support(partial_path, local_assigns = nil, deprecated_local_assigns = nil) + if partial_path.is_a?(Array) + "Array Partial" + else + render_partial_without_array_support(partial_path, local_assigns, deprecated_local_assigns) + end + end + + alias :render_partial_without_array_support :render_partial + alias :render_partial :render_template_with_partial_with_array_support + end + + @array = ['Alice', 'Bob'] + assigns[:array] = @array + end + + after(:each) do + module ActionView::Partials + alias :render_template_with_partial_with_array_support :render_partial + alias :render_partial :render_partial_without_array_support + undef render_template_with_partial_with_array_support + end + end + + it "should render have the array passed through to render_partial without modification" do + render "view_spec/template_with_partial_with_array" + response.body.should match(/^Array Partial$/) + end +end + +describe "Different types of renders (not :template)", :behaviour_type => :view do + it "should render partial with local" do + render :partial => "view_spec/partial_with_local_variable", :locals => {:x => "Ender"} + response.should have_tag('div', :content => "Ender") + end +end + +describe "A view", :behaviour_type => :view do + before(:each) do + session[:key] = "session" + params[:key] = "params" + flash[:key] = "flash" + render "view_spec/accessor" + end + + it "should have access to session data" do + response.should have_tag("div#session", "session") + end + + specify "should have access to params data" do + response.should have_tag("div#params", "params") + end + + it "should have access to flash data" do + response.should have_tag("div#flash", "flash") + end +end + +describe "A view with a form_tag", :behaviour_type => :view do + it "should render the right action" do + render "view_spec/entry_form" + response.should have_tag("form[action=?]","/view_spec/entry_form") + end +end + +describe "An instantiated ViewExampleController", :behaviour_type => :view do + before do + render "view_spec/foo/show" + end + + it "should return the name of the real controller that it replaces" do + @controller.controller_name.should == 'foo' + end + + it "should return the path of the real controller that it replaces" do + @controller.controller_path.should == 'view_spec/foo' + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec/rails/extensions/action_controller_rescue_action_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec/rails/extensions/action_controller_rescue_action_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec/rails/extensions/action_controller_rescue_action_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec/rails/extensions/action_controller_rescue_action_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,54 @@ +require File.dirname(__FILE__) + '/../../spec_helper' + +module ActionController + describe "Rescue", "#rescue_action in default mode" do + before(:each) do + @fixture = Object.new + @fixture.extend ActionController::Rescue + class << @fixture + public :rescue_action + end + end + + it "should raise the passed in exception so examples fail fast" do + proc {@fixture.rescue_action(RuntimeError.new("Foobar"))}.should raise_error(RuntimeError, "Foobar") + end + end + + class RescueOverriddenController < ActionController::Base + def rescue_action(error) + "successfully overridden" + end + end + + describe "Rescue", "#rescue_action, when overridden" do + before(:each) do + @fixture = RescueOverriddenController.new + end + + it "should do whatever the overridden method does" do + @fixture.rescue_action(RuntimeError.new("Foobar")).should == "successfully overridden" + end + end + + class SearchController < ActionController::Base + end + + describe "Rescue", "#rescue_action when told to use rails error handling" do + before(:each) do + @controller = SearchController.new + @controller.use_rails_error_handling! + class << @controller + public :rescue_action + end + end + + it "should use Rails exception handling" do + exception = RuntimeError.new("The Error") + exception.stub!(:backtrace).and_return(caller) + @controller.should_receive(:rescue_action_locally).with(exception) + + @controller.rescue_action(exception) + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec/rails/extensions/action_view_base_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec/rails/extensions/action_view_base_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec/rails/extensions/action_view_base_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec/rails/extensions/action_view_base_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,37 @@ +require File.dirname(__FILE__) + '/../../spec_helper' +require 'spec/mocks/errors' + +describe ActionView::Base, "with RSpec extensions", :behaviour_type => :view do + it "should not raise when render has been received" do + template.expect_render(:partial => "name") + template.render :partial => "name" + end + + it "should raise when render has NOT been received" do + template.expect_render(:partial => "name") + lambda { + template.verify_rendered + }.should raise_error + end + + it "should not raise when stubbing and render has been received" do + template.stub_render(:partial => "name") + template.render :partial => "name" + end + + it "should not raise when stubbing and render has NOT been received" do + template.stub_render(:partial => "name") + end + + it "should not raise when stubbing and render has been received with different options" do + template.stub_render(:partial => "name") + template.render :partial => "view_spec/spacer" + end + + it "should not raise when stubbing and expecting and render has been received" do + template.stub_render(:partial => "name") + template.expect_render(:partial => "name") + template.render(:partial => "name") + end + +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec/rails/extensions/active_record_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec/rails/extensions/active_record_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec/rails/extensions/active_record_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec/rails/extensions/active_record_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,17 @@ +require File.dirname(__FILE__) + '/../../spec_helper' + +class Thing < ActiveRecord::Base + validates_presence_of :name +end + +describe "A model" do + it "should tell you its required fields" do + Thing.new.should have(1).error_on(:name) + end + + it "should tell you how many records it has" do + Thing.should have(:no).records + Thing.create(:name => "THE THING") + Thing.should have(1).record + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec/rails/matchers/assert_select_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec/rails/matchers/assert_select_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec/rails/matchers/assert_select_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec/rails/matchers/assert_select_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,783 @@ +require File.dirname(__FILE__) + '/../../spec_helper' + +# assert_select plugins for Rails +# +# Copyright (c) 2006 Assaf Arkin, under Creative Commons Attribution and/or MIT License +# Developed for http://co.mments.com +# Code and documention: http://labnotes.org + +class AssertSelectController < ActionController::Base + + def response=(content) + @content = content + end + + #NOTE - this is commented because response is implemented in lib/spec/rails/context/controller + # def response(&block) + # @update = block + # end + # + def html() + render :text=>@content, :layout=>false, :content_type=>Mime::HTML + @content = nil + end + + def rjs() + update = @update + render :update do |page| + update.call page + end + @update = nil + end + + def xml() + render :text=>@content, :layout=>false, :content_type=>Mime::XML + @content = nil + end + + def rescue_action(e) + raise e + end + +end + +class AssertSelectMailer < ActionMailer::Base + + def test(html) + recipients "test " + from "test@test.host" + subject "Test e-mail" + part :content_type=>"text/html", :body=>html + end + +end + +module AssertSelectSpecHelpers + def render_html(html) + @controller.response = html + get :html + end + + def render_rjs(&block) + clear_response + @controller.response &block + get :rjs + end + + def render_xml(xml) + @controller.response = xml + get :xml + end + + def first_non_rspec_line_in_backtrace_of(error) + rspec_path = File.join('rspec', 'lib', 'spec') + error.backtrace.reject { |line| + line =~ /#{rspec_path}/ + }.first + end + + private + # necessary for 1.2.1 + def clear_response + render_html("") + end +end + +unless defined?(SpecFailed) + SpecFailed = Spec::Expectations::ExpectationNotMetError +end + +describe "should have_tag", :behaviour_type => :controller do + include AssertSelectSpecHelpers + controller_name :assert_select + integrate_views + + it "should find specific numbers of elements" do + render_html %Q{

      } + response.should have_tag( "div" ) + response.should have_tag("div", 2) + lambda { response.should_not have_tag("div") }.should raise_error(SpecFailed, "should not have tag(\"div\"), but did") + + lambda { response.should have_tag("div", 3) }.should raise_error(SpecFailed) + lambda { response.should have_tag("p") }.should raise_error(SpecFailed) + end + + it "should expect to find elements when using true" do + render_html %Q{
      } + response.should have_tag( "div", true ) + lambda { response.should have_tag( "p", true )}.should raise_error(SpecFailed) + end + + it "should expect to not find elements when using false" do + render_html %Q{
      } + response.should have_tag( "p", false ) + lambda { response.should have_tag( "div", false )}.should raise_error(SpecFailed) + end + + + it "should match submitted text using text or regexp" do + render_html %Q{
      foo
      foo
      } + response.should have_tag("div", "foo") + response.should have_tag("div", /(foo|bar)/) + response.should have_tag("div", :text=>"foo") + response.should have_tag("div", :text=>/(foo|bar)/) + + lambda { response.should have_tag("div", "bar") }.should raise_error(SpecFailed) + lambda { response.should have_tag("div", :text=>"bar") }.should raise_error(SpecFailed) + lambda { response.should have_tag("p", :text=>"foo") }.should raise_error(SpecFailed) + + lambda { response.should have_tag("div", /foobar/) }.should raise_error(SpecFailed) + lambda { response.should have_tag("div", :text=>/foobar/) }.should raise_error(SpecFailed) + lambda { response.should have_tag("p", :text=>/foo/) }.should raise_error(SpecFailed) + end + + it "should use submitted message" do + render_html %Q{nothing here} + lambda { + response.should have_tag("div", {}, "custom message") + }.should raise_error(SpecFailed, /custom message/) + end + + it "should match submitted html" do + render_html %Q{

      \n"This is not a big problem," he said.\n

      } + text = "\"This is not a big problem,\" he said." + html = "\"This is not a big problem,\" he said." + response.should have_tag("p", text) + lambda { response.should have_tag("p", html) }.should raise_error(SpecFailed) + response.should have_tag("p", :html=>html) + lambda { response.should have_tag("p", :html=>text) }.should raise_error(SpecFailed) + + # # No stripping for pre. + render_html %Q{
      \n"This is not a big problem," he said.\n
      } + text = "\n\"This is not a big problem,\" he said.\n" + html = "\n\"This is not a big problem,\" he said.\n" + response.should have_tag("pre", text) + lambda { response.should have_tag("pre", html) }.should raise_error(SpecFailed) + response.should have_tag("pre", :html=>html) + lambda { response.should have_tag("pre", :html=>text) }.should raise_error(SpecFailed) + end + + it "should match number of instances" do + render_html %Q{
      foo
      foo
      } + response.should have_tag("div", 2) + lambda { response.should have_tag("div", 3) }.should raise_error(SpecFailed) + response.should have_tag("div", 1..2) + lambda { response.should have_tag("div", 3..4) }.should raise_error(SpecFailed) + response.should have_tag("div", :count=>2) + lambda { response.should have_tag("div", :count=>3) }.should raise_error(SpecFailed) + response.should have_tag("div", :minimum=>1) + response.should have_tag("div", :minimum=>2) + lambda { response.should have_tag("div", :minimum=>3) }.should raise_error(SpecFailed) + response.should have_tag("div", :maximum=>2) + response.should have_tag("div", :maximum=>3) + lambda { response.should have_tag("div", :maximum=>1) }.should raise_error(SpecFailed) + response.should have_tag("div", :minimum=>1, :maximum=>2) + lambda { response.should have_tag("div", :minimum=>3, :maximum=>4) }.should raise_error(SpecFailed) + end + + it "substitution values" do + render_html %Q{
      foo
      foo
      } + response.should have_tag("div#?", /\d+/) do |elements| #using do/end + elements.size.should == 2 + end + response.should have_tag("div#?", /\d+/) { |elements| #using {} + elements.size.should == 2 + } + lambda { + response.should have_tag("div#?", /\d+/) do |elements| + elements.size.should == 3 + end + }.should raise_error(SpecFailed, "expected: 3,\n got: 2 (using ==)") + + lambda { + response.should have_tag("div#?", /\d+/) { |elements| + elements.size.should == 3 + } + }.should raise_error(SpecFailed, "expected: 3,\n got: 2 (using ==)") + + response.should have_tag("div#?", /\d+/) do |elements| + elements.size.should == 2 + with_tag("#1") + with_tag("#2") + without_tag("#3") + end + end + + #added for RSpec + it "nested tags in form" do + render_html %Q{ +
      + +
      +
      + +
      + } + response.should have_tag("form[action=test]") { |form| + with_tag("input[type=text][name=email]") + } + response.should have_tag("form[action=test]") { |form| + with_tag("input[type=text][name=email]") + } + + lambda { + response.should have_tag("form[action=test]") { |form| + with_tag("input[type=text][name=other_input]") + } + }.should raise_error(SpecFailed) + + lambda { + response.should have_tag("form[action=test]") { + with_tag("input[type=text][name=other_input]") + } + }.should raise_error(SpecFailed) + end + + it "should report the correct line number for a nested failed expectation" do + render_html %Q{ +
      + +
      + } + begin + response.should have_tag("form[action=test]") { + @expected_error_line = __LINE__; should have_tag("input[type=text][name=other_input]") + } + rescue => e + first_non_rspec_line_in_backtrace_of(e).should =~ + /#{File.basename(__FILE__)}:#{@expected_error_line}/ + else + fail + end + end + + it "should report the correct line number for a nested raised exception" do + render_html %Q{ +
      + +
      + } + begin + response.should have_tag("form[action=test]") { + @expected_error_line = __LINE__; raise "Failed!" + } + rescue => e + first_non_rspec_line_in_backtrace_of(e).should =~ + /#{File.basename(__FILE__)}:#{@expected_error_line}/ + else + fail + end + end + + it "should report the correct line number for a nested failed test/unit assertion" do + pending "Doesn't work at the moment. Do we want to support this?" do + render_html %Q{ +
      + +
      + } + begin + response.should have_tag("form[action=test]") { + @expected_error_line = __LINE__; assert false + } + rescue => e + first_non_rspec_line_in_backtrace_of(e).should =~ + /#{File.basename(__FILE__)}:#{@expected_error_line}/ + else + fail + end + end + end + + + it "beatles" do + unless defined?(BEATLES) + BEATLES = [ + ["John", "Guitar"], + ["George", "Guitar"], + ["Paul", "Bass"], + ["Ringo", "Drums"] + ] + end + + render_html %Q{ +
      +
      +

      John

      Guitar

      +
      +
      +

      George

      Guitar

      +
      +
      +

      Paul

      Bass

      +
      +
      +

      Ringo

      Drums

      +
      +
      + } + response.should have_tag("div#beatles>div[class=\"beatle\"]", 4) + + response.should have_tag("div#beatles>div.beatle") { + BEATLES.each { |name, instrument| + with_tag("div.beatle>h2", name) + with_tag("div.beatle>p", instrument) + without_tag("div.beatle>span") + } + } + end + + it "assert_select_text_match" do + render_html %Q{
      foo
      bar
      } + response.should have_tag("div") do |divs| + with_tag("div", "foo") + with_tag("div", "bar") + with_tag("div", /\w*/) + with_tag("div", /\w*/, :count=>2) + without_tag("div", :text=>"foo", :count=>2) + with_tag("div", :html=>"bar") + with_tag("div", :html=>"bar") + with_tag("div", :html=>/\w*/) + with_tag("div", :html=>/\w*/, :count=>2) + without_tag("div", :html=>"foo", :count=>2) + end + end + + + it "assert_select_from_rjs with one item" do + render_rjs do |page| + page.replace_html "test", "
      foo
      \n
      foo
      " + end + response.should have_tag("div") { |elements| + elements.size.should == 2 + with_tag("#1") + with_tag("#2") + } + + lambda { + response.should have_tag("div") { |elements| + elements.size.should == 2 + with_tag("#1") + with_tag("#3") + } + }.should raise_error(SpecFailed) + + lambda { + response.should have_tag("div") { |elements| + elements.size.should == 2 + with_tag("#1") + without_tag("#2") + } + }.should raise_error(SpecFailed, "should not have tag(\"#2\"), but did") + + lambda { + response.should have_tag("div") { |elements| + elements.size.should == 3 + with_tag("#1") + with_tag("#2") + } + }.should raise_error(SpecFailed) + + + response.should have_tag("div#?", /\d+/) { |elements| + with_tag("#1") + with_tag("#2") + } + end + + it "assert_select_from_rjs with multiple items" do + render_rjs do |page| + page.replace_html "test", "
      foo
      " + page.replace_html "test2", "
      foo
      " + end + response.should have_tag("div") + response.should have_tag("div") { |elements| + elements.size.should == 2 + with_tag("#1") + with_tag("#2") + } + + lambda { + response.should have_tag("div") { |elements| + with_tag("#3") + } + }.should raise_error(SpecFailed) + end +end + +describe "css_select", :behaviour_type => :controller do + include AssertSelectSpecHelpers + controller_name :assert_select + integrate_views + + it "can select tags from html" do + render_html %Q{
      } + css_select("div").size.should == 2 + css_select("p").size.should == 0 + end + + + it "can select nested tags from html" do + render_html %Q{
      foo
      foo
      } + response.should have_tag("div#?", /\d+/) { |elements| + css_select(elements[0], "div").should have(1).element + css_select(elements[1], "div").should have(1).element + } + response.should have_tag("div") { + css_select("div").should have(2).elements + css_select("div").each { |element| + # Testing as a group is one thing + css_select("#1,#2").should have(2).elements + # Testing individually is another + css_select("#1").should have(1).element + css_select("#2").should have(1).element + } + } + end + + it "can select nested tags from rjs (one result)" do + render_rjs do |page| + page.replace_html "test", "
      foo
      \n
      foo
      " + end + css_select("div").should have(2).elements + css_select("#1").should have(1).element + css_select("#2").should have(1).element + end + + it "can select nested tags from rjs (two results)" do + render_rjs do |page| + page.replace_html "test", "
      foo
      " + page.replace_html "test2", "
      foo
      " + end + css_select("div").should have(2).elements + css_select("#1").should have(1).element + css_select("#2").should have(1).element + end + +end + +describe "have_rjs behaviour", :behaviour_type => :controller do + include AssertSelectSpecHelpers + controller_name :assert_select + integrate_views + + before(:each) do + render_rjs do |page| + page.replace "test1", "
      foo
      " + page.replace_html "test2", "
      bar
      none
      " + page.insert_html :top, "test3", "
      loopy
      " + page.hide "test4" + page["test5"].hide + end + end + + it "should pass if any rjs exists" do + response.should have_rjs + end + + it "should fail if no rjs exists" do + render_rjs do |page| + end + lambda do + response.should have_rjs + end.should raise_error(SpecFailed) + end + + it "should find all rjs from multiple statements" do + response.should have_rjs do + with_tag("#1") + with_tag("#2") + with_tag("#3") + # with_tag("#4") + # with_tag("#5") + end + end + + it "should find by id" do + response.should have_rjs("test1") { |rjs| + rjs.size.should == 1 + with_tag("div", 1) + with_tag("div#1", "foo") + } + + lambda do + response.should have_rjs("test1") { |rjs| + rjs.size.should == 1 + without_tag("div#1", "foo") + } + end.should raise_error(SpecFailed, "should not have tag(\"div#1\", \"foo\"), but did") + + response.should have_rjs("test2") { |rjs| + rjs.size.should == 2 + with_tag("div", 2) + with_tag("div#2", "bar") + with_tag("div#3", "none") + } + # response.should have_rjs("test4") + # response.should have_rjs("test5") + end + + # specify "should find rjs using :hide" do + # response.should have_rjs(:hide) + # response.should have_rjs(:hide, "test4") + # response.should have_rjs(:hide, "test5") + # lambda do + # response.should have_rjs(:hide, "test3") + # end.should raise_error(SpecFailed) + # end + + it "should find rjs using :replace" do + response.should have_rjs(:replace) { |rjs| + with_tag("div", 1) + with_tag("div#1", "foo") + } + response.should have_rjs(:replace, "test1") { |rjs| + with_tag("div", 1) + with_tag("div#1", "foo") + } + lambda { + response.should have_rjs(:replace, "test2") + }.should raise_error(SpecFailed) + + lambda { + response.should have_rjs(:replace, "test3") + }.should raise_error(SpecFailed) + end + + it "should find rjs using :replace_html" do + response.should have_rjs(:replace_html) { |rjs| + with_tag("div", 2) + with_tag("div#2", "bar") + with_tag("div#3", "none") + } + + response.should have_rjs(:replace_html, "test2") { |rjs| + with_tag("div", 2) + with_tag("div#2", "bar") + with_tag("div#3", "none") + } + + lambda { + response.should have_rjs(:replace_html, "test1") + }.should raise_error(SpecFailed) + + lambda { + response.should have_rjs(:replace_html, "test3") + }.should raise_error(SpecFailed) + end + + it "should find rjs using :insert_html (non-positioned)" do + response.should have_rjs(:insert_html) { |rjs| + with_tag("div", 1) + with_tag("div#4", "loopy") + } + + response.should have_rjs(:insert_html, "test3") { |rjs| + with_tag("div", 1) + with_tag("div#4", "loopy") + } + + lambda { + response.should have_rjs(:insert_html, "test1") + }.should raise_error(SpecFailed) + + lambda { + response.should have_rjs(:insert_html, "test2") + }.should raise_error(SpecFailed) + end + + it "should find rjs using :insert (positioned)" do + render_rjs do |page| + page.insert_html :top, "test1", "
      foo
      " + page.insert_html :bottom, "test2", "
      bar
      " + page.insert_html :before, "test3", "
      none
      " + page.insert_html :after, "test4", "
      loopy
      " + end + response.should have_rjs(:insert, :top) do + with_tag("div", 1) + with_tag("#1") + end + response.should have_rjs(:insert, :top, "test1") do + with_tag("div", 1) + with_tag("#1") + end + lambda { + response.should have_rjs(:insert, :top, "test2") + }.should raise_error(SpecFailed) + response.should have_rjs(:insert, :bottom) {|rjs| + with_tag("div", 1) + with_tag("#2") + } + response.should have_rjs(:insert, :bottom, "test2") {|rjs| + with_tag("div", 1) + with_tag("#2") + } + response.should have_rjs(:insert, :before) {|rjs| + with_tag("div", 1) + with_tag("#3") + } + response.should have_rjs(:insert, :before, "test3") {|rjs| + with_tag("div", 1) + with_tag("#3") + } + response.should have_rjs(:insert, :after) {|rjs| + with_tag("div", 1) + with_tag("#4") + } + response.should have_rjs(:insert, :after, "test4") {|rjs| + with_tag("div", 1) + with_tag("#4") + } + end +end + +describe "send_email behaviour", :behaviour_type => :controller do + include AssertSelectSpecHelpers + controller_name :assert_select + integrate_views + + before(:each) do + ActionMailer::Base.delivery_method = :test + ActionMailer::Base.perform_deliveries = true + ActionMailer::Base.deliveries = [] + end + + after(:each) do + ActionMailer::Base.deliveries.clear + end + + it "should fail with nothing sent" do + response.should_not send_email + lambda { + response.should send_email{} + }.should raise_error(SpecFailed, /No e-mail in delivery list./) + end + + it "should pass otherwise" do + AssertSelectMailer.deliver_test "

      foo

      bar

      " + response.should send_email + lambda { + response.should_not send_email + }.should raise_error(SpecFailed) + response.should send_email{} + response.should send_email { + with_tag("div:root") { + with_tag("p:first-child", "foo") + with_tag("p:last-child", "bar") + } + } + + lambda { + response.should_not send_email + }.should raise_error(SpecFailed, "should not send email, but did") + end + +end + +# describe "An rjs call to :visual_effect, a 'should have_rjs' spec with", +# :behaviour_type => :view do +# +# before do +# render 'rjs_spec/visual_effect' +# end +# +# it "should pass with the correct element name" do +# response.should have_rjs(:effect, :fade, 'mydiv') +# end +# +# it "should fail the wrong element name" do +# lambda { +# response.should have_rjs(:effect, :fade, 'wrongname') +# }.should raise_error(SpecFailed) +# end +# +# it "should fail with the correct element but the wrong command" do +# lambda { +# response.should have_rjs(:effect, :puff, 'mydiv') +# }.should raise_error(SpecFailed) +# end +# +# end +# +# describe "An rjs call to :visual_effect for a toggle, a 'should have_rjs' spec with", +# :behaviour_type => :view do +# +# before do +# render 'rjs_spec/visual_toggle_effect' +# end +# +# it "should pass with the correct element name" do +# response.should have_rjs(:effect, :toggle_blind, 'mydiv') +# end +# +# it "should fail with the wrong element name" do +# lambda { +# response.should have_rjs(:effect, :toggle_blind, 'wrongname') +# }.should raise_error(SpecFailed) +# end +# +# it "should fail the correct element but the wrong command" do +# lambda { +# response.should have_rjs(:effect, :puff, 'mydiv') +# }.should raise_error(SpecFailed) +# end +# +# end + +describe "string.should have_tag", :behaviour_type => :helper do + include AssertSelectSpecHelpers + + it "should find root element" do + "

      a paragraph

      ".should have_tag("p", "a paragraph") + end + + it "should not find non-existent element" do + lambda do + "

      a paragraph

      ".should have_tag("p", "wrong text") + end.should raise_error(SpecFailed) + end + + it "should find child element" do + "

      a paragraph

      ".should have_tag("p", "a paragraph") + end + + it "should find nested element" do + "

      a paragraph

      ".should have_tag("div") do + with_tag("p", "a paragraph") + end + end + + it "should not find wrong nested element" do + lambda do + "

      a paragraph

      ".should have_tag("div") do + with_tag("p", "wrong text") + end + end.should raise_error(SpecFailed) + end +end + +describe "have_tag", :behaviour_type => :controller do + include AssertSelectSpecHelpers + controller_name :assert_select + integrate_views + + it "should work exactly the same as assert_select" do + render_html %Q{ +
      foo +
      +

      Text

      +
      +
      +

      Another

      +
      +
      + } + + assert_select "#wrapper .piece h3", :text => "Text" + assert_select "#wrapper .piece h3", :text => "Another" + + response.should have_tag("#wrapper .piece h3", :text => "Text") + response.should have_tag("#wrapper .piece h3", :text => "Another") + end +end + diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec/rails/matchers/description_generation_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec/rails/matchers/description_generation_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec/rails/matchers/description_generation_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec/rails/matchers/description_generation_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,40 @@ +require File.dirname(__FILE__) + '/../../spec_helper' + +class DescriptionGenerationSpecController < ActionController::Base + def render_action + end + + def redirect_action + redirect_to :action => :render_action + end +end + +describe "Description generation", :behaviour_type => :controller do + controller_name :description_generation_spec + before(:each) do + Spec::Matchers.clear_generated_description + end + + after(:each) do + Spec::Matchers.clear_generated_description + end + + it "should generate description for render_template" do + get 'render_action' + response.should render_template("render_action") + Spec::Matchers.generated_description.should == "should render template \"render_action\"" + end + + it "should generate description for render_template with full path" do + get 'render_action' + response.should render_template("description_generation_spec/render_action") + Spec::Matchers.generated_description.should == "should render template \"description_generation_spec/render_action\"" + end + + it "should generate description for redirect_to" do + get 'redirect_action' + response.should redirect_to("http://test.host/description_generation_spec/render_action") + Spec::Matchers.generated_description.should == "should redirect to \"http://test.host/description_generation_spec/render_action\"" + end + +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec/rails/matchers/errors_on_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec/rails/matchers/errors_on_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec/rails/matchers/errors_on_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec/rails/matchers/errors_on_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,13 @@ +require File.dirname(__FILE__) + '/../../spec_helper' + +describe "error_on" do + it "should provide a message including the name of what the error is on" do + have(1).error_on(:whatever).description.should == "should have 1 error on :whatever" + end +end + +describe "errors_on" do + it "should provide a message including the name of what the error is on" do + have(2).errors_on(:whatever).description.should == "should have 2 errors on :whatever" + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec/rails/matchers/redirect_to_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec/rails/matchers/redirect_to_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec/rails/matchers/redirect_to_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec/rails/matchers/redirect_to_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,203 @@ +require File.dirname(__FILE__) + '/../../spec_helper' + +['isolation','integration'].each do |mode| + describe "redirect_to behaviour", :behaviour_type => :controller do + if mode == 'integration' + integrate_views + end + controller_name :redirect_spec + + it "redirected to another action" do + get 'action_with_redirect_to_somewhere' + response.should redirect_to(:action => 'somewhere') + end + + it "redirected to another controller and action" do + get 'action_with_redirect_to_other_somewhere' + response.should redirect_to(:controller => 'render_spec', :action => 'text_action') + end + + it "redirected to another action (with 'and return')" do + get 'action_with_redirect_to_somewhere_and_return' + response.should redirect_to(:action => 'somewhere') + end + + it "redirected to correct path with leading /" do + get 'action_with_redirect_to_somewhere' + response.should redirect_to('/redirect_spec/somewhere') + end + + it "redirected to correct path without leading /" do + get 'action_with_redirect_to_somewhere' + response.should redirect_to('redirect_spec/somewhere') + end + + it "redirected to correct internal URL" do + get 'action_with_redirect_to_somewhere' + response.should redirect_to("http://test.host/redirect_spec/somewhere") + end + + it "redirected to correct external URL" do + get 'action_with_redirect_to_rspec_site' + response.should redirect_to("http://rspec.rubyforge.org") + end + + it "redirected :back" do + request.env['HTTP_REFERER'] = "http://test.host/previous/page" + get 'action_with_redirect_back' + response.should redirect_to(:back) + end + + it "redirected :back and should redirect_to URL matches" do + request.env['HTTP_REFERER'] = "http://test.host/previous/page" + get 'action_with_redirect_back' + response.should redirect_to("http://test.host/previous/page") + end + + it "redirected from within a respond_to block" do + get 'action_with_redirect_in_respond_to' + response.should redirect_to('redirect_spec/somewhere') + end + + params_as_hash = {:action => "somewhere", :id => 1111, :param1 => "value1", :param2 => "value2"} + + it "redirected to an internal URL containing a query string" do + get "action_with_redirect_which_creates_query_string" + response.should redirect_to(params_as_hash) + end + + it "redirected to an internal URL containing a query string, one way it might be generated" do + get "action_with_redirect_with_query_string_order1" + response.should redirect_to(params_as_hash) + end + + it "redirected to an internal URL containing a query string, another way it might be generated" do + get "action_with_redirect_with_query_string_order2" + response.should redirect_to(params_as_hash) + end + + it "redirected to an internal URL which is unroutable but matched via a string" do + get "action_with_redirect_to_unroutable_url_inside_app" + response.should redirect_to("http://test.host/nonexistant/none") + end + + end + + + describe "redirect_to with a controller spec in #{mode} mode and a custom request.host", :behaviour_type => :controller do + if mode == 'integration' + integrate_views + end + controller_name :redirect_spec + before do + request.host = "some.custom.host" + end + + it "should pass when redirected to another action" do + get 'action_with_redirect_to_somewhere' + response.should redirect_to(:action => 'somewhere') + end + end + + describe "Given a controller spec in #{mode} mode", :behaviour_type => :controller do + if mode == 'integration' + integrate_views + end + controller_name :redirect_spec + + it "an action that redirects should not result in an error if no should redirect_to expectation is called" do + get 'action_with_redirect_to_somewhere' + end + + it "an action that redirects should not result in an error if should_not redirect_to expectation was called, but not to that action" do + get 'action_with_redirect_to_somewhere' + response.should_not redirect_to(:action => 'another_destination') + end + + it "an action that redirects should result in an error if should_not redirect_to expectation was called to that action" do + get 'action_with_redirect_to_somewhere' + lambda { + response.should_not redirect_to(:action => 'somewhere') + }.should fail_with("expected not to be redirected to {:action=>\"somewhere\"}, but was") + end + + it "an action that does not redirects should not result in an error if should_not redirect_to expectation was called" do + get 'action_with_no_redirect' + response.should_not redirect_to(:action => 'any_destination') + end + + + end + + describe "Given a controller spec in #{mode} mode, should redirect_to should fail when", :behaviour_type => :controller do + if mode == 'integration' + integrate_views + end + controller_name :redirect_spec + + it "redirected to wrong action" do + get 'action_with_redirect_to_somewhere' + lambda { + response.should redirect_to(:action => 'somewhere_else') + }.should fail_with("expected redirect to {:action=>\"somewhere_else\"}, got redirect to \"http://test.host/redirect_spec/somewhere\"") + end + + it "redirected to incorrect path with leading /" do + get 'action_with_redirect_to_somewhere' + lambda { + response.should redirect_to('/redirect_spec/somewhere_else') + }.should fail_with('expected redirect to "/redirect_spec/somewhere_else", got redirect to "http://test.host/redirect_spec/somewhere"') + end + + it "redirected to incorrect path without leading /" do + get 'action_with_redirect_to_somewhere' + lambda { + response.should redirect_to('redirect_spec/somewhere_else') + }.should fail_with('expected redirect to "redirect_spec/somewhere_else", got redirect to "http://test.host/redirect_spec/somewhere"') + end + + it "redirected to incorrect internal URL (based on the action)" do + get 'action_with_redirect_to_somewhere' + lambda { + response.should redirect_to("http://test.host/redirect_spec/somewhere_else") + }.should fail_with('expected redirect to "http://test.host/redirect_spec/somewhere_else", got redirect to "http://test.host/redirect_spec/somewhere"') + end + + it "redirected to wrong external URL" do + get 'action_with_redirect_to_rspec_site' + lambda { + response.should redirect_to("http://test.unit.rubyforge.org") + }.should fail_with('expected redirect to "http://test.unit.rubyforge.org", got redirect to "http://rspec.rubyforge.org"') + end + + it "redirected to incorrect internal URL (based on the directory path)" do + get 'action_with_redirect_to_somewhere' + lambda { + response.should redirect_to("http://test.host/non_existent_controller/somewhere") + }.should fail_with('expected redirect to "http://test.host/non_existent_controller/somewhere", got redirect to "http://test.host/redirect_spec/somewhere"') + end + + it "expected redirect :back, but redirected to a new URL" do + get 'action_with_no_redirect' + lambda { + response.should redirect_to(:back) + }.should fail_with('expected redirect to :back, got no redirect') + end + + it "no redirect at all" do + get 'action_with_no_redirect' + lambda { + response.should redirect_to(:action => 'nowhere') + }.should fail_with("expected redirect to {:action=>\"nowhere\"}, got no redirect") + end + + it "redirected to an internal URL which is unroutable and matched via a hash" do + get "action_with_redirect_to_unroutable_url_inside_app" + route = {:controller => "nonexistant", :action => "none"} + lambda { + response.should redirect_to(route) + }.should raise_error(ActionController::RoutingError, /(no route found to match|No route matches) \"\/nonexistant\/none\" with \{\}/) + end + + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec/rails/matchers/render_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec/rails/matchers/render_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec/rails/matchers/render_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec/rails/matchers/render_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,131 @@ +require File.dirname(__FILE__) + '/../../spec_helper' + +['isolation','integration'].each do |mode| + describe "response.should render_template (in #{mode} mode)", + :behaviour_type => :controller do + controller_name :render_spec + if mode == 'integration' + integrate_views + end + + it "should match a simple path" do + post 'some_action' + response.should render_template('some_action') + end + + it "should match a less simple path" do + post 'some_action' + response.should render_template('render_spec/some_action') + end + + it "should match a less simple path to another controller" do + post 'action_which_renders_template_from_other_controller' + response.should render_template('controller_spec/action_with_template') + end + + it "should match a symbol" do + post 'some_action' + response.should render_template(:some_action) + end + + it "should match an rjs template" do + xhr :post, 'some_action' + if ActionView::Base.const_defined?('DEFAULT_TEMPLATE_HANDLER_PREFERENCE') + response.should render_template('render_spec/some_action') + else + response.should render_template('render_spec/some_action.rjs') + end + end + + it "should match a partial template (simple path)" do + get 'action_with_partial' + response.should render_template("_a_partial") + end + + it "should match a partial template (complex path)" do + get 'action_with_partial' + response.should render_template("render_spec/_a_partial") + end + + it "should fail when the wrong template is rendered" do + post 'some_action' + lambda do + response.should render_template('non_existent_template') + end.should fail_with("expected \"non_existent_template\", got \"render_spec/some_action\"") + end + + it "should fail without full path when template is associated with a different controller" do + post 'action_which_renders_template_from_other_controller' + lambda do + response.should render_template('action_with_template') + end.should fail_with(%Q|expected "action_with_template", got "controller_spec/action_with_template"|) + end + + it "should fail with incorrect full path when template is associated with a different controller" do + post 'action_which_renders_template_from_other_controller' + lambda do + response.should render_template('render_spec/action_with_template') + end.should fail_with(%Q|expected "render_spec/action_with_template", got "controller_spec/action_with_template"|) + end + + it "should fail on the wrong extension (given rhtml)" do + get 'some_action' + lambda { + response.should render_template('render_spec/some_action.rjs') + }.should fail_with("expected \"render_spec/some_action.rjs\", got \"render_spec/some_action\"") + end + + it "should fail when TEXT is rendered" do + post 'text_action' + lambda do + response.should render_template('some_action') + end.should fail_with("expected \"some_action\", got nil") + end + end + + describe "response.should have_text (in #{mode} mode)", + :behaviour_type => :controller do + controller_name :render_spec + if mode == 'integration' + integrate_views + end + + it "should pass with exactly matching text" do + post 'text_action' + response.should have_text("this is the text for this action") + end + + it "should pass with matching text (using Regexp)" do + post 'text_action' + response.should have_text(/is the text/) + end + + it "should fail with matching text" do + post 'text_action' + lambda { + response.should have_text("this is NOT the text for this action") + }.should fail_with("expected \"this is NOT the text for this action\", got \"this is the text for this action\"") + end + + it "should fail when a template is rendered" do + post 'some_action' + lambda { + response.should have_text("this is the text for this action") + }.should fail_with(/expected \"this is the text for this action\", got .*/) + end + end + + describe "response.should_not have_text (in #{mode} mode)", + :behaviour_type => :controller do + controller_name :render_spec + if mode == 'integration' + integrate_views + end + + it "should pass with exactly matching text" do + post 'text_action' + response.should_not have_text("the accordian guy") + end + end + +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec/rails/mocks/mock_model_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec/rails/mocks/mock_model_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec/rails/mocks/mock_model_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec/rails/mocks/mock_model_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,65 @@ +require File.dirname(__FILE__) + '/../../spec_helper' + +class MockableModel < ActiveRecord::Base + has_one :associated_model +end + +class SubMockableModel < MockableModel +end + +class AssociatedModel < ActiveRecord::Base + belongs_to :mockable_model +end + +describe "mock_model", :behaviour_type => :view do + before(:each) do + @model = mock_model(SubMockableModel) + end + it "should say it is_a? if it is" do + @model.is_a?(SubMockableModel).should be(true) + end + it "should say it is_a? if it's ancestor is" do + @model.is_a?(MockableModel).should be(true) + end + it "should say it is kind_of? if it is" do + @model.kind_of?(SubMockableModel).should be(true) + end + it "should say it is kind_of? if it's ancestor is" do + @model.kind_of?(MockableModel).should be(true) + end + it "should say it is instance_of? if it is" do + @model.instance_of?(SubMockableModel).should be(true) + end + it "should not say it instance_of? if it isn't, even if it's ancestor is" do + @model.instance_of?(MockableModel).should be(false) + end +end + +describe "mock_model with null_object", :behaviour_type => :view do + before(:each) do + @model = mock_model(MockableModel, :null_object => true, :mocked_method => "mocked") + end + + it "should be able to mock methods" do + @model.mocked_method.should == "mocked" + end + it "should return itself to unmocked methods" do + @model.unmocked_method.should equal(@model) + end +end + +describe "mock_model as association", :behaviour_type => :view do + before(:each) do + @real = AssociatedModel.create! + @mock_model = mock_model(MockableModel) + @real.mockable_model = @mock_model + end + + it "should pass associated_model == mock" do + @mock_model.should == @real.mockable_model + end + + it "should pass mock == associated_model" do + @real.mockable_model.should == @mock_model + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec/rails/sample_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec/rails/sample_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec/rails/sample_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec/rails/sample_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,7 @@ +require File.dirname(__FILE__) + '/../spec_helper' + +describe "A sample spec" do + it "should pass" do + true.should === true + end +end \ No newline at end of file diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec/rails/spec_server_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec/rails/spec_server_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec/rails/spec_server_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec/rails/spec_server_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,89 @@ +require File.dirname(__FILE__) + '/../spec_helper' + +describe "script/spec_server file", :shared => true do + attr_accessor :tmbundle_install_directory + + after do + system "kill -9 #{@pid}" + end + + it "runs a spec" do + dir = File.dirname(__FILE__) + output = "" + Timeout.timeout(10) do + loop do + output = `#{RAILS_ROOT}/script/spec #{dir}/sample_spec.rb --drb 2>&1` + break unless output.include?("No server is running") + end + end + + unless $?.exitstatus == 0 + flunk "command 'script/spec spec/sample_spec' failed\n#{output}" + end + end + + def start_spec_server + create_spec_server_pid_file + start_spec_server_process + end + + def create_spec_server_pid_file + current_dir = File.dirname(__FILE__) + pid_dir = "#{Dir.tmpdir}/#{Time.now.to_i}" + @spec_server_pid_file = "#{pid_dir}/spec_server.pid" + FileUtils.mkdir_p pid_dir + system "touch #{@spec_server_pid_file}" + @rspec_path = File.expand_path("#{current_dir}/../../../rspec/lib") + end + + def start_spec_server_process + dir = File.dirname(__FILE__) + spec_server_cmd = %Q|export HOME=#{Dir.tmpdir}; | + spec_server_cmd << %Q|ruby -e 'system("echo " + Process.pid.to_s + " > #{@spec_server_pid_file}"); | + spec_server_cmd << %Q|$LOAD_PATH.unshift("#{@rspec_path}"); require "spec"; | + spec_server_cmd << %Q|load "#{RAILS_ROOT}/script/spec_server"' &| + system spec_server_cmd + + file_content = "" + Timeout.timeout(5) do + loop do + file_content = File.read(@spec_server_pid_file) + break unless file_content.blank? + end + end + @pid = Integer(File.read(@spec_server_pid_file)) + end +end + +describe "script/spec_server file without TextMate bundle" do + it_should_behave_like "script/spec_server file" + before do + start_spec_server + end +end + +describe "script/spec_server file with TextMate bundle" do + it_should_behave_like "script/spec_server file" + before do + dir = File.dirname(__FILE__) + @tmbundle_install_directory = File.expand_path("#{Dir.tmpdir}/Library/Application Support/TextMate/Bundles") + @bundle_name = "RSpec.tmbundle" + FileUtils.mkdir_p(tmbundle_install_directory) + bundle_dir = File.expand_path("#{dir}/../../../../../../#{@bundle_name}") + File.directory?(bundle_dir).should be_true + unless system(%Q|ln -s #{bundle_dir} "#{tmbundle_install_directory}"|) + raise "Creating link to Textmate Bundle" + end + start_spec_server + end + + after do + bundle_file_to_remove = "#{tmbundle_install_directory}/#{@bundle_name}" + if bundle_file_to_remove == "/" + raise "bundle file path resolved to '/' - could not call rm" + end + unless system(%Q|rm "#{bundle_file_to_remove}"|) + raise "Removing Textmate bundle link failed" + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec/rails/spec_spec.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec/rails/spec_spec.rb --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec/rails/spec_spec.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec/rails/spec_spec.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,11 @@ +require File.dirname(__FILE__) + '/../spec_helper' + +describe "script/spec file" do + it "should run a spec" do + dir = File.dirname(__FILE__) + output = `#{RAILS_ROOT}/script/spec #{dir}/sample_spec.rb` + unless $?.exitstatus == 0 + flunk "command 'script/spec spec/sample_spec' failed\n#{output}" + end + end +end \ No newline at end of file diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec/rails_suite.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec/rails_suite.rb --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec/rails_suite.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec/rails_suite.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,7 @@ +dir = File.dirname(__FILE__) +Dir["#{dir}/**/*_example.rb"].each do |file| + require file +end +Dir["#{dir}/**/*_spec.rb"].each do |file| + require file +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec/spec_helper.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec/spec_helper.rb --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec/spec_helper.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec/spec_helper.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,48 @@ +dir = File.dirname(__FILE__) +$LOAD_PATH.unshift(File.expand_path("#{dir}/../../../../../rspec/lib")) +$LOAD_PATH.unshift(File.expand_path("#{dir}/../spec_resources/controllers")) +$LOAD_PATH.unshift(File.expand_path("#{dir}/../spec_resources/helpers")) +require File.expand_path("#{dir}/../../../../spec/spec_helper") +require File.expand_path("#{dir}/../spec_resources/controllers/render_spec_controller") +require File.expand_path("#{dir}/../spec_resources/controllers/rjs_spec_controller") +require File.expand_path("#{dir}/../spec_resources/controllers/redirect_spec_controller") +require File.expand_path("#{dir}/../spec_resources/controllers/action_view_base_spec_controller") +require File.expand_path("#{dir}/../spec_resources/helpers/explicit_helper") +require File.expand_path("#{dir}/../spec_resources/helpers/more_explicit_helper") +require File.expand_path("#{dir}/../spec_resources/helpers/view_spec_helper") +require File.expand_path("#{dir}/../spec_resources/helpers/plugin_application_helper") + +if Rails::VERSION::MINOR >= 2 + ActionController::Routing.controller_paths << "#{dir}/../spec_resources/controllers" +end + +module Spec + module Rails + module Example + class ViewExampleController + set_view_path File.join(File.dirname(__FILE__), "..", "spec_resources", "views") + end + end + end +end + +def fail() + raise_error(Spec::Expectations::ExpectationNotMetError) +end + +def fail_with(message) + raise_error(Spec::Expectations::ExpectationNotMetError,message) +end + +class Proc + def should_pass + lambda { self.call }.should_not raise_error + end +end + +ActionController::Routing::Routes.draw do |map| + map.resources :rspec_on_rails_specs + map.connect 'custom_route', :controller => 'custom_route_spec', :action => 'custom_route' + map.connect ":controller/:action/:id" +end + diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec_resources/controllers/action_view_base_spec_controller.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec_resources/controllers/action_view_base_spec_controller.rb --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec_resources/controllers/action_view_base_spec_controller.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec_resources/controllers/action_view_base_spec_controller.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,2 @@ +class ActionViewBaseSpecController < ActionController::Base +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec_resources/controllers/controller_spec_controller.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec_resources/controllers/controller_spec_controller.rb --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec_resources/controllers/controller_spec_controller.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec_resources/controllers/controller_spec_controller.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,48 @@ +class ControllerSpecController < ActionController::Base + if ['edge','2.0.0'].include?(ENV['RSPEC_RAILS_VERSION']) + set_view_path [File.join(File.dirname(__FILE__), "..", "views")] + else + set_view_path File.join(File.dirname(__FILE__), "..", "views") + end + + def some_action + render :template => "template/that/does/not/actually/exist" + end + + def action_with_template + session[:session_key] = "session value" + flash[:flash_key] = "flash value" + render :template => "controller_spec/action_with_template" + end + + def action_with_partial + render :partial => "controller_spec/partial" + end + + def action_with_partial_with_object + render :partial => "controller_spec/partial", :object => params[:thing] + end + + def action_with_partial_with_locals + render :partial => "controller_spec/partial", :locals => {:thing => params[:thing]} + end + + def action_with_errors_in_template + render :template => "controller_spec/action_with_errors_in_template" + end + + def action_setting_the_assigns_hash + assigns['direct_assigns_key'] = :direct_assigns_key_value + end + + def action_setting_flash_after_session_reset + reset_session + flash[:after_reset] = "available" + end + + def action_setting_flash_before_session_reset + flash[:before_reset] = 'available' + reset_session + end +end + diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec_resources/controllers/redirect_spec_controller.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec_resources/controllers/redirect_spec_controller.rb --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec_resources/controllers/redirect_spec_controller.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec_resources/controllers/redirect_spec_controller.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,59 @@ +class RedirectSpecController < ApplicationController + + def action_with_no_redirect + render :text => "this is just here to keep this from causing a MissingTemplate error" + end + + def action_with_redirect_to_somewhere + redirect_to :action => 'somewhere' + end + + def action_with_redirect_to_other_somewhere + redirect_to :controller => 'render_spec', :action => 'text_action' + end + + def action_with_redirect_to_somewhere_and_return + redirect_to :action => 'somewhere' and return + render :text => "this is after the return" + end + + def somewhere + render :text => "this is just here to keep this from causing a MissingTemplate error" + end + + def action_with_redirect_to_rspec_site + redirect_to "http://rspec.rubyforge.org" + end + + def action_with_redirect_back + redirect_to :back + end + + def action_with_redirect_in_respond_to + respond_to do |wants| + wants.html { redirect_to :action => 'somewhere' } + end + end + + def action_with_redirect_which_creates_query_string + redirect_to :action => "somewhere", :id => 1111, :param1 => "value1", :param2 => "value2" + end + + # note: sometimes this is the URL which rails will generate from the hash in + # action_with_redirect_which_creates_query_string + def action_with_redirect_with_query_string_order1 + redirect_to "http://test.host/redirect_spec/somewhere/1111?param1=value1¶m2=value2" + end + + # note: sometimes this is the URL which rails will generate from the hash in + # action_with_redirect_which_creates_query_string + def action_with_redirect_with_query_string_order2 + redirect_to "http://test.host/redirect_spec/somewhere/1111?param2=value2¶m1=value1" + end + + def action_with_redirect_to_unroutable_url_inside_app + redirect_to :controller => "nonexistant", :action => "none" + end + +end + diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec_resources/controllers/render_spec_controller.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec_resources/controllers/render_spec_controller.rb --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec_resources/controllers/render_spec_controller.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec_resources/controllers/render_spec_controller.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,22 @@ +class RenderSpecController < ApplicationController + set_view_path File.join(File.dirname(__FILE__), "..", "views") + + def some_action + respond_to do |format| + format.html + format.js + end + end + + def action_which_renders_template_from_other_controller + render :template => 'controller_spec/action_with_template' + end + + def text_action + render :text => "this is the text for this action" + end + + def action_with_partial + render :partial => "a_partial" + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec_resources/controllers/rjs_spec_controller.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec_resources/controllers/rjs_spec_controller.rb --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec_resources/controllers/rjs_spec_controller.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec_resources/controllers/rjs_spec_controller.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,58 @@ +class RjsSpecController < ApplicationController + set_view_path File.join(File.dirname(__FILE__), "..", "views") + + def replace_html + end + + def insert_html + end + + def replace + end + + def hide_div + end + + def hide_page_element + end + + def replace_html_with_partial + end + + def render_replace_html + render :update do |page| + page.replace_html 'mydiv', 'replacement text' + page.replace_html 'myotherdiv', 'other replacement text' + end + end + + def render_replace_html_with_partial + render :update do |page| + page.replace_html 'mydiv', :partial => 'rjs_spec/replacement_partial' + end + end + + def render_insert_html + render :update do |page| + page.insert_html 'mydiv', 'replacement text' + end + end + + def render_replace + render :update do |page| + page.replace 'mydiv', 'replacement text' + end + end + + def render_hide_div + render :update do |page| + page.hide 'mydiv' + end + end + + def render_hide_page_element + render :update do |page| + page['mydiv'].hide + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec_resources/helpers/explicit_helper.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec_resources/helpers/explicit_helper.rb --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec_resources/helpers/explicit_helper.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec_resources/helpers/explicit_helper.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,10 @@ +module ExplicitHelper + def method_in_explicit_helper + "
      This is text from a method in the ExplicitHelper
      " + end + + # this is an example of a method spec'able with eval_erb in helper specs + def prepend(arg, &block) + concat(arg, block.binding) + block.call + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec_resources/helpers/more_explicit_helper.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec_resources/helpers/more_explicit_helper.rb --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec_resources/helpers/more_explicit_helper.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec_resources/helpers/more_explicit_helper.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,5 @@ +module MoreExplicitHelper + def method_in_more_explicit_helper + "
      This is text from a method in the MoreExplicitHelper
      " + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec_resources/helpers/plugin_application_helper.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec_resources/helpers/plugin_application_helper.rb --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec_resources/helpers/plugin_application_helper.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec_resources/helpers/plugin_application_helper.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,6 @@ +# Methods added to this helper will be available to all templates in the application. +module ApplicationHelper + def method_in_plugin_application_helper + "
      This is text from a method in the ApplicationHelper
      " + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec_resources/helpers/view_spec_helper.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec_resources/helpers/view_spec_helper.rb --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec_resources/helpers/view_spec_helper.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec_resources/helpers/view_spec_helper.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,13 @@ +module ViewSpecHelper + def method_in_helper + "
      This is text from a method in the ViewSpecHelper
      " + end + + def method_in_template_with_partial + "
      method_in_template_with_partial in ViewSpecHelper
      " + end + + def method_in_partial + "
      method_in_partial in ViewSpecHelper
      " + end +end diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec_resources/views/controller_spec/action_setting_flash_after_session_reset.rhtml technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec_resources/views/controller_spec/action_setting_flash_after_session_reset.rhtml --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec_resources/views/controller_spec/action_setting_flash_after_session_reset.rhtml 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec_resources/views/controller_spec/action_setting_flash_after_session_reset.rhtml 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1 @@ + diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec_resources/views/controller_spec/action_setting_flash_before_session_reset.rhtml technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec_resources/views/controller_spec/action_setting_flash_before_session_reset.rhtml --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec_resources/views/controller_spec/action_setting_flash_before_session_reset.rhtml 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec_resources/views/controller_spec/action_setting_flash_before_session_reset.rhtml 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1 @@ + diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec_resources/views/controller_spec/action_with_errors_in_template.rhtml technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec_resources/views/controller_spec/action_with_errors_in_template.rhtml --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec_resources/views/controller_spec/action_with_errors_in_template.rhtml 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec_resources/views/controller_spec/action_with_errors_in_template.rhtml 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1 @@ +<% raise %> \ No newline at end of file diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec_resources/views/controller_spec/action_with_template.rhtml technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec_resources/views/controller_spec/action_with_template.rhtml --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec_resources/views/controller_spec/action_with_template.rhtml 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec_resources/views/controller_spec/action_with_template.rhtml 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1 @@ +
      This is action_with_template.rhtml
      diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec_resources/views/render_spec/some_action.js.rjs technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec_resources/views/render_spec/some_action.js.rjs --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec_resources/views/render_spec/some_action.js.rjs 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec_resources/views/render_spec/some_action.js.rjs 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1 @@ +# This is used for rails > 1.2.3 \ No newline at end of file diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec_resources/views/render_spec/some_action.rjs technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec_resources/views/render_spec/some_action.rjs --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec_resources/views/render_spec/some_action.rjs 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec_resources/views/render_spec/some_action.rjs 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1 @@ +# This is used for rails <= 1.2.3 diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec_resources/views/rjs_spec/_replacement_partial.rhtml technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec_resources/views/rjs_spec/_replacement_partial.rhtml --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec_resources/views/rjs_spec/_replacement_partial.rhtml 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec_resources/views/rjs_spec/_replacement_partial.rhtml 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1 @@ +This is the text in the replacement partial. \ No newline at end of file diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec_resources/views/rjs_spec/hide_div.rjs technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec_resources/views/rjs_spec/hide_div.rjs --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec_resources/views/rjs_spec/hide_div.rjs 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec_resources/views/rjs_spec/hide_div.rjs 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1 @@ +page.hide 'mydiv' diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec_resources/views/rjs_spec/hide_page_element.rjs technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec_resources/views/rjs_spec/hide_page_element.rjs --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec_resources/views/rjs_spec/hide_page_element.rjs 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec_resources/views/rjs_spec/hide_page_element.rjs 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1 @@ +page['mydiv'].hide diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec_resources/views/rjs_spec/insert_html.rjs technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec_resources/views/rjs_spec/insert_html.rjs --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec_resources/views/rjs_spec/insert_html.rjs 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec_resources/views/rjs_spec/insert_html.rjs 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1 @@ +page.insert_html 'mydiv', 'replacement text' diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec_resources/views/rjs_spec/replace.rjs technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec_resources/views/rjs_spec/replace.rjs --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec_resources/views/rjs_spec/replace.rjs 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec_resources/views/rjs_spec/replace.rjs 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1 @@ +page.replace 'mydiv', 'replacement text' diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec_resources/views/rjs_spec/replace_html.rjs technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec_resources/views/rjs_spec/replace_html.rjs --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec_resources/views/rjs_spec/replace_html.rjs 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec_resources/views/rjs_spec/replace_html.rjs 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1 @@ +page.replace_html 'mydiv', 'replacement text' \ No newline at end of file diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec_resources/views/rjs_spec/replace_html_with_partial.rjs technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec_resources/views/rjs_spec/replace_html_with_partial.rjs --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec_resources/views/rjs_spec/replace_html_with_partial.rjs 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec_resources/views/rjs_spec/replace_html_with_partial.rjs 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1 @@ +page.replace_html 'mydiv', :partial => 'rjs_spec/replacement_partial' \ No newline at end of file diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec_resources/views/rjs_spec/visual_effect.rjs technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec_resources/views/rjs_spec/visual_effect.rjs --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec_resources/views/rjs_spec/visual_effect.rjs 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec_resources/views/rjs_spec/visual_effect.rjs 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1 @@ +page.visual_effect :fade, 'mydiv' diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec_resources/views/rjs_spec/visual_toggle_effect.rjs technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec_resources/views/rjs_spec/visual_toggle_effect.rjs --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec_resources/views/rjs_spec/visual_toggle_effect.rjs 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec_resources/views/rjs_spec/visual_toggle_effect.rjs 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1 @@ +page.visual_effect :toggle_blind, 'mydiv' diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec_resources/views/tag_spec/no_tags.rhtml technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec_resources/views/tag_spec/no_tags.rhtml --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec_resources/views/tag_spec/no_tags.rhtml 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec_resources/views/tag_spec/no_tags.rhtml 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1 @@ + \ No newline at end of file diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec_resources/views/tag_spec/single_div_with_no_attributes.rhtml technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec_resources/views/tag_spec/single_div_with_no_attributes.rhtml --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec_resources/views/tag_spec/single_div_with_no_attributes.rhtml 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec_resources/views/tag_spec/single_div_with_no_attributes.rhtml 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1 @@ +
      \ No newline at end of file diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec_resources/views/tag_spec/single_div_with_one_attribute.rhtml technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec_resources/views/tag_spec/single_div_with_one_attribute.rhtml --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec_resources/views/tag_spec/single_div_with_one_attribute.rhtml 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec_resources/views/tag_spec/single_div_with_one_attribute.rhtml 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1 @@ +
      \ No newline at end of file diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec_resources/views/view_spec/_partial.rhtml technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec_resources/views/view_spec/_partial.rhtml --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec_resources/views/view_spec/_partial.rhtml 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec_resources/views/view_spec/_partial.rhtml 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,2 @@ +<%= method_in_plugin_application_helper %> +<%= method_in_partial %> \ No newline at end of file diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec_resources/views/view_spec/_partial_with_local_variable.rhtml technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec_resources/views/view_spec/_partial_with_local_variable.rhtml --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec_resources/views/view_spec/_partial_with_local_variable.rhtml 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec_resources/views/view_spec/_partial_with_local_variable.rhtml 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1 @@ +
      <%= x %>
      \ No newline at end of file diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec_resources/views/view_spec/_partial_with_sub_partial.rhtml technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec_resources/views/view_spec/_partial_with_sub_partial.rhtml --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec_resources/views/view_spec/_partial_with_sub_partial.rhtml 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec_resources/views/view_spec/_partial_with_sub_partial.rhtml 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1 @@ +<%= render :partial => 'partial', :object => partial %> \ No newline at end of file diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec_resources/views/view_spec/_spacer.rhtml technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec_resources/views/view_spec/_spacer.rhtml --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec_resources/views/view_spec/_spacer.rhtml 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec_resources/views/view_spec/_spacer.rhtml 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1 @@ +
      diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec_resources/views/view_spec/accessor.rhtml technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec_resources/views/view_spec/accessor.rhtml --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec_resources/views/view_spec/accessor.rhtml 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec_resources/views/view_spec/accessor.rhtml 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,3 @@ +
      <%= session[:key] %>
      +
      <%= params[:key] %>
      +
      <%= flash[:key] %>
      \ No newline at end of file diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec_resources/views/view_spec/entry_form.rhtml technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec_resources/views/view_spec/entry_form.rhtml --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec_resources/views/view_spec/entry_form.rhtml 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec_resources/views/view_spec/entry_form.rhtml 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,2 @@ +<% form_tag do %> +<% end %> \ No newline at end of file diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec_resources/views/view_spec/explicit_helper.rhtml technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec_resources/views/view_spec/explicit_helper.rhtml --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec_resources/views/view_spec/explicit_helper.rhtml 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec_resources/views/view_spec/explicit_helper.rhtml 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,2 @@ +<%= method_in_plugin_application_helper %> +<%= method_in_explicit_helper %> diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec_resources/views/view_spec/foo/show.rhtml technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec_resources/views/view_spec/foo/show.rhtml --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec_resources/views/view_spec/foo/show.rhtml 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec_resources/views/view_spec/foo/show.rhtml 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1 @@ +<%= method_in_plugin_application_helper %> diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec_resources/views/view_spec/implicit_helper.rhtml technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec_resources/views/view_spec/implicit_helper.rhtml --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec_resources/views/view_spec/implicit_helper.rhtml 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec_resources/views/view_spec/implicit_helper.rhtml 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,2 @@ +<%= method_in_plugin_application_helper %> +<%= method_in_helper %> diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec_resources/views/view_spec/multiple_helpers.rhtml technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec_resources/views/view_spec/multiple_helpers.rhtml --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec_resources/views/view_spec/multiple_helpers.rhtml 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec_resources/views/view_spec/multiple_helpers.rhtml 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,3 @@ +<%= method_in_plugin_application_helper %> +<%= method_in_explicit_helper %> +<%= method_in_more_explicit_helper %> \ No newline at end of file diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec_resources/views/view_spec/template_with_partial.rhtml technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec_resources/views/view_spec/template_with_partial.rhtml --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec_resources/views/view_spec/template_with_partial.rhtml 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec_resources/views/view_spec/template_with_partial.rhtml 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,5 @@ +<%= method_in_template_with_partial %> +<%= render :partial => 'partial' %> + +<%= render :partial => 'partial_used_twice' %> +<%= render :partial => 'partial_used_twice' %> diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec_resources/views/view_spec/template_with_partial_using_collection.rhtml technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec_resources/views/view_spec/template_with_partial_using_collection.rhtml --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec_resources/views/view_spec/template_with_partial_using_collection.rhtml 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec_resources/views/view_spec/template_with_partial_using_collection.rhtml 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,3 @@ +<%= render :partial => 'partial', + :collection => ['Alice', 'Bob'], + :spacer_template => 'spacer' %> diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec_resources/views/view_spec/template_with_partial_with_array.rhtml technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec_resources/views/view_spec/template_with_partial_with_array.rhtml --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/spec_resources/views/view_spec/template_with_partial_with_array.rhtml 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/spec_resources/views/view_spec/template_with_partial_with_array.rhtml 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1 @@ +<%= render :partial => @array %> diff -Nur mephisto-0.7.3/vendor/plugins/rspec_on_rails/tasks/rspec.rake technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/tasks/rspec.rake --- mephisto-0.7.3/vendor/plugins/rspec_on_rails/tasks/rspec.rake 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/rspec_on_rails/tasks/rspec.rake 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,135 @@ +# In rails 1.2, plugins aren't available in the path until they're loaded. +# Check to see if the rspec plugin is installed first and require +# it if it is. If not, use the gem version. +rspec_base = File.expand_path(File.dirname(__FILE__) + '/../../rspec/lib') +$LOAD_PATH.unshift(rspec_base) if File.exist?(rspec_base) +require 'spec/rake/spectask' +require 'spec/translator' + +spec_prereq = File.exist?(File.join(RAILS_ROOT, 'config', 'database.yml')) ? "db:test:prepare" : :noop +task :noop do +end + +task :default => :spec +task :stats => "spec:statsetup" + +desc "Run all specs in spec directory (excluding plugin specs)" +Spec::Rake::SpecTask.new(:spec => spec_prereq) do |t| + t.spec_opts = ['--options', "\"#{RAILS_ROOT}/spec/spec.opts\""] + t.spec_files = FileList['spec/**/*_spec.rb'] +end + +namespace :spec do + desc "Run all specs in spec directory with RCov (excluding plugin specs)" + Spec::Rake::SpecTask.new(:rcov) do |t| + t.spec_opts = ['--options', "\"#{RAILS_ROOT}/spec/spec.opts\""] + t.spec_files = FileList['spec/**/*_spec.rb'] + t.rcov = true + t.rcov_opts = lambda do + IO.readlines("#{RAILS_ROOT}/spec/rcov.opts").map {|l| l.chomp.split " "}.flatten + end + end + + desc "Print Specdoc for all specs (excluding plugin specs)" + Spec::Rake::SpecTask.new(:doc) do |t| + t.spec_opts = ["--format", "specdoc", "--dry-run"] + t.spec_files = FileList['spec/**/*_spec.rb'] + end + + desc "Print Specdoc for all plugin specs" + Spec::Rake::SpecTask.new(:plugin_doc) do |t| + t.spec_opts = ["--format", "specdoc", "--dry-run"] + t.spec_files = FileList['vendor/plugins/**/spec/**/*_spec.rb'].exclude('vendor/plugins/rspec/*') + end + + [:models, :controllers, :views, :helpers, :lib].each do |sub| + desc "Run the specs under spec/#{sub}" + Spec::Rake::SpecTask.new(sub => spec_prereq) do |t| + t.spec_opts = ['--options', "\"#{RAILS_ROOT}/spec/spec.opts\""] + t.spec_files = FileList["spec/#{sub}/**/*_spec.rb"] + end + end + + desc "Run the specs under vendor/plugins (except RSpec's own)" + Spec::Rake::SpecTask.new(:plugins => spec_prereq) do |t| + t.spec_opts = ['--options', "\"#{RAILS_ROOT}/spec/spec.opts\""] + t.spec_files = FileList['vendor/plugins/**/spec/**/*_spec.rb'].exclude('vendor/plugins/rspec/*').exclude("vendor/plugins/rspec_on_rails/*") + end + + namespace :plugins do + desc "Runs the examples for rspec_on_rails" + Spec::Rake::SpecTask.new(:rspec_on_rails => spec_prereq) do |t| + t.spec_opts = ['--options', "\"#{RAILS_ROOT}/spec/spec.opts\""] + t.spec_files = FileList['vendor/plugins/rspec_on_rails/spec/**/*_spec.rb'] + end + end + + desc "Translate/upgrade specs using the built-in translator" + task :translate do + translator = ::Spec::Translator.new + dir = RAILS_ROOT + '/spec' + translator.translate(dir, dir) + end + + # Setup specs for stats + task :statsetup do + require 'code_statistics' + ::STATS_DIRECTORIES << %w(Model\ specs spec/models) + ::STATS_DIRECTORIES << %w(View\ specs spec/views) + ::STATS_DIRECTORIES << %w(Controller\ specs spec/controllers) + ::STATS_DIRECTORIES << %w(Helper\ specs spec/helpers) + ::CodeStatistics::TEST_TYPES << "Model specs" + ::CodeStatistics::TEST_TYPES << "View specs" + ::CodeStatistics::TEST_TYPES << "Controller specs" + ::CodeStatistics::TEST_TYPES << "Helper specs" + ::STATS_DIRECTORIES.delete_if {|a| a[0] =~ /test/} + end + + namespace :db do + namespace :fixtures do + desc "Load fixtures (from spec/fixtures) into the current environment's database. Load specific fixtures using FIXTURES=x,y" + task :load => :environment do + require 'active_record/fixtures' + ActiveRecord::Base.establish_connection(RAILS_ENV.to_sym) + (ENV['FIXTURES'] ? ENV['FIXTURES'].split(/,/) : Dir.glob(File.join(RAILS_ROOT, 'spec', 'fixtures', '*.{yml,csv}'))).each do |fixture_file| + Fixtures.create_fixtures('spec/fixtures', File.basename(fixture_file, '.*')) + end + end + end + end + + namespace :server do + daemonized_server_pid = File.expand_path("spec_server.pid", RAILS_ROOT + "/tmp") + + desc "start spec_server." + task :start do + if File.exist?(daemonized_server_pid) + $stderr.puts "spec_server is already running." + else + $stderr.puts "Starting up spec server." + system("ruby", "script/spec_server", "--daemon", "--pid", daemonized_server_pid) + end + end + + desc "stop spec_server." + task :stop do + unless File.exist?(daemonized_server_pid) + $stderr.puts "No server running." + else + $stderr.puts "Shutting down spec_server." + system("kill", "-s", "TERM", File.read(daemonized_server_pid).strip) && + File.delete(daemonized_server_pid) + end + end + + desc "reload spec_server." + task :restart do + unless File.exist?(daemonized_server_pid) + $stderr.puts "No server running." + else + $stderr.puts "Reloading down spec_server." + system("kill", "-s", "USR2", File.read(daemonized_server_pid).strip) + end + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/simply_bdd/README technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/simply_bdd/README --- mephisto-0.7.3/vendor/plugins/simply_bdd/README 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/simply_bdd/README 1969-12-31 19:00:00.000000000 -0500 @@ -1,30 +0,0 @@ -SimplyBdd -========= - -Allows you to use context and specify macros for creating TestCase classes - -context "New User" do - def setup - @user = User.new - end - - specify "should be invalid without a username" do - assert !@user.valid? - @user.username = 'someusername' - assert_valid @user - end -end - -This (dynamically) generates a class like: - -class NewUserTest < Test::Unit::TestCase - def setup - @user = User.new - end - - def test_should_be_invalid_without_a_username - assert !@user.valid? - @user.username = 'someusername' - assert_valid @user - end -end \ No newline at end of file diff -Nur mephisto-0.7.3/vendor/plugins/simply_bdd/Rakefile technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/simply_bdd/Rakefile --- mephisto-0.7.3/vendor/plugins/simply_bdd/Rakefile 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/simply_bdd/Rakefile 1969-12-31 19:00:00.000000000 -0500 @@ -1,22 +0,0 @@ -require 'rake' -require 'rake/testtask' -require 'rake/rdoctask' - -desc 'Default: run unit tests.' -task :default => :test - -desc 'Test the simply_bdd plugin.' -Rake::TestTask.new(:test) do |t| - t.libs << 'lib' - t.pattern = 'test/**/*_test.rb' - t.verbose = true -end - -desc 'Generate documentation for the simply_bdd plugin.' -Rake::RDocTask.new(:rdoc) do |rdoc| - rdoc.rdoc_dir = 'rdoc' - rdoc.title = 'SimplyBdd' - rdoc.options << '--line-numbers' << '--inline-source' - rdoc.rdoc_files.include('README') - rdoc.rdoc_files.include('lib/**/*.rb') -end diff -Nur mephisto-0.7.3/vendor/plugins/simply_bdd/init.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/simply_bdd/init.rb --- mephisto-0.7.3/vendor/plugins/simply_bdd/init.rb 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/simply_bdd/init.rb 1969-12-31 19:00:00.000000000 -0500 @@ -1,20 +0,0 @@ -if RAILS_ENV == 'test' - Object.class_eval do - def context(name, &block) - # create class first so it has a name before evaling the block. this is so fixtures work correctly. - returning self.class.const_set(self.class.convert_bdd_name(name).camelize + 'Test', Class.new(Test::Unit::TestCase)) do |klass| - klass.class_eval &block - end - end - - def self.convert_bdd_name(name) - name.to_s.gsub(/[^\w ]+/, '').gsub(/ +/, '_') - end - end - - class << Test::Unit::TestCase - def specify(name, &block) - define_method 'test_' + convert_bdd_name(name), &block - end - end -end \ No newline at end of file diff -Nur mephisto-0.7.3/vendor/plugins/simply_helpful/CHANGELOG technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/simply_helpful/CHANGELOG --- mephisto-0.7.3/vendor/plugins/simply_helpful/CHANGELOG 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/simply_helpful/CHANGELOG 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,9 @@ +* Added formatted_polymorphic_url, formatted_polymorphic_path + +* Added support for route options. Example: + + polymorphic_url(:id => @subject, :anchor => "photo") + +* Added polymorphic routes for new and edit actions (new_polymorphic_url, edit_polymorphic_url) + +* Moved polymorphic routes from SimplyHelpful::RecordIdentifier to SimplyHelpful::PolymorphicRoutes \ No newline at end of file diff -Nur mephisto-0.7.3/vendor/plugins/simply_helpful/init.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/simply_helpful/init.rb --- mephisto-0.7.3/vendor/plugins/simply_helpful/init.rb 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/simply_helpful/init.rb 2008-03-31 02:18:56.000000000 -0400 @@ -1,2 +1,4 @@ require 'simply_helpful' -ActionController::Base.helper(SimplyHelpful::RecordIdentificationHelper, SimplyHelpful::RecordTagHelper) \ No newline at end of file +ActionController::Base.send :include, SimplyHelpful::RecordIdentificationHelper +ActionController::Base.helper SimplyHelpful::RecordIdentificationHelper, + SimplyHelpful::RecordTagHelper diff -Nur mephisto-0.7.3/vendor/plugins/simply_helpful/lib/simply_helpful/controller_extensions.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/simply_helpful/lib/simply_helpful/controller_extensions.rb --- mephisto-0.7.3/vendor/plugins/simply_helpful/lib/simply_helpful/controller_extensions.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/simply_helpful/lib/simply_helpful/controller_extensions.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,42 @@ +module SimplyHelpful + module ActionControllerExtensions + POLYMORPHIC_ROUTES = %w( + polymorphic_url polymorphic_path + edit_polymorphic_url edit_polymorphic_path + new_polymorphic_url new_polymorphic_path + formatted_polymorphic_url formatted_polymorphic_path + ) + + def self.included(base) + POLYMORPHIC_ROUTES.each { |route| base.helper_method(route) } + end + + POLYMORPHIC_ROUTES.each do |route| + module_eval <<-EOT + def #{route}(record) + SimplyHelpful::PolymorphicRoutes.#{route}(record, self) + end + EOT + end + + def redirect_to_with_record_identification(*args) + return redirect_to_without_record_identification *args unless args.size == 1 + + potential_object = args.first + + case potential_object + when String, Symbol, Hash + redirect_to_without_record_identification *args + else + redirect_to_without_record_identification SimplyHelpful::PolymorphicRoutes.polymorphic_url(potential_object, self) + end + end + end +end + +module ActionController + class Base + include SimplyHelpful::ActionControllerExtensions + alias_method_chain :redirect_to, :record_identification + end +end \ No newline at end of file diff -Nur mephisto-0.7.3/vendor/plugins/simply_helpful/lib/simply_helpful/form_helper_extensions.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/simply_helpful/lib/simply_helpful/form_helper_extensions.rb --- mephisto-0.7.3/vendor/plugins/simply_helpful/lib/simply_helpful/form_helper_extensions.rb 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/simply_helpful/lib/simply_helpful/form_helper_extensions.rb 2008-03-31 02:18:56.000000000 -0400 @@ -18,7 +18,7 @@ object_name = SimplyHelpful::RecordIdentifier.singular_class_name(name_or_object) object = name_or_object - url = SimplyHelpful::RecordIdentifier.named_route(object, self) + url = SimplyHelpful::PolymorphicRoutes.polymorphic_url(object, self) html_options = if object.new_record? { :class => dom_class(object, :new), :id => dom_id(object), :method => :post } diff -Nur mephisto-0.7.3/vendor/plugins/simply_helpful/lib/simply_helpful/polymorphic_routes.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/simply_helpful/lib/simply_helpful/polymorphic_routes.rb --- mephisto-0.7.3/vendor/plugins/simply_helpful/lib/simply_helpful/polymorphic_routes.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/simply_helpful/lib/simply_helpful/polymorphic_routes.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,52 @@ +module SimplyHelpful + module PolymorphicRoutes + extend self + + def polymorphic_url(record_or_hash, url_writer, options = {}) + record = extract_record(record_or_hash) + + case + when options[:action] == "new" + url_writer.send(action_prefix(options) + RecordIdentifier.singular_class_name(record) + routing_type(options)) + + when record.new_record? + url_writer.send(RecordIdentifier.plural_class_name(record) + routing_type(options)) + + else + url_writer.send( + action_prefix(options) + RecordIdentifier.singular_class_name(record) + routing_type(options), record_or_hash + ) + end + end + + def polymorphic_path(record_or_hash, url_writer) + polymorphic_url(record_or_hash, url_writer, :routing_type => :path) + end + + %w( edit new formatted ).each do |action| + module_eval <<-EOT + def #{action}_polymorphic_url(record_or_hash, url_writer) + polymorphic_url(record_or_hash, url_writer, :action => "#{action}") + end + + def #{action}_polymorphic_path(record_or_hash, url_writer) + polymorphic_url(record_or_hash, url_writer, :action => "#{action}", :routing_type => :path) + end + EOT + end + + + private + def action_prefix(options) + options[:action] ? "#{options[:action]}_" : "" + end + + def routing_type(options) + "_#{options[:routing_type] || "url"}" + end + + def extract_record(record_or_hash) + record_or_hash.is_a?(Hash) ? record_or_hash[:id] : record_or_hash + end + end +end diff -Nur mephisto-0.7.3/vendor/plugins/simply_helpful/lib/simply_helpful/record_identification_helper.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/simply_helpful/lib/simply_helpful/record_identification_helper.rb --- mephisto-0.7.3/vendor/plugins/simply_helpful/lib/simply_helpful/record_identification_helper.rb 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/simply_helpful/lib/simply_helpful/record_identification_helper.rb 2008-03-31 02:18:56.000000000 -0400 @@ -1,15 +1,16 @@ module SimplyHelpful module RecordIdentificationHelper - def partial_path(*args, &block) - RecordIdentifier.partial_path(*args, &block) - end - - def dom_class(*args, &block) - RecordIdentifier.dom_class(*args, &block) - end + protected + def partial_path(*args, &block) + RecordIdentifier.partial_path(*args, &block) + end - def dom_id(*args, &block) - RecordIdentifier.dom_id(*args, &block) - end + def dom_class(*args, &block) + RecordIdentifier.dom_class(*args, &block) + end + + def dom_id(*args, &block) + RecordIdentifier.dom_id(*args, &block) + end end -end \ No newline at end of file +end diff -Nur mephisto-0.7.3/vendor/plugins/simply_helpful/lib/simply_helpful/record_identifier.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/simply_helpful/lib/simply_helpful/record_identifier.rb --- mephisto-0.7.3/vendor/plugins/simply_helpful/lib/simply_helpful/record_identifier.rb 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/simply_helpful/lib/simply_helpful/record_identifier.rb 2008-03-31 02:18:56.000000000 -0400 @@ -2,12 +2,6 @@ module RecordIdentifier extend self - def named_route(record, url_writer) - record.new_record? ? - url_writer.send(plural_class_name(record) + "_url") : - url_writer.send(singular_class_name(record) + "_url", record) - end - def partial_path(record_or_class) klass = class_from_record_or_class(record_or_class) "#{klass.name.tableize}/#{klass.name.demodulize.underscore}" diff -Nur mephisto-0.7.3/vendor/plugins/simply_helpful/lib/simply_helpful/record_tag_helper.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/simply_helpful/lib/simply_helpful/record_tag_helper.rb --- mephisto-0.7.3/vendor/plugins/simply_helpful/lib/simply_helpful/record_tag_helper.rb 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/simply_helpful/lib/simply_helpful/record_tag_helper.rb 2008-03-31 02:18:56.000000000 -0400 @@ -1,9 +1,55 @@ module SimplyHelpful module RecordTagHelper + # Produces a wrapper DIV element with id and class parameters that + # relate to the specified ActiveRecord object. Usage example: + # + # <% div_for(@person, :class => "foo") do %> + # <%=h @person.name %> + # <% end %> + # + # produces: + # + #
      Joe Bloggs
      + # def div_for(record, *args, &block) + content_tag_for(:div, record, *args, &block) + end + + # content_tag_for creates an HTML element with id and class parameters + # that relate to the specified ActiveRecord object. For example: + # + # <% content_tag_for(:tr, @person) do %> + # <%=h @person.first_name %> + # <%=h @person.last_name %> + # <% end %> + # + # would produce hthe following HTML (assuming @person is an instance of + # a Person object, with an id value of 123): + # + # .... + # + # If you require the HTML id attribute to have a prefix, you can specify it: + # + # <% content_tag_for(:tr, @person, :foo) do %> ... + # + # produces: + # + # ... + # + # content_tag_for also accepts a hash of options, which will be converted to + # additional HTML attributes. If you specify a +:class+ value, it will be combined + # with the default class name for your object. For example: + # + # <% content_tag_for(:li, @person, :class => "bar") %>... + # + # produces: + # + #
    • ... + # + def content_tag_for(tag_name, record, *args, &block) prefix = args.first.is_a?(Hash) ? nil : args.shift options = args.first.is_a?(Hash) ? args.shift : {} - concat content_tag(:div, capture(&block), + concat content_tag(tag_name, capture(&block), options.merge({ :class => "#{dom_class(record)} #{options[:class]}".strip, :id => dom_id(record, prefix) })), block.binding end @@ -18,8 +64,9 @@ when Hash, String, Symbol, NilClass link_to_without_record_identification(attr_name, record, html_options, *parameters_for_method_reference) else - url = SimplyHelpful::RecordIdentifier.named_route(record, self) - link_to_without_record_identification(record.send(attr_name), url, html_options, *parameters_for_method_reference) + url = SimplyHelpful::PolymorphicRoutes.polymorphic_url(record, self) + link_text = record.respond_to?(attr_name) ? record.send(attr_name) : attr_name + link_to_without_record_identification(link_text, url, html_options, *parameters_for_method_reference) end end diff -Nur mephisto-0.7.3/vendor/plugins/simply_helpful/lib/simply_helpful.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/simply_helpful/lib/simply_helpful.rb --- mephisto-0.7.3/vendor/plugins/simply_helpful/lib/simply_helpful.rb 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/simply_helpful/lib/simply_helpful.rb 2008-03-31 02:18:56.000000000 -0400 @@ -2,6 +2,9 @@ require 'simply_helpful/record_identifier' require 'simply_helpful/record_tag_helper' +require 'simply_helpful/polymorphic_routes' + require 'simply_helpful/jsg_extensions' require 'simply_helpful/av_extensions' -require 'simply_helpful/form_helper_extensions' \ No newline at end of file +require 'simply_helpful/form_helper_extensions' +require 'simply_helpful/controller_extensions' \ No newline at end of file diff -Nur mephisto-0.7.3/vendor/plugins/simply_helpful/test/controller_extensions_test.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/simply_helpful/test/controller_extensions_test.rb --- mephisto-0.7.3/vendor/plugins/simply_helpful/test/controller_extensions_test.rb 1969-12-31 19:00:00.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/simply_helpful/test/controller_extensions_test.rb 2008-03-31 02:18:56.000000000 -0400 @@ -0,0 +1,52 @@ +require File.dirname(__FILE__) + '/test_helper' +require 'ostruct' + +class RedirectionTestingController < ActionController::Base + class MockResponse + attr_accessor :redirected_to + + def redirect(_) + end + + end + + def initialize + super + @response = MockResponse.new + @request = OpenStruct.new + @request.protocol= "http://" + @request.host_with_port= "www.example.com" + end + + def response + @response + end + + def request + @request + end + + def post_url(p) + "/posts/#{p.id}" + end + + +end + +class ControllerExtensionsTest < Test::Unit::TestCase + def setup + @record = Post.new + @record.save + @controller = RedirectionTestingController.new + end + + def test_redirect_to_record + @controller.send :redirect_to, @record + assert_equal "http://www.example.com/posts/1", @controller.response.redirected_to + end + + def test_redirect_to_string + @controller.send :redirect_to, "http://www.yahoo.com" + assert_equal "http://www.yahoo.com", @controller.response.redirected_to + end +end \ No newline at end of file diff -Nur mephisto-0.7.3/vendor/plugins/simply_helpful/test/form_helper_extensions_test.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/simply_helpful/test/form_helper_extensions_test.rb --- mephisto-0.7.3/vendor/plugins/simply_helpful/test/form_helper_extensions_test.rb 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/simply_helpful/test/form_helper_extensions_test.rb 2008-03-31 02:18:56.000000000 -0400 @@ -65,7 +65,7 @@ _erbout = '' form_for(@record) {} - expected = "
      " + expected = "
      " assert_dom_equal expected, _erbout end @@ -90,7 +90,7 @@ _erbout = '' remote_form_for(@record) {} - expected = %(
      ) + expected = %(
      ) assert_dom_equal expected, _erbout end end \ No newline at end of file diff -Nur mephisto-0.7.3/vendor/plugins/simply_helpful/test/record_identifier_test.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/simply_helpful/test/record_identifier_test.rb --- mephisto-0.7.3/vendor/plugins/simply_helpful/test/record_identifier_test.rb 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/simply_helpful/test/record_identifier_test.rb 2008-03-31 02:18:56.000000000 -0400 @@ -77,4 +77,4 @@ assert_equal expected, partial_path(@record) assert_equal expected, partial_path(Post::Nested) end -end +end \ No newline at end of file diff -Nur mephisto-0.7.3/vendor/plugins/simply_helpful/test/record_tag_helper_test.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/simply_helpful/test/record_tag_helper_test.rb --- mephisto-0.7.3/vendor/plugins/simply_helpful/test/record_tag_helper_test.rb 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/simply_helpful/test/record_tag_helper_test.rb 2008-03-31 02:18:56.000000000 -0400 @@ -12,6 +12,54 @@ @record = Post.new end + def test_content_tag_for_with_new_record + _erbout = '' + content_tag_for(:li, @record) {} + + expected = "
    • " + assert_dom_equal expected, _erbout + end + + def test_content_tag_for_with_existing_record + @record.save + _erbout = '' + content_tag_for(:li, @record) {} + + expected = "
    • " + assert_dom_equal expected, _erbout + end + + def test_content_tag_for_merges_given_class_names + _erbout = '' + content_tag_for(:li, @record, :class => 'foo') {} + + expected = "
    • " + assert_dom_equal expected, _erbout + + _erbout = '' + content_tag_for(:li, @record, :class => 'foo bar') {} + + expected = "
    • " + assert_dom_equal expected, _erbout + end + + def test_content_tag_for_with_dom_id_prefix_on_new_record + _erbout = '' + content_tag_for(:li, @record, :foo, :class => 'foo') {} + + expected = "
    • " + assert_dom_equal expected, _erbout + end + + def test_content_tag_for_with_dom_id_prefix_on_existing_record + @record.save + _erbout = '' + content_tag_for(:li, @record, :foo, :class => 'foo') {} + + expected = "
    • " + assert_dom_equal expected, _erbout + end + def test_div_for_with_new_record _erbout = '' div_for(@record) {} @@ -74,4 +122,12 @@ expected = "post #1" assert_dom_equal expected, actual end + + def test_link_to_with_an_existing_method_and_constant_text + @record.save + actual = link_to "Cancel Editing", @record + + expected = "Cancel Editing" + assert_dom_equal expected, actual + end end \ No newline at end of file diff -Nur mephisto-0.7.3/vendor/plugins/white_list/README technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/white_list/README --- mephisto-0.7.3/vendor/plugins/white_list/README 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/white_list/README 2008-03-31 02:18:56.000000000 -0400 @@ -10,26 +10,20 @@ You can add or remove tags/attributes if you want to customize it a bit. -add table tags +Add table tags - WhiteListHelper.tags += %w(table td th) + WhiteListHelper.tags.merge %w(table td th) -remove tags +Remove tags - WhiteListHelper.tags -= %w(div span) + WhiteListHelper.tags.delete 'div' -clear any attributes that are allowed for tags +Change allowed attributes - WhiteListHelper.attributes['a'] = [] + WhiteListHelper.attributes.merge %w(id class style) -allow a new attribute for the tag +white_list accepts a block for custom tag escaping. Shown below is the default block that white_list uses if none is given. +The block is called for all bad tags, and every text node. node is an instance of HTML::Node (either HTML::Tag or HTML::Text). +bad is nil for text nodes inside good tags, or is the tag name of the bad tag. - WhiteListHelper.attributes['img'] += %w(style) - -add new tag with attributes - - WhiteListHelper.attributes['table'] = %w(cellpadding cellspacing) - -change allowed attributes for all tags - - WhiteListHelper.attributes[nil] = %w(id class style) \ No newline at end of file + <%= white_list(@article.body) { |node, bad| white_listed_bad_tags.include?(bad) ? nil : node.to_s.gsub(/ \ No newline at end of file diff -Nur mephisto-0.7.3/vendor/plugins/white_list/lib/white_list_helper.rb technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/white_list/lib/white_list_helper.rb --- mephisto-0.7.3/vendor/plugins/white_list/lib/white_list_helper.rb 2006-11-23 13:57:06.000000000 -0500 +++ technoweenie-mephisto-9072b487bf45c5e41e33c66b32d94aea84732d1b/vendor/plugins/white_list/lib/white_list_helper.rb 2008-03-31 02:18:56.000000000 -0400 @@ -1,61 +1,97 @@ module WhiteListHelper - PROTOCOL_ATTRIBUTES = %w(src href) - PROTOCOL_SEPARATOR = /:|(�*58)|(p)|(%|%)3A/ - mattr_reader :tags, :attributes, :protocols - @@tags = %w(strong em b i p code pre tt output samp kbd var sub sup dfn cite big small address hr br div span h1 h2 h3 h4 h5 h6 ul ol li dt dd abbr acronym) - @@attributes = { - 'a' => %w(href), - 'img' => %w(src width height alt), - 'blockquote' => %w(cite), - 'del' => %w(cite datetime), - 'ins' => %w(cite datetime), - nil => %w(title class) } - @@protocols = %w(ed2k ftp http https irc mailto news gopher nntp telnet webcal xmpp callto feed) - tags.push(*attributes.keys).uniq! + @@protocol_attributes = Set.new %w(src href) + @@protocol_separator = /:|(�*58)|(p)|(%|%)3A/ + mattr_reader :protocol_attributes, :protocol_separator - def white_listed_tags - ::WhiteListHelper.tags - end - - def white_listed_attributes - ::WhiteListHelper.attributes + def self.contains_bad_protocols?(white_listed_protocols, value) + value =~ protocol_separator && !white_listed_protocols.include?(value.split(protocol_separator).first) end - def white_listed_protocols - ::WhiteListHelper.protocols + klass = class << self; self; end + klass_methods = [] + inst_methods = [] + [:bad_tags, :tags, :attributes, :protocols].each do |attr| + # Add class methods to the module itself + klass_methods << <<-EOS + def #{attr}=(value) @@#{attr} = Set.new(value) end + def #{attr}() @@#{attr} end + EOS + + # prefix the instance methods with white_listed_* + inst_methods << "def white_listed_#{attr}() ::WhiteListHelper.#{attr} end" end + + klass.class_eval klass_methods.join("\n"), __FILE__, __LINE__ + class_eval inst_methods.join("\n"), __FILE__, __LINE__ - def white_list(html, options = {}) + # This White Listing helper will html encode all tags and strip all attributes that aren't specifically allowed. + # It also strips href/src tags with invalid protocols, like javascript: especially. It does its best to counter any + # tricks that hackers may use, like throwing in unicode/ascii/hex values to get past the javascript: filters. Check out + # the extensive test suite. + # + # <%= white_list @article.body %> + # + # You can add or remove tags/attributes if you want to customize it a bit. + # + # Add table tags + # + # WhiteListHelper.tags.merge %w(table td th) + # + # Remove tags + # + # WhiteListHelper.tags.delete 'div' + # + # Change allowed attributes + # + # WhiteListHelper.attributes.merge %w(id class style) + # + # white_list accepts a block for custom tag escaping. Shown below is the default block that white_list uses if none is given. + # The block is called for all bad tags, and every text node. node is an instance of HTML::Node (either HTML::Tag or HTML::Text). + # bad is nil for text nodes inside good tags, or is the tag name of the bad tag. + # + # <%= white_list(@article.body) { |node, bad| white_listed_bad_tags.include?(bad) ? nil : node.to_s.gsub(/ + # + def white_list(html, options = {}, &block) return html if html.blank? || !html.include?('<') - (options[:attributes] ||= {}).update(white_listed_attributes) - (options[:tags] ||= []).push(*options[:attributes].keys).push(*white_listed_tags).uniq! + attrs = Set.new(options[:attributes]).merge(white_listed_attributes) + tags = Set.new(options[:tags] ).merge(white_listed_tags) + block ||= lambda { |node, bad| white_listed_bad_tags.include?(bad) ? nil : node.to_s.gsub(/foo bar baz end", "start <#{tag_name} title='1'>foo <bad>bar</bad> baz end" + assert_white_listed "start <#{tag_name} title=\"1\" name=\"foo\">foo bar baz end", %(start <#{tag_name} title="1">foo <bad>bar</bad> baz end) end end def test_should_allow_anchors - assert_white_listed %(), "<script>baz</script>" + assert_white_listed %(), %() end - WhiteListHelper.attributes['img'].each do |img_attr| + %w(src width height alt).each do |img_attr| define_method "test_should_allow_image_#{img_attr}_attribute" do - assert_white_listed %(), "" + assert_white_listed %(), %() end end @@ -36,13 +36,13 @@ end def test_should_allow_custom_tags_with_attributes - text = "
      foo
      " - assert_equal(text, white_list(text, :attributes => {'fieldset' => %w(foo)})) + text = %(
      foo
      ) + assert_equal(text, white_list(text, :attributes => ['foo'])) end [%w(img src), %w(a href)].each do |(tag, attr)| define_method "test_should_strip_#{attr}_attribute_in_#{tag}_with_bad_protocols" do - assert_white_listed %(<#{tag} #{attr}="javascript:bang" title="1">boo), %(<#{tag} title='1'>boo) + assert_white_listed %(<#{tag} #{attr}="javascript:bang" title="1">boo), %(<#{tag} title="1">boo) end end @@ -64,7 +64,7 @@ end def test_should_block_script_tag - assert_white_listed %(), "<script src='http:' /></script>" + assert_white_listed %(), "" end [%(), @@ -92,16 +92,16 @@ end def test_should_sanitize_invalid_script_tag - assert_white_listed %(), "<script /></script>" + assert_white_listed %(), "" end def test_should_sanitize_script_tag_with_multiple_open_brackets - assert_white_listed %(<), "<<script>alert(\"XSS\");//<</script>" - assert_white_listed %(