diff --git a/tracks/public/javascripts/controls.js b/tracks/public/javascripts/controls.js index 9742b691..de0261ed 100644 --- a/tracks/public/javascripts/controls.js +++ b/tracks/public/javascripts/controls.js @@ -141,8 +141,8 @@ Autocompleter.Base.prototype = { return; } else - if(event.keyCode==Event.KEY_TAB || event.keyCode==Event.KEY_RETURN) - return; + if(event.keyCode==Event.KEY_TAB || event.keyCode==Event.KEY_RETURN || + (navigator.appVersion.indexOf('AppleWebKit') > 0 && event.keyCode == 0)) return; this.changed = true; this.hasFocus = true; @@ -152,6 +152,12 @@ Autocompleter.Base.prototype = { 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) @@ -221,8 +227,13 @@ Autocompleter.Base.prototype = { this.options.updateElement(selectedElement); return; } - - var value = Element.collectTextNodesIgnoreClass(selectedElement, 'informal'); + 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 lastTokenPos = this.findLastToken(); if (lastTokenPos != -1) { var newValue = this.element.value.substr(0, lastTokenPos + 1); @@ -305,7 +316,7 @@ Autocompleter.Base.prototype = { 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.baseInitialize(element, update, options); this.options.asynchronous = true; this.options.onComplete = this.onComplete.bind(this); this.options.defaultParams = this.options.parameters || null; @@ -448,7 +459,9 @@ Ajax.InPlaceEditor.prototype = { this.element = $(element); this.options = Object.extend({ + okButton: true, okText: "ok", + cancelLink: true, cancelText: "cancel", savingText: "Saving...", clickToEditText: "Click to edit", @@ -470,8 +483,10 @@ Ajax.InPlaceEditor.prototype = { formClassName: 'inplaceeditor-form', highlightcolor: Ajax.InPlaceEditor.defaultHighlightColor, highlightendcolor: "#FFFFFF", - externalControl: null, - ajaxOptions: {} + externalControl: null, + submitOnBlur: false, + ajaxOptions: {}, + evalScripts: false }, options || {}); if(!this.options.formId && this.element.id) { @@ -536,16 +551,22 @@ Ajax.InPlaceEditor.prototype = { this.form.appendChild(br); } - okButton = document.createElement("input"); - okButton.type = "submit"; - okButton.value = this.options.okText; - this.form.appendChild(okButton); + if (this.options.okButton) { + okButton = document.createElement("input"); + okButton.type = "submit"; + okButton.value = this.options.okText; + okButton.className = 'editor_ok_button'; + this.form.appendChild(okButton); + } - cancelLink = document.createElement("a"); - cancelLink.href = "#"; - cancelLink.appendChild(document.createTextNode(this.options.cancelText)); - cancelLink.onclick = this.onclickCancel.bind(this); - this.form.appendChild(cancelLink); + if (this.options.cancelLink) { + cancelLink = document.createElement("a"); + cancelLink.href = "#"; + cancelLink.appendChild(document.createTextNode(this.options.cancelText)); + cancelLink.onclick = this.onclickCancel.bind(this); + cancelLink.className = 'editor_cancel'; + this.form.appendChild(cancelLink); + } }, hasHTMLLineBreaks: function(string) { if (!this.options.handleLineBreaks) return false; @@ -561,24 +582,34 @@ Ajax.InPlaceEditor.prototype = { } else { text = this.getText(); } + + var obj = this; if (this.options.rows == 1 && !this.hasHTMLLineBreaks(text)) { this.options.textarea = false; var textField = document.createElement("input"); + textField.obj = this; textField.type = "text"; textField.name = "value"; textField.value = text; textField.style.backgroundColor = this.options.highlightcolor; + textField.className = 'editor_field'; var size = this.options.size || this.options.cols || 0; if (size != 0) textField.size = size; + if (this.options.submitOnBlur) + textField.onblur = this.onSubmit.bind(this); this.editField = textField; } else { this.options.textarea = true; var textArea = document.createElement("textarea"); + textArea.obj = this; textArea.name = "value"; textArea.value = this.convertHTMLLineBreaks(text); textArea.rows = this.options.rows; textArea.cols = this.options.cols || 40; + textArea.className = 'editor_field'; + if (this.options.submitOnBlur) + textArea.onblur = this.onSubmit.bind(this); this.editField = textArea; } @@ -629,19 +660,26 @@ Ajax.InPlaceEditor.prototype = { // to be displayed indefinitely this.onLoading(); - new Ajax.Updater( - { - success: this.element, - // don't update on failure (this could be an option) - failure: null - }, - this.url, - Object.extend({ - parameters: this.options.callback(form, value), - onComplete: this.onComplete.bind(this), - onFailure: this.onFailure.bind(this) - }, this.options.ajaxOptions) - ); + if (this.options.evalScripts) { + new Ajax.Request( + this.url, Object.extend({ + parameters: this.options.callback(form, value), + onComplete: this.onComplete.bind(this), + onFailure: this.onFailure.bind(this), + asynchronous:true, + evalScripts:true + }, this.options.ajaxOptions)); + } else { + new Ajax.Updater( + { success: this.element, + // don't update on failure (this could be an option) + failure: null }, + this.url, Object.extend({ + parameters: this.options.callback(form, value), + onComplete: this.onComplete.bind(this), + onFailure: this.onFailure.bind(this) + }, this.options.ajaxOptions)); + } // stop the event to avoid a page refresh in Safari if (arguments.length > 1) { Event.stop(arguments[0]); @@ -723,6 +761,33 @@ Ajax.InPlaceEditor.prototype = { } }; +Ajax.InPlaceCollectionEditor = Class.create(); +Object.extend(Ajax.InPlaceCollectionEditor.prototype, Ajax.InPlaceEditor.prototype); +Object.extend(Ajax.InPlaceCollectionEditor.prototype, { + createEditField: function() { + if (!this.cached_selectTag) { + var selectTag = document.createElement("select"); + var collection = this.options.collection || []; + var optionTag; + collection.each(function(e,i) { + optionTag = document.createElement("option"); + optionTag.value = (e instanceof Array) ? e[0] : e; + if(this.options.value==optionTag.value) optionTag.selected = true; + optionTag.appendChild(document.createTextNode((e instanceof Array) ? e[1] : e)); + selectTag.appendChild(optionTag); + }.bind(this)); + this.cached_selectTag = selectTag; + } + + this.editField = this.cached_selectTag; + if(this.options.loadTextURL) this.loadExternalText(); + this.form.appendChild(this.editField); + this.options.callback = function(form, value) { + return "value=" + encodeURIComponent(value); + } + } +}); + // Delayed observer, like Form.Element.Observer, // but waits for delay after last key input // Ideal for live-search fields @@ -747,4 +812,4 @@ Form.Element.DelayedObserver.prototype = { this.timer = null; this.callback(this.element, $F(this.element)); } -}; \ No newline at end of file +}; diff --git a/tracks/public/javascripts/dragdrop.js b/tracks/public/javascripts/dragdrop.js index 92d1f731..f1dc7ea2 100644 --- a/tracks/public/javascripts/dragdrop.js +++ b/tracks/public/javascripts/dragdrop.js @@ -128,7 +128,7 @@ var Draggables = { this.activeDraggable = draggable; }, - deactivate: function(draggbale) { + deactivate: function() { this.activeDraggable = null; }, @@ -146,6 +146,7 @@ var Draggables = { if(!this.activeDraggable) return; this._lastPointer = null; this.activeDraggable.endDrag(event); + this.activeDraggable = null; }, keyPress: function(event) { @@ -191,22 +192,28 @@ Draggable.prototype = { }, reverteffect: function(element, top_offset, left_offset) { var dur = Math.sqrt(Math.abs(top_offset^2)+Math.abs(left_offset^2))*0.02; - element._revert = new Effect.MoveBy(element, -top_offset, -left_offset, {duration:dur}); + element._revert = new Effect.Move(element, { x: -left_offset, y: -top_offset, duration: dur}); }, endeffect: function(element) { new Effect.Opacity(element, {duration:0.2, from:0.7, to:1.0}); }, zindex: 1000, revert: false, + scroll: false, + scrollSensitivity: 20, + scrollSpeed: 15, snap: false // false, or xy or [x,y] or function(x,y){ return [x,y] } }, arguments[1] || {}); this.element = $(element); if(options.handle && (typeof options.handle == 'string')) - this.handle = Element.childrenWithClassName(this.element, options.handle)[0]; + this.handle = Element.childrenWithClassName(this.element, options.handle, true)[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); Element.makePositioned(this.element); // fix IE @@ -227,8 +234,8 @@ Draggable.prototype = { currentDelta: function() { return([ - parseInt(this.element.style.left || '0'), - parseInt(this.element.style.top || '0')]); + parseInt(Element.getStyle(this.element,'left') || '0'), + parseInt(Element.getStyle(this.element,'top') || '0')]); }, initDrag: function(event) { @@ -238,6 +245,7 @@ Draggable.prototype = { if(src.tagName && ( src.tagName=='INPUT' || src.tagName=='SELECT' || + src.tagName=='OPTION' || src.tagName=='BUTTON' || src.tagName=='TEXTAREA')) return; @@ -269,6 +277,17 @@ Draggable.prototype = { 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); }, @@ -281,8 +300,30 @@ Draggable.prototype = { 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; + p[1] += this.options.scroll.scrollTop; + 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(navigator.appVersion.indexOf('AppleWebKit')>0) window.scrollBy(0,0); + Event.stop(event); }, @@ -320,13 +361,14 @@ Draggable.prototype = { }, keyPress: function(event) { - if(!event.keyCode==Event.KEY_ESC) return; + 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); }, @@ -336,7 +378,14 @@ Draggable.prototype = { var d = this.currentDelta(); pos[0] -= d[0]; pos[1] -= d[1]; - var p = [0,1].map(function(i){ return (point[i]-pos[i]-this.offset[i]) }.bind(this)); + if(this.options.scroll && (this.options.scroll != window)) { + 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(typeof this.options.snap == 'function') { @@ -357,6 +406,67 @@ Draggable.prototype = { 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; + } + }, + + startScrolling: function(speed) { + 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); + this.draw(Draggables._lastPointer); + + 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 }; } } @@ -413,7 +523,10 @@ var Sortable = { only: false, hoverclass: null, ghosting: false, - format: null, + scroll: false, + scrollSensitivity: 20, + scrollSpeed: 15, + format: /^[^_]*_(.*)$/, onChange: Prototype.emptyFunction, onUpdate: Prototype.emptyFunction }, arguments[1] || {}); @@ -424,6 +537,9 @@ var Sortable = { // build options for the draggables var options_for_draggable = { revert: true, + scroll: options.scroll, + scrollSpeed: options.scrollSpeed, + scrollSensitivity: options.scrollSensitivity, ghosting: options.ghosting, constraint: options.constraint, handle: options.handle }; @@ -491,9 +607,10 @@ var Sortable = { findElements: function(element, options) { if(!element.hasChildNodes()) return null; var elements = []; + var only = options.only ? [options.only].flatten() : null; $A(element.childNodes).each( function(e) { if(e.tagName && e.tagName.toUpperCase()==options.tag.toUpperCase() && - (!options.only || (Element.hasClassName(e, options.only)))) + (!only || (Element.classNames(e).detect(function(v) { return only.include(v) })))) elements.push(e); if(options.tree) { var grandchildren = this.findElements(e, options); @@ -567,18 +684,41 @@ var Sortable = { Element.show(Sortable._marker); }, + 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 sortableOptions = this.options(element); - var options = Object.extend({ - tag: sortableOptions.tag, - only: sortableOptions.only, - name: element.id, - format: sortableOptions.format || /^[^_]*_(.*)$/ - }, arguments[1] || {}); - return $(this.findElements(element, options) || []).map( function(item) { - return (encodeURIComponent(options.name) + "[]=" + - encodeURIComponent(item.id.match(options.format) ? item.id.match(options.format)[1] : '')); - }).join("&"); + var name = encodeURIComponent( + (arguments[1] && arguments[1].name) ? arguments[1].name : element.id); + return Sortable.sequence(element, arguments[1]).map( function(item) { + return name + "[]=" + encodeURIComponent(item); + }).join('&'); } -} \ No newline at end of file +} diff --git a/tracks/public/javascripts/effects.js b/tracks/public/javascripts/effects.js index 414398ce..bcf836b8 100644 --- a/tracks/public/javascripts/effects.js +++ b/tracks/public/javascripts/effects.js @@ -6,8 +6,6 @@ // // See scriptaculous.js for full license. -/* ------------- element ext -------------- */ - // converts rgb() and #xxx to #xxxxxx format, // returns self (or first argument) if not convertable String.prototype.parseColor = function() { @@ -22,33 +20,29 @@ String.prototype.parseColor = function() { } } return(color.length==7 ? color : (arguments[0] || this)); -} - -Element.collectTextNodesIgnoreClass = function(element, ignoreclass) { - var children = $(element).childNodes; - var text = ''; - var classtest = new RegExp('^([^ ]+ )*' + ignoreclass+ '( [^ ]+)*$','i'); - - for (var i = 0; i < children.length; i++) { - if(children[i].nodeType==3) { - text+=children[i].nodeValue; - } else { - if((!children[i].className.match(classtest)) && children[i].hasChildNodes()) - text += Element.collectTextNodesIgnoreClass(children[i], ignoreclass); - } - } - - return text; } -Element.setStyle = function(element, style) { - element = $(element); - for(k in style) element.style[k.camelize()] = style[k]; +/*--------------------------------------------------------------------------*/ + +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.setContentZoom = function(element, percent) { +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(element, {fontSize: (percent/100) + 'em'}); - if(navigator.appVersion.indexOf('AppleWebKit')>0) window.scrollBy(0,0); + if(navigator.appVersion.indexOf('AppleWebKit')>0) window.scrollBy(0,0); } Element.getOpacity = function(element){ @@ -75,18 +69,35 @@ Element.setOpacity = function(element, value){ Element.setStyle(element, { filter: Element.getStyle(element,'filter').replace(/alpha\([^\)]*\)/gi,'') + 'alpha(opacity='+value*100+')' }); - } + } } Element.getInlineOpacity = function(element){ return $(element).style.opacity || ''; } -Element.childrenWithClassName = function(element, className) { - return $A($(element).getElementsByTagName('*')).select( - function(c) { return Element.hasClassName(c, className) }); +Element.childrenWithClassName = function(element, className, findFirst) { + return [$A($(element).getElementsByTagName('*'))[findFirst ? 'detect' : 'select']( function(c) { + return c.className ? Element.hasClassName(c, className) : false; + })].flatten(); } +Element.forceRerendering = function(element) { + try { + element = $(element); + var n = document.createTextNode(' '); + element.appendChild(n); + element.removeChild(n); + } catch(e) { } +}; + +['setOpacity','getOpacity','getInlineOpacity','forceRerendering','setContentZoom', + 'collectTextNodes','collectTextNodesIgnoreClass','childrenWithClassName'].each( + function(f) { Element.Methods[f] = Element[f]; } +); + +/*--------------------------------------------------------------------------*/ + Array.prototype.call = function() { var args = arguments; this.each(function(f){ f.apply(this, args) }); @@ -129,6 +140,20 @@ var Effect = { $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); } }; @@ -166,16 +191,22 @@ Effect.Transitions.full = function(pos) { /* ------------- core effects ------------- */ -Effect.Queue = { - effects: [], +Effect.ScopedQueue = Class.create(); +Object.extend(Object.extend(Effect.ScopedQueue.prototype, Enumerable), { + initialize: function() { + this.effects = []; + this.interval = null; + }, _each: function(iterator) { this.effects._each(iterator); }, - interval: null, add: function(effect) { var timestamp = new Date().getTime(); - switch(effect.options.queue) { + var position = (typeof effect.options.queue == 'string') ? + 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) { @@ -191,7 +222,10 @@ Effect.Queue = { effect.startOn += timestamp; effect.finishOn += timestamp; - this.effects.push(effect); + + 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), 40); }, @@ -206,32 +240,45 @@ Effect.Queue = { var timePos = new Date().getTime(); this.effects.invoke('loop', timePos); } +}); + +Effect.Queues = { + instances: $H(), + get: function(queueName) { + if(typeof queueName != 'string') return queueName; + + if(!this.instances[queueName]) + this.instances[queueName] = new Effect.ScopedQueue(); + + return this.instances[queueName]; + } +} +Effect.Queue = Effect.Queues.get('global'); + +Effect.DefaultOptions = { + transition: Effect.Transitions.sinoidal, + duration: 1.0, // seconds + fps: 25.0, // max. 25fps due to Effect.Queue implementation + sync: false, // true for combining + from: 0.0, + to: 1.0, + delay: 0.0, + queue: 'parallel' } -Object.extend(Effect.Queue, Enumerable); Effect.Base = function() {}; Effect.Base.prototype = { position: null, - setOptions: function(options) { - this.options = Object.extend({ - transition: Effect.Transitions.sinoidal, - duration: 1.0, // seconds - fps: 25.0, // max. 25fps due to Effect.Queue implementation - sync: false, // true for combining - from: 0.0, - to: 1.0, - delay: 0.0, - queue: 'parallel' - }, options || {}); - }, start: function(options) { - this.setOptions(options || {}); + this.options = Object.extend(Object.extend({},Effect.DefaultOptions), options || {}); this.currentFrame = 0; this.state = 'idle'; this.startOn = this.options.delay*1000; this.finishOn = this.startOn + (this.options.duration*1000); this.event('beforeStart'); - if(!this.options.sync) Effect.Queue.add(this); + if(!this.options.sync) + Effect.Queues.get(typeof this.options.queue == 'string' ? + 'global' : this.options.queue.scope).add(this); }, loop: function(timePos) { if(timePos >= this.startOn) { @@ -269,7 +316,9 @@ Effect.Base.prototype = { } }, cancel: function() { - if(!this.options.sync) Effect.Queue.remove(this); + if(!this.options.sync) + Effect.Queues.get(typeof this.options.queue == 'string' ? + 'global' : this.options.queue.scope).remove(this); this.state = 'finished'; }, event: function(eventName) { @@ -307,43 +356,57 @@ Object.extend(Object.extend(Effect.Opacity.prototype, Effect.Base.prototype), { this.element = $(element); // make this work on IE on elements without 'layout' if(/MSIE/.test(navigator.userAgent) && (!this.element.hasLayout)) - Element.setStyle(this.element, {zoom: 1}); + this.element.setStyle({zoom: 1}); var options = Object.extend({ - from: Element.getOpacity(this.element) || 0.0, + from: this.element.getOpacity() || 0.0, to: 1.0 }, arguments[1] || {}); this.start(options); }, update: function(position) { - Element.setOpacity(this.element, position); + this.element.setOpacity(position); } }); -Effect.MoveBy = Class.create(); -Object.extend(Object.extend(Effect.MoveBy.prototype, Effect.Base.prototype), { - initialize: function(element, toTop, toLeft) { - this.element = $(element); - this.toTop = toTop; - this.toLeft = toLeft; - this.start(arguments[3]); +Effect.Move = Class.create(); +Object.extend(Object.extend(Effect.Move.prototype, Effect.Base.prototype), { + initialize: function(element) { + this.element = $(element); + var options = Object.extend({ + x: 0, + y: 0, + mode: 'relative' + }, arguments[1] || {}); + this.start(options); }, setup: function() { // Bug in Opera: Opera returns the "real" position of a static element or // relative element that does not have top/left explicitly set. // ==> Always set top and left for position relative elements in your stylesheets // (to 0 if you do not need them) - Element.makePositioned(this.element); - this.originalTop = parseFloat(Element.getStyle(this.element,'top') || '0'); - this.originalLeft = parseFloat(Element.getStyle(this.element,'left') || '0'); + this.element.makePositioned(); + this.originalLeft = parseFloat(this.element.getStyle('left') || '0'); + this.originalTop = parseFloat(this.element.getStyle('top') || '0'); + if(this.options.mode == 'absolute') { + // absolute movement, so we need to calc deltaX and deltaY + this.options.x = this.options.x - this.originalLeft; + this.options.y = this.options.y - this.originalTop; + } }, update: function(position) { - Element.setStyle(this.element, { - top: this.toTop * position + this.originalTop + 'px', - left: this.toLeft * position + this.originalLeft + 'px' + this.element.setStyle({ + left: this.options.x * position + this.originalLeft + 'px', + top: this.options.y * position + this.originalTop + '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(); Object.extend(Object.extend(Effect.Scale.prototype, Effect.Base.prototype), { initialize: function(element, percent) { @@ -361,7 +424,7 @@ Object.extend(Object.extend(Effect.Scale.prototype, Effect.Base.prototype), { }, setup: function() { this.restoreAfterFinish = this.options.restoreAfterFinish || false; - this.elementPositioning = Element.getStyle(this.element,'position'); + this.elementPositioning = this.element.getStyle('position'); this.originalStyle = {}; ['top','left','width','height','fontSize'].each( function(k) { @@ -371,7 +434,7 @@ Object.extend(Object.extend(Effect.Scale.prototype, Effect.Base.prototype), { this.originalTop = this.element.offsetTop; this.originalLeft = this.element.offsetLeft; - var fontSize = Element.getStyle(this.element,'font-size') || '100%'; + var fontSize = this.element.getStyle('font-size') || '100%'; ['em','px','%'].each( function(fontSizeType) { if(fontSize.indexOf(fontSizeType)>0) { this.fontSize = parseFloat(fontSize); @@ -393,11 +456,11 @@ Object.extend(Object.extend(Effect.Scale.prototype, Effect.Base.prototype), { update: function(position) { var currentScale = (this.options.scaleFrom/100.0) + (this.factor * position); if(this.options.scaleContent && this.fontSize) - Element.setStyle(this.element, {fontSize: this.fontSize * currentScale + this.fontSizeType }); + 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) Element.setStyle(this.element, this.originalStyle); + if (this.restoreAfterFinish) this.element.setStyle(this.originalStyle); }, setDimensions: function(height, width) { var d = {}; @@ -414,7 +477,7 @@ Object.extend(Object.extend(Effect.Scale.prototype, Effect.Base.prototype), { if(this.options.scaleX) d.left = -leftd + 'px'; } } - Element.setStyle(this.element, d); + this.element.setStyle(d); } }); @@ -427,25 +490,25 @@ Object.extend(Object.extend(Effect.Highlight.prototype, Effect.Base.prototype), }, setup: function() { // Prevent executing on elements not in the layout flow - if(Element.getStyle(this.element, 'display')=='none') { this.cancel(); return; } + if(this.element.getStyle('display')=='none') { this.cancel(); return; } // Disable background image during the effect this.oldStyle = { - backgroundImage: Element.getStyle(this.element, 'background-image') }; - Element.setStyle(this.element, {backgroundImage: 'none'}); + backgroundImage: this.element.getStyle('background-image') }; + this.element.setStyle({backgroundImage: 'none'}); if(!this.options.endcolor) - this.options.endcolor = Element.getStyle(this.element, 'background-color').parseColor('#ffffff'); + this.options.endcolor = this.element.getStyle('background-color').parseColor('#ffffff'); if(!this.options.restorecolor) - this.options.restorecolor = Element.getStyle(this.element, 'background-color'); + 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) { - Element.setStyle(this.element,{backgroundColor: $R(0,2).inject('#',function(m,v,i){ + this.element.setStyle({backgroundColor: $R(0,2).inject('#',function(m,v,i){ return m+(Math.round(this._base[i]+(this._delta[i]*position)).toColorPart()); }.bind(this)) }); }, finish: function() { - Element.setStyle(this.element, Object.extend(this.oldStyle, { + this.element.setStyle(Object.extend(this.oldStyle, { backgroundColor: this.options.restorecolor })); } @@ -479,85 +542,91 @@ Object.extend(Object.extend(Effect.ScrollTo.prototype, Effect.Base.prototype), { /* ------------- combination effects ------------- */ Effect.Fade = function(element) { - var oldOpacity = Element.getInlineOpacity(element); + element = $(element); + var oldOpacity = element.getInlineOpacity(); var options = Object.extend({ - from: Element.getOpacity(element) || 1.0, + from: element.getOpacity() || 1.0, to: 0.0, - afterFinishInternal: function(effect) { with(Element) { + afterFinishInternal: function(effect) { if(effect.options.to!=0) return; - hide(effect.element); - setStyle(effect.element, {opacity: oldOpacity}); }} - }, arguments[1] || {}); + effect.element.hide(); + effect.element.setStyle({opacity: oldOpacity}); + }}, arguments[1] || {}); return new Effect.Opacity(element,options); } Effect.Appear = function(element) { + element = $(element); var options = Object.extend({ - from: (Element.getStyle(element, 'display') == 'none' ? 0.0 : Element.getOpacity(element) || 0.0), + from: (element.getStyle('display') == 'none' ? 0.0 : element.getOpacity() || 0.0), to: 1.0, - beforeSetup: function(effect) { with(Element) { - setOpacity(effect.element, effect.options.from); - show(effect.element); }} - }, arguments[1] || {}); + // force Safari to render floated elements properly + afterFinishInternal: function(effect) { + effect.element.forceRerendering(); + }, + beforeSetup: function(effect) { + effect.element.setOpacity(effect.options.from); + effect.element.show(); + }}, arguments[1] || {}); return new Effect.Opacity(element,options); } Effect.Puff = function(element) { element = $(element); - var oldStyle = { opacity: Element.getInlineOpacity(element), position: Element.getStyle(element, 'position') }; + var oldStyle = { opacity: element.getInlineOpacity(), position: element.getStyle('position') }; 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) { with(Element) { - setStyle(effect.effects[0].element, {position: 'absolute'}); }}, - afterFinishInternal: function(effect) { with(Element) { - hide(effect.effects[0].element); - setStyle(effect.effects[0].element, oldStyle); }} + beforeSetupInternal: function(effect) { + effect.effects[0].element.setStyle({position: 'absolute'}); }, + afterFinishInternal: function(effect) { + effect.effects[0].element.hide(); + effect.effects[0].element.setStyle(oldStyle); } }, arguments[1] || {}) ); } Effect.BlindUp = function(element) { element = $(element); - Element.makeClipping(element); + element.makeClipping(); return new Effect.Scale(element, 0, Object.extend({ scaleContent: false, scaleX: false, restoreAfterFinish: true, - afterFinishInternal: function(effect) { with(Element) { - [hide, undoClipping].call(effect.element); }} + afterFinishInternal: function(effect) { + effect.element.hide(); + effect.element.undoClipping(); + } }, arguments[1] || {}) ); } Effect.BlindDown = function(element) { element = $(element); - var oldHeight = Element.getStyle(element, 'height'); - var elementDimensions = Element.getDimensions(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) { with(Element) { - makeClipping(effect.element); - setStyle(effect.element, {height: '0px'}); - show(effect.element); - }}, - afterFinishInternal: function(effect) { with(Element) { - undoClipping(effect.element); - setStyle(effect.element, {height: oldHeight}); - }} + afterSetup: function(effect) { + effect.element.makeClipping(); + effect.element.setStyle({height: '0px'}); + effect.element.show(); + }, + afterFinishInternal: function(effect) { + effect.element.undoClipping(); + } }, arguments[1] || {}) ); } Effect.SwitchOff = function(element) { element = $(element); - var oldOpacity = Element.getInlineOpacity(element); + var oldOpacity = element.getInlineOpacity(); return new Effect.Appear(element, { duration: 0.4, from: 0, @@ -566,13 +635,16 @@ Effect.SwitchOff = function(element) { new Effect.Scale(effect.element, 1, { duration: 0.3, scaleFromCenter: true, scaleX: false, scaleContent: false, restoreAfterFinish: true, - beforeSetup: function(effect) { with(Element) { - [makePositioned,makeClipping].call(effect.element); - }}, - afterFinishInternal: function(effect) { with(Element) { - [hide,undoClipping,undoPositioned].call(effect.element); - setStyle(effect.element, {opacity: oldOpacity}); - }} + beforeSetup: function(effect) { + effect.element.makePositioned(); + effect.element.makeClipping(); + }, + afterFinishInternal: function(effect) { + effect.element.hide(); + effect.element.undoClipping(); + effect.element.undoPositioned(); + effect.element.setStyle({opacity: oldOpacity}); + } }) } }); @@ -581,99 +653,110 @@ Effect.SwitchOff = function(element) { Effect.DropOut = function(element) { element = $(element); var oldStyle = { - top: Element.getStyle(element, 'top'), - left: Element.getStyle(element, 'left'), - opacity: Element.getInlineOpacity(element) }; + top: element.getStyle('top'), + left: element.getStyle('left'), + opacity: element.getInlineOpacity() }; return new Effect.Parallel( - [ new Effect.MoveBy(element, 100, 0, { sync: true }), + [ 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) { with(Element) { - makePositioned(effect.effects[0].element); }}, - afterFinishInternal: function(effect) { with(Element) { - [hide, undoPositioned].call(effect.effects[0].element); - setStyle(effect.effects[0].element, oldStyle); }} + beforeSetup: function(effect) { + effect.effects[0].element.makePositioned(); + }, + afterFinishInternal: function(effect) { + effect.effects[0].element.hide(); + effect.effects[0].element.undoPositioned(); + effect.effects[0].element.setStyle(oldStyle); + } }, arguments[1] || {})); } Effect.Shake = function(element) { element = $(element); var oldStyle = { - top: Element.getStyle(element, 'top'), - left: Element.getStyle(element, 'left') }; - return new Effect.MoveBy(element, 0, 20, - { duration: 0.05, afterFinishInternal: function(effect) { - new Effect.MoveBy(effect.element, 0, -40, - { duration: 0.1, afterFinishInternal: function(effect) { - new Effect.MoveBy(effect.element, 0, 40, - { duration: 0.1, afterFinishInternal: function(effect) { - new Effect.MoveBy(effect.element, 0, -40, - { duration: 0.1, afterFinishInternal: function(effect) { - new Effect.MoveBy(effect.element, 0, 40, - { duration: 0.1, afterFinishInternal: function(effect) { - new Effect.MoveBy(effect.element, 0, -20, - { duration: 0.05, afterFinishInternal: function(effect) { with(Element) { - undoPositioned(effect.element); - setStyle(effect.element, 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(); + effect.element.setStyle(oldStyle); + }}) }}) }}) }}) }}) }}); } Effect.SlideDown = function(element) { element = $(element); - Element.cleanWhitespace(element); + element.cleanWhitespace(); // SlideDown need to have the content of the element wrapped in a container element with fixed height! - var oldInnerBottom = Element.getStyle(element.firstChild, 'bottom'); - var elementDimensions = Element.getDimensions(element); + var oldInnerBottom = $(element.firstChild).getStyle('bottom'); + 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) { with(Element) { - makePositioned(effect.element); - makePositioned(effect.element.firstChild); - if(window.opera) setStyle(effect.element, {top: ''}); - makeClipping(effect.element); - setStyle(effect.element, {height: '0px'}); - show(element); }}, - afterUpdateInternal: function(effect) { with(Element) { - setStyle(effect.element.firstChild, {bottom: - (effect.dims[0] - effect.element.clientHeight) + 'px' }); }}, - afterFinishInternal: function(effect) { with(Element) { - undoClipping(effect.element); - undoPositioned(effect.element.firstChild); - undoPositioned(effect.element); - setStyle(effect.element.firstChild, {bottom: oldInnerBottom}); }} + afterSetup: function(effect) { + effect.element.makePositioned(); + effect.element.firstChild.makePositioned(); + if(window.opera) effect.element.setStyle({top: ''}); + effect.element.makeClipping(); + effect.element.setStyle({height: '0px'}); + effect.element.show(); }, + afterUpdateInternal: function(effect) { + effect.element.firstChild.setStyle({bottom: + (effect.dims[0] - effect.element.clientHeight) + 'px' }); + }, + afterFinishInternal: function(effect) { + effect.element.undoClipping(); + // IE will crash if child is undoPositioned first + if(/MSIE/.test(navigator.userAgent)){ + effect.element.undoPositioned(); + effect.element.firstChild.undoPositioned(); + }else{ + effect.element.firstChild.undoPositioned(); + effect.element.undoPositioned(); + } + effect.element.firstChild.setStyle({bottom: oldInnerBottom}); } }, arguments[1] || {}) ); } Effect.SlideUp = function(element) { element = $(element); - Element.cleanWhitespace(element); - var oldInnerBottom = Element.getStyle(element.firstChild, 'bottom'); + element.cleanWhitespace(); + var oldInnerBottom = $(element.firstChild).getStyle('bottom'); return new Effect.Scale(element, 0, Object.extend({ scaleContent: false, scaleX: false, scaleMode: 'box', scaleFrom: 100, restoreAfterFinish: true, - beforeStartInternal: function(effect) { with(Element) { - makePositioned(effect.element); - makePositioned(effect.element.firstChild); - if(window.opera) setStyle(effect.element, {top: ''}); - makeClipping(effect.element); - show(element); }}, - afterUpdateInternal: function(effect) { with(Element) { - setStyle(effect.element.firstChild, {bottom: - (effect.dims[0] - effect.element.clientHeight) + 'px' }); }}, - afterFinishInternal: function(effect) { with(Element) { - [hide, undoClipping].call(effect.element); - undoPositioned(effect.element.firstChild); - undoPositioned(effect.element); - setStyle(effect.element.firstChild, {bottom: oldInnerBottom}); }} + beforeStartInternal: function(effect) { + effect.element.makePositioned(); + effect.element.firstChild.makePositioned(); + if(window.opera) effect.element.setStyle({top: ''}); + effect.element.makeClipping(); + effect.element.show(); }, + afterUpdateInternal: function(effect) { + effect.element.firstChild.setStyle({bottom: + (effect.dims[0] - effect.element.clientHeight) + 'px' }); }, + afterFinishInternal: function(effect) { + effect.element.hide(); + effect.element.undoClipping(); + effect.element.firstChild.undoPositioned(); + effect.element.undoPositioned(); + effect.element.setStyle({bottom: oldInnerBottom}); } }, arguments[1] || {}) ); } @@ -682,11 +765,11 @@ Effect.SlideUp = function(element) { Effect.Squish = function(element) { return new Effect.Scale(element, window.opera ? 1 : 0, { restoreAfterFinish: true, - beforeSetup: function(effect) { with(Element) { - makeClipping(effect.element); }}, - afterFinishInternal: function(effect) { with(Element) { - hide(effect.element); - undoClipping(effect.element); }} + beforeSetup: function(effect) { + effect.element.makeClipping(effect.element); }, + afterFinishInternal: function(effect) { + effect.element.hide(effect.element); + effect.element.undoClipping(effect.element); } }); } @@ -694,7 +777,7 @@ Effect.Grow = function(element) { element = $(element); var options = Object.extend({ direction: 'center', - moveTransistion: Effect.Transitions.sinoidal, + moveTransition: Effect.Transitions.sinoidal, scaleTransition: Effect.Transitions.sinoidal, opacityTransition: Effect.Transitions.full }, arguments[1] || {}); @@ -703,9 +786,9 @@ Effect.Grow = function(element) { left: element.style.left, height: element.style.height, width: element.style.width, - opacity: Element.getInlineOpacity(element) }; + opacity: element.getInlineOpacity() }; - var dims = Element.getDimensions(element); + var dims = element.getDimensions(); var initialMoveX, initialMoveY; var moveX, moveY; @@ -737,27 +820,32 @@ Effect.Grow = function(element) { break; } - return new Effect.MoveBy(element, initialMoveY, initialMoveX, { + return new Effect.Move(element, { + x: initialMoveX, + y: initialMoveY, duration: 0.01, - beforeSetup: function(effect) { with(Element) { - hide(effect.element); - makeClipping(effect.element); - makePositioned(effect.element); - }}, + beforeSetup: function(effect) { + effect.element.hide(); + effect.element.makeClipping(); + effect.element.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.MoveBy(effect.element, moveY, moveX, { sync: true, transition: options.moveTransition }), + 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) { with(Element) { - setStyle(effect.effects[0].element, {height: '0px'}); - show(effect.effects[0].element); }}, - afterFinishInternal: function(effect) { with(Element) { - [undoClipping, undoPositioned].call(effect.effects[0].element); - setStyle(effect.effects[0].element, oldStyle); }} + beforeSetup: function(effect) { + effect.effects[0].element.setStyle({height: '0px'}); + effect.effects[0].element.show(); + }, + afterFinishInternal: function(effect) { + effect.effects[0].element.undoClipping(); + effect.effects[0].element.undoPositioned(); + effect.effects[0].element.setStyle(oldStyle); + } }, options) ) } @@ -768,7 +856,7 @@ Effect.Shrink = function(element) { element = $(element); var options = Object.extend({ direction: 'center', - moveTransistion: Effect.Transitions.sinoidal, + moveTransition: Effect.Transitions.sinoidal, scaleTransition: Effect.Transitions.sinoidal, opacityTransition: Effect.Transitions.none }, arguments[1] || {}); @@ -777,9 +865,9 @@ Effect.Shrink = function(element) { left: element.style.left, height: element.style.height, width: element.style.width, - opacity: Element.getInlineOpacity(element) }; + opacity: element.getInlineOpacity() }; - var dims = Element.getDimensions(element); + var dims = element.getDimensions(); var moveX, moveY; switch (options.direction) { @@ -807,13 +895,16 @@ Effect.Shrink = function(element) { 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.MoveBy(element, moveY, moveX, { sync: true, transition: options.moveTransition }) + new Effect.Move(element, { x: moveX, y: moveY, sync: true, transition: options.moveTransition }) ], Object.extend({ - beforeStartInternal: function(effect) { with(Element) { - [makePositioned, makeClipping].call(effect.effects[0].element) }}, - afterFinishInternal: function(effect) { with(Element) { - [hide, undoClipping, undoPositioned].call(effect.effects[0].element); - setStyle(effect.effects[0].element, oldStyle); }} + beforeStartInternal: function(effect) { + effect.effects[0].element.makePositioned(); + effect.effects[0].element.makeClipping(); }, + afterFinishInternal: function(effect) { + effect.effects[0].element.hide(); + effect.effects[0].element.undoClipping(); + effect.effects[0].element.undoPositioned(); + effect.effects[0].element.setStyle(oldStyle); } }, options) ); } @@ -821,13 +912,13 @@ Effect.Shrink = function(element) { Effect.Pulsate = function(element) { element = $(element); var options = arguments[1] || {}; - var oldOpacity = Element.getInlineOpacity(element); + var oldOpacity = element.getInlineOpacity(); var transition = options.transition || Effect.Transitions.sinoidal; var reverser = function(pos){ return transition(1-Effect.Transitions.pulse(pos)) }; reverser.bind(transition); return new Effect.Opacity(element, Object.extend(Object.extend({ duration: 3.0, from: 0, - afterFinishInternal: function(effect) { Element.setStyle(effect.element, {opacity: oldOpacity}); } + afterFinishInternal: function(effect) { effect.element.setStyle({opacity: oldOpacity}); } }, options), {transition: reverser})); } @@ -846,9 +937,17 @@ Effect.Fold = function(element) { new Effect.Scale(element, 1, { scaleContent: false, scaleY: false, - afterFinishInternal: function(effect) { with(Element) { - [hide, undoClipping].call(effect.element); - setStyle(effect.element, oldStyle); - }} }); + afterFinishInternal: function(effect) { + effect.element.hide(); + effect.element.undoClipping(); + effect.element.setStyle(oldStyle); + } }); }}, arguments[1] || {})); } + +Element.Methods.visualEffect = function(element, effect, options) { + s = effect.gsub(/_/, '-').camelize(); + effect_class = s.charAt(0).toUpperCase() + s.substring(1); + new Effect[effect_class](element, options); + return $(element); +}; \ No newline at end of file diff --git a/tracks/public/javascripts/prototype.js b/tracks/public/javascripts/prototype.js index e9ccd3c8..2d4ba34c 100644 --- a/tracks/public/javascripts/prototype.js +++ b/tracks/public/javascripts/prototype.js @@ -1,17 +1,13 @@ -/* Prototype JavaScript framework, version 1.4.0 +/* Prototype JavaScript framework, version 1.5.0_pre1 * (c) 2005 Sam Stephenson * - * THIS FILE IS AUTOMATICALLY GENERATED. When sending patches, please diff - * against the source tree, available from the Prototype darcs repository. - * * Prototype is freely distributable under the terms of an MIT-style license. - * * For details, see the Prototype web site: http://prototype.conio.net/ * /*--------------------------------------------------------------------------*/ var Prototype = { - Version: '1.4.0', + Version: '1.5.0_pre1', ScriptFragment: '(?:)((\n|\r|.)*?)(?:<\/script>)', emptyFunction: function() {}, @@ -120,26 +116,49 @@ PeriodicalExecuter.prototype = { } } } - -/*--------------------------------------------------------------------------*/ - -function $() { - var elements = new Array(); - - for (var i = 0; i < arguments.length; i++) { - var element = arguments[i]; - if (typeof element == 'string') - element = document.getElementById(element); - - if (arguments.length == 1) - return element; - - elements.push(element); - } - - return elements; -} 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 += (replacement(match) || '').toString(); + 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 this; + }, + + truncate: function(length, truncation) { + length = length || 30; + truncation = truncation === undefined ? '...' : truncation; + return this.length > length ? + this.slice(0, length - truncation.length) + truncation : this; + }, + + strip: function() { + return this.replace(/^\s+/, '').replace(/\s+$/, ''); + }, + stripTags: function() { return this.replace(/<\/?[^>]+>/gi, ''); }, @@ -203,12 +222,35 @@ Object.extend(String.prototype, { }, inspect: function() { - return "'" + this.replace('\\', '\\\\').replace("'", '\\\'') + "'"; + return "'" + this.replace(/\\/g, '\\\\').replace(/'/g, '\\\'') + "'"; } }); +String.prototype.gsub.prepareReplacement = function(replacement) { + if (typeof replacement == 'function') return replacement; + var template = new Template(replacement); + return function(match) { return template.evaluate(match) }; +} + String.prototype.parseQuery = String.prototype.toQueryParams; +var Template = Class.create(); +Template.Pattern = /(^|.|\r|\n)(#\{(.*?)\})/; +Template.prototype = { + initialize: function(template, pattern) { + this.template = template.toString(); + this.pattern = pattern || Template.Pattern; + }, + + evaluate: function(object) { + return this.template.gsub(this.pattern, function(match) { + var before = match[1]; + if (before == '\\') return match[2]; + return before + (object[match[3]] || '').toString(); + }); + } +} + var $break = new Object(); var $continue = new Object(); @@ -375,8 +417,7 @@ var Enumerable = { var collections = [this].concat(args).map($A); return this.map(function(value, index) { - iterator(value = collections.pluck(index)); - return value; + return iterator(collections.pluck(index)); }); }, @@ -662,7 +703,8 @@ Ajax.Request.prototype = Object.extend(new Ajax.Base(), { setRequestHeaders: function() { var requestHeaders = ['X-Requested-With', 'XMLHttpRequest', - 'X-Prototype-Version', Prototype.Version]; + 'X-Prototype-Version', Prototype.Version, + 'Accept', 'text/javascript, text/html, application/xml, text/xml, */*']; if (this.options.method == 'post') { requestHeaders.push('Content-type', @@ -831,22 +873,48 @@ Ajax.PeriodicalUpdater.prototype = Object.extend(new Ajax.Base(), { this.updater = new Ajax.Updater(this.container, this.url, this.options); } }); +function $() { + var results = [], element; + for (var i = 0; i < arguments.length; i++) { + element = arguments[i]; + if (typeof element == 'string') + element = document.getElementById(element); + results.push(Element.extend(element)); + } + return results.length < 2 ? results[0] : results; +} + document.getElementsByClassName = function(className, parentElement) { var children = ($(parentElement) || document.body).getElementsByTagName('*'); return $A(children).inject([], function(elements, child) { if (child.className.match(new RegExp("(^|\\s)" + className + "(\\s|$)"))) - elements.push(child); + elements.push(Element.extend(child)); return elements; }); } /*--------------------------------------------------------------------------*/ -if (!window.Element) { +if (!window.Element) var Element = new Object(); + +Element.extend = function(element) { + if (!element) return; + + if (!element._extended && element.tagName && element != window) { + var methods = Element.Methods; + for (property in methods) { + var value = methods[property]; + if (typeof value == 'function') + element[property] = value.bind(null, element); + } + } + + element._extended = true; + return element; } -Object.extend(Element, { +Element.Methods = { visible: function(element) { return $(element).style.display != 'none'; }, @@ -882,6 +950,19 @@ Object.extend(Element, { setTimeout(function() {html.evalScripts()}, 10); }, + replace: function(element, html) { + element = $(element); + if (element.outerHTML) { + element.outerHTML = html.stripScripts(); + } else { + var range = element.ownerDocument.createRange(); + range.selectNodeContents(element); + element.parentNode.replaceChild( + range.createContextualFragment(html.stripScripts()), element); + } + setTimeout(function() {html.evalScripts()}, 10); + }, + getHeight: function(element) { element = $(element); return element.offsetHeight; @@ -920,6 +1001,13 @@ Object.extend(Element, { return $(element).innerHTML.match(/^\s*$/); }, + childOf: function(element, ancestor) { + element = $(element), ancestor = $(ancestor); + while (element = element.parentNode) + if (element == ancestor) return true; + return false; + }, + scrollTo: function(element) { element = $(element); var x = element.x ? element.x : element.offsetLeft, @@ -1013,7 +1101,9 @@ Object.extend(Element, { element.style.overflow = element._overflow; element._overflow = undefined; } -}); +} + +Object.extend(Element, Element.Methods); var Toggle = new Object(); Toggle.display = Element.toggle; @@ -1148,6 +1238,116 @@ Element.ClassNames.prototype = { } Object.extend(Element.ClassNames.prototype, Enumerable); +var Selector = Class.create(); +Selector.prototype = { + initialize: function(expression) { + this.params = {classNames: []}; + this.expression = expression.toString().strip(); + this.parseExpression(); + this.compileMatcher(); + }, + + parseExpression: function() { + function abort(message) { throw 'Parse error in selector: ' + message; } + + if (this.expression == '') abort('empty expression'); + + var params = this.params, expr = this.expression, match, modifier, clause, rest; + while (match = expr.match(/^(.*)\[([a-z0-9_:-]+?)(?:([~\|!]?=)(?:"([^"]*)"|([^\]\s]*)))?\]$/i)) { + params.attributes = params.attributes || []; + params.attributes.push({name: match[2], operator: match[3], value: match[4] || match[5] || ''}); + expr = match[1]; + } + + if (expr == '*') return this.params.wildcard = true; + + while (match = expr.match(/^([^a-z0-9_-])?([a-z0-9_-]+)(.*)/i)) { + modifier = match[1], clause = match[2], rest = match[3]; + switch (modifier) { + case '#': params.id = clause; break; + case '.': params.classNames.push(clause); break; + case '': + case undefined: params.tagName = clause.toUpperCase(); break; + default: abort(expr.inspect()); + } + expr = rest; + } + + if (expr.length > 0) abort(expr.inspect()); + }, + + buildMatchExpression: function() { + var params = this.params, conditions = [], clause; + + if (params.wildcard) + conditions.push('true'); + if (clause = params.id) + conditions.push('element.id == ' + clause.inspect()); + if (clause = params.tagName) + conditions.push('element.tagName.toUpperCase() == ' + clause.inspect()); + if ((clause = params.classNames).length > 0) + for (var i = 0; i < clause.length; i++) + conditions.push('Element.hasClassName(element, ' + clause[i].inspect() + ')'); + if (clause = params.attributes) { + clause.each(function(attribute) { + var value = 'element.getAttribute(' + attribute.name.inspect() + ')'; + var splitValueBy = function(delimiter) { + return value + ' && ' + value + '.split(' + delimiter.inspect() + ')'; + } + + switch (attribute.operator) { + case '=': conditions.push(value + ' == ' + attribute.value.inspect()); break; + case '~=': conditions.push(splitValueBy(' ') + '.include(' + attribute.value.inspect() + ')'); break; + case '|=': conditions.push( + splitValueBy('-') + '.first().toUpperCase() == ' + attribute.value.toUpperCase().inspect() + ); break; + case '!=': conditions.push(value + ' != ' + attribute.value.inspect()); break; + case '': + case undefined: conditions.push(value + ' != null'); break; + default: throw 'Unknown operator ' + attribute.operator + ' in selector'; + } + }); + } + + return conditions.join(' && '); + }, + + compileMatcher: function() { + this.match = new Function('element', 'if (!element.tagName) return false; \ + return ' + this.buildMatchExpression()); + }, + + findElements: function(scope) { + var element; + + if (element = $(this.params.id)) + if (this.match(element)) + if (!scope || Element.childOf(element, scope)) + return [element]; + + scope = (scope || document).getElementsByTagName(this.params.tagName || '*'); + + var results = []; + for (var i = 0; i < scope.length; i++) + if (this.match(element = scope[i])) + results.push(Element.extend(element)); + + return results; + }, + + toString: function() { + return this.expression; + } +} + +function $$() { + return $A(arguments).map(function(expression) { + return expression.strip().split(/\s+/).inject([null], function(results, expr) { + var selector = new Selector(expr); + return results.map(selector.findElements.bind(selector)).flatten(); + }); + }).flatten(); +} var Field = { clear: function() { for (var i = 0; i < arguments.length; i++) diff --git a/tracks/vendor/plugins/javascript_generator_templates/CHANGELOG b/tracks/vendor/plugins/javascript_generator_templates/CHANGELOG deleted file mode 100644 index 843fccfe..00000000 --- a/tracks/vendor/plugins/javascript_generator_templates/CHANGELOG +++ /dev/null @@ -1,15 +0,0 @@ -December 25, 2005 -* Added changeset 3316: http://dev.rubyonrails.org/changeset/3316 -* Added tests for javascript_generator_templates up to changeset 3116 -* Added changeset 3319: http://dev.rubyonrails.org/changeset/3319 - * Adds support for alert, redirect_to, call, assign, << -* Added changeset 3329 and 3335 - * Adds support for toggle, delay - -December 15, 2005 -* Updated prototype.js to 1.4.0 -* Enabled the test test_render_file_with_locals -* Add CHANGELOG file -* Update README to reflect version 1.0 of Rails -* Added MIT-LICENSE - diff --git a/tracks/vendor/plugins/javascript_generator_templates/MIT-LICENSE b/tracks/vendor/plugins/javascript_generator_templates/MIT-LICENSE deleted file mode 100644 index 5919c288..00000000 --- a/tracks/vendor/plugins/javascript_generator_templates/MIT-LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -Copyright (c) 2004 David Heinemeier Hansson - -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. \ No newline at end of file diff --git a/tracks/vendor/plugins/javascript_generator_templates/README b/tracks/vendor/plugins/javascript_generator_templates/README deleted file mode 100644 index c4973e70..00000000 --- a/tracks/vendor/plugins/javascript_generator_templates/README +++ /dev/null @@ -1,15 +0,0 @@ -JavaScriptGeneratorTemplates -============================ - -This plugin allows the usage of the new RJS templates without having to run -edge rails. For more information about RJS templates please check out these -resources on the web: - -http://rails.techno-weenie.net/tip/2005/11/29/ajaxed_forms_with_rjs_templates -http://www.codyfauser.com/articles/2005/11/20/rails-rjs-templates -http://dev.rubyonrails.org/changeset/3078 - -The RJS templates need at least version 1.4.0_rc4 of the prototype library to -function correctly. Run rake update_prototype from this source directory to -update your project's version of prototype to 1.4.0. - diff --git a/tracks/vendor/plugins/javascript_generator_templates/Rakefile b/tracks/vendor/plugins/javascript_generator_templates/Rakefile deleted file mode 100644 index 30f44248..00000000 --- a/tracks/vendor/plugins/javascript_generator_templates/Rakefile +++ /dev/null @@ -1,27 +0,0 @@ -require 'rake' -require 'rake/testtask' -require 'rake/rdoctask' - -desc 'Default: run unit tests.' -task :default => :test - -desc 'Test the javascript_generator_templates plugin.' -Rake::TestTask.new(:test) do |t| - t.libs << 'lib' - t.pattern = 'test/**/*_test.rb' - t.verbose = true -end - -desc 'Generate documentation for the javascript_generator_templates plugin.' -Rake::RDocTask.new(:rdoc) do |rdoc| - rdoc.rdoc_dir = 'rdoc' - rdoc.title = 'JavaScriptGeneratorTemplates' - rdoc.options << '--line-numbers --inline-source' - rdoc.rdoc_files.include('README') - rdoc.rdoc_files.include('lib/**/*.rb') -end - -desc "Install prototype.js file to public/javascripts" -task :update_prototype do - FileUtils.cp(File.dirname(__FILE__) + "/javascripts/prototype.js", File.dirname(__FILE__) + '/../../../public/javascripts/') -end diff --git a/tracks/vendor/plugins/javascript_generator_templates/init.rb b/tracks/vendor/plugins/javascript_generator_templates/init.rb deleted file mode 100644 index 6272338b..00000000 --- a/tracks/vendor/plugins/javascript_generator_templates/init.rb +++ /dev/null @@ -1,3 +0,0 @@ -require 'add_rjs_to_action_view' -require 'add_rjs_to_action_controller' -require 'add_rjs_to_javascript_helper' diff --git a/tracks/vendor/plugins/javascript_generator_templates/javascripts/prototype.js b/tracks/vendor/plugins/javascript_generator_templates/javascripts/prototype.js deleted file mode 100644 index e9ccd3c8..00000000 --- a/tracks/vendor/plugins/javascript_generator_templates/javascripts/prototype.js +++ /dev/null @@ -1,1785 +0,0 @@ -/* Prototype JavaScript framework, version 1.4.0 - * (c) 2005 Sam Stephenson - * - * THIS FILE IS AUTOMATICALLY GENERATED. When sending patches, please diff - * against the source tree, available from the Prototype darcs repository. - * - * Prototype is freely distributable under the terms of an MIT-style license. - * - * For details, see the Prototype web site: http://prototype.conio.net/ - * -/*--------------------------------------------------------------------------*/ - -var Prototype = { - Version: '1.4.0', - ScriptFragment: '(?:)((\n|\r|.)*?)(?:<\/script>)', - - emptyFunction: function() {}, - K: function(x) {return x} -} - -var Class = { - create: function() { - return function() { - this.initialize.apply(this, arguments); - } - } -} - -var Abstract = new Object(); - -Object.extend = function(destination, source) { - for (property in source) { - destination[property] = source[property]; - } - return destination; -} - -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; - } -} - -Function.prototype.bind = function() { - var __method = this, args = $A(arguments), object = args.shift(); - return function() { - return __method.apply(object, args.concat($A(arguments))); - } -} - -Function.prototype.bindAsEventListener = function(object) { - var __method = this; - return function(event) { - return __method.call(object, event || window.event); - } -} - -Object.extend(Number.prototype, { - toColorPart: function() { - var digits = this.toString(16); - if (this < 16) return '0' + digits; - return digits; - }, - - succ: function() { - return this + 1; - }, - - times: function(iterator) { - $R(0, this, true).each(iterator); - return this; - } -}); - -var Try = { - these: function() { - var returnValue; - - for (var i = 0; i < arguments.length; i++) { - var lambda = arguments[i]; - try { - returnValue = lambda(); - break; - } catch (e) {} - } - - return returnValue; - } -} - -/*--------------------------------------------------------------------------*/ - -var PeriodicalExecuter = Class.create(); -PeriodicalExecuter.prototype = { - initialize: function(callback, frequency) { - this.callback = callback; - this.frequency = frequency; - this.currentlyExecuting = false; - - this.registerCallback(); - }, - - registerCallback: function() { - setInterval(this.onTimerEvent.bind(this), this.frequency * 1000); - }, - - onTimerEvent: function() { - if (!this.currentlyExecuting) { - try { - this.currentlyExecuting = true; - this.callback(); - } finally { - this.currentlyExecuting = false; - } - } - } -} - -/*--------------------------------------------------------------------------*/ - -function $() { - var elements = new Array(); - - for (var i = 0; i < arguments.length; i++) { - var element = arguments[i]; - if (typeof element == 'string') - element = document.getElementById(element); - - if (arguments.length == 1) - return element; - - elements.push(element); - } - - return elements; -} -Object.extend(String.prototype, { - 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(eval); - }, - - escapeHTML: function() { - var div = document.createElement('div'); - var text = document.createTextNode(this); - div.appendChild(text); - return div.innerHTML; - }, - - unescapeHTML: function() { - var div = document.createElement('div'); - div.innerHTML = this.stripTags(); - return div.childNodes[0] ? div.childNodes[0].nodeValue : ''; - }, - - toQueryParams: function() { - var pairs = this.match(/^\??(.*)$/)[1].split('&'); - return pairs.inject({}, function(params, pairString) { - var pair = pairString.split('='); - params[pair[0]] = pair[1]; - return params; - }); - }, - - toArray: function() { - return this.split(''); - }, - - camelize: function() { - var oStringList = this.split('-'); - if (oStringList.length == 1) return oStringList[0]; - - var camelizedString = this.indexOf('-') == 0 - ? oStringList[0].charAt(0).toUpperCase() + oStringList[0].substring(1) - : oStringList[0]; - - for (var i = 1, len = oStringList.length; i < len; i++) { - var s = oStringList[i]; - camelizedString += s.charAt(0).toUpperCase() + s.substring(1); - } - - return camelizedString; - }, - - inspect: function() { - return "'" + this.replace('\\', '\\\\').replace("'", '\\\'') + "'"; - } -}); - -String.prototype.parseQuery = String.prototype.toQueryParams; - -var $break = new Object(); -var $continue = new Object(); - -var Enumerable = { - each: function(iterator) { - var index = 0; - try { - this._each(function(value) { - try { - iterator(value, index++); - } catch (e) { - if (e != $continue) throw e; - } - }); - } catch (e) { - if (e != $break) throw e; - } - }, - - all: function(iterator) { - var result = true; - this.each(function(value, index) { - result = result && !!(iterator || Prototype.K)(value, index); - if (!result) throw $break; - }); - return result; - }, - - any: function(iterator) { - var result = true; - this.each(function(value, index) { - if (result = !!(iterator || Prototype.K)(value, index)) - throw $break; - }); - return result; - }, - - collect: function(iterator) { - var results = []; - this.each(function(value, index) { - results.push(iterator(value, index)); - }); - return results; - }, - - detect: function (iterator) { - var result; - this.each(function(value, index) { - if (iterator(value, index)) { - result = value; - throw $break; - } - }); - return result; - }, - - findAll: function(iterator) { - var results = []; - this.each(function(value, index) { - if (iterator(value, index)) - results.push(value); - }); - return results; - }, - - grep: function(pattern, iterator) { - var results = []; - this.each(function(value, index) { - var stringValue = value.toString(); - if (stringValue.match(pattern)) - results.push((iterator || Prototype.K)(value, index)); - }) - return results; - }, - - include: function(object) { - var found = false; - this.each(function(value) { - if (value == object) { - found = true; - throw $break; - } - }); - return found; - }, - - inject: function(memo, iterator) { - this.each(function(value, index) { - memo = iterator(memo, value, index); - }); - return memo; - }, - - invoke: function(method) { - var args = $A(arguments).slice(1); - return this.collect(function(value) { - return value[method].apply(value, args); - }); - }, - - max: function(iterator) { - var result; - this.each(function(value, index) { - value = (iterator || Prototype.K)(value, index); - if (value >= (result || value)) - result = value; - }); - return result; - }, - - min: function(iterator) { - var result; - this.each(function(value, index) { - value = (iterator || Prototype.K)(value, index); - if (value <= (result || value)) - result = value; - }); - return result; - }, - - partition: function(iterator) { - var trues = [], falses = []; - this.each(function(value, index) { - ((iterator || Prototype.K)(value, index) ? - trues : falses).push(value); - }); - return [trues, falses]; - }, - - pluck: function(property) { - var results = []; - this.each(function(value, index) { - results.push(value[property]); - }); - return results; - }, - - reject: function(iterator) { - var results = []; - this.each(function(value, index) { - if (!iterator(value, index)) - results.push(value); - }); - return results; - }, - - sortBy: function(iterator) { - return this.collect(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.collect(Prototype.K); - }, - - zip: function() { - var iterator = Prototype.K, args = $A(arguments); - if (typeof args.last() == 'function') - iterator = args.pop(); - - var collections = [this].concat(args).map($A); - return this.map(function(value, index) { - iterator(value = collections.pluck(index)); - return value; - }); - }, - - inspect: function() { - return '#'; - } -} - -Object.extend(Enumerable, { - map: Enumerable.collect, - find: Enumerable.detect, - select: Enumerable.findAll, - member: Enumerable.include, - entries: Enumerable.toArray -}); -var $A = Array.from = function(iterable) { - if (!iterable) return []; - if (iterable.toArray) { - return iterable.toArray(); - } else { - var results = []; - for (var i = 0; i < iterable.length; i++) - results.push(iterable[i]); - return results; - } -} - -Object.extend(Array.prototype, Enumerable); - -Array.prototype._reverse = Array.prototype.reverse; - -Object.extend(Array.prototype, { - _each: function(iterator) { - for (var i = 0; i < this.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 != undefined || value != null; - }); - }, - - flatten: function() { - return this.inject([], function(array, value) { - return array.concat(value.constructor == Array ? - value.flatten() : [value]); - }); - }, - - without: function() { - var values = $A(arguments); - return this.select(function(value) { - return !values.include(value); - }); - }, - - indexOf: function(object) { - for (var i = 0; i < this.length; i++) - if (this[i] == object) return i; - return -1; - }, - - reverse: function(inline) { - return (inline !== false ? this : this.toArray())._reverse(); - }, - - shift: function() { - var result = this[0]; - for (var i = 0; i < this.length - 1; i++) - this[i] = this[i + 1]; - this.length--; - return result; - }, - - inspect: function() { - return '[' + this.map(Object.inspect).join(', ') + ']'; - } -}); -var Hash = { - _each: function(iterator) { - for (key in this) { - var value = this[key]; - if (typeof value == 'function') 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'); - }, - - merge: function(hash) { - return $H(hash).inject($H(this), function(mergedHash, pair) { - mergedHash[pair.key] = pair.value; - return mergedHash; - }); - }, - - toQueryString: function() { - return this.map(function(pair) { - return pair.map(encodeURIComponent).join('='); - }).join('&'); - }, - - inspect: function() { - return '#'; - } -} - -function $H(object) { - var hash = Object.extend({}, object || {}); - Object.extend(hash, Enumerable); - Object.extend(hash, Hash); - return hash; -} -ObjectRange = Class.create(); -Object.extend(ObjectRange.prototype, Enumerable); -Object.extend(ObjectRange.prototype, { - initialize: function(start, end, exclusive) { - this.start = start; - this.end = end; - this.exclusive = exclusive; - }, - - _each: function(iterator) { - var value = this.start; - do { - iterator(value); - value = value.succ(); - } while (this.include(value)); - }, - - 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 ActiveXObject('Msxml2.XMLHTTP')}, - function() {return new ActiveXObject('Microsoft.XMLHTTP')}, - function() {return new XMLHttpRequest()} - ) || false; - }, - - activeRequestCount: 0 -} - -Ajax.Responders = { - responders: [], - - _each: function(iterator) { - this.responders._each(iterator); - }, - - register: function(responderToAdd) { - if (!this.include(responderToAdd)) - this.responders.push(responderToAdd); - }, - - unregister: function(responderToRemove) { - this.responders = this.responders.without(responderToRemove); - }, - - dispatch: function(callback, request, transport, json) { - this.each(function(responder) { - if (responder[callback] && typeof responder[callback] == 'function') { - 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 = function() {}; -Ajax.Base.prototype = { - setOptions: function(options) { - this.options = { - method: 'post', - asynchronous: true, - parameters: '' - } - Object.extend(this.options, options || {}); - }, - - responseIsSuccess: function() { - return this.transport.status == undefined - || this.transport.status == 0 - || (this.transport.status >= 200 && this.transport.status < 300); - }, - - responseIsFailure: function() { - return !this.responseIsSuccess(); - } -} - -Ajax.Request = Class.create(); -Ajax.Request.Events = - ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete']; - -Ajax.Request.prototype = Object.extend(new Ajax.Base(), { - initialize: function(url, options) { - this.transport = Ajax.getTransport(); - this.setOptions(options); - this.request(url); - }, - - request: function(url) { - var parameters = this.options.parameters || ''; - if (parameters.length > 0) parameters += '&_='; - - try { - this.url = url; - if (this.options.method == 'get' && parameters.length > 0) - this.url += (this.url.match(/\?/) ? '&' : '?') + parameters; - - Ajax.Responders.dispatch('onCreate', this, this.transport); - - this.transport.open(this.options.method, this.url, - this.options.asynchronous); - - if (this.options.asynchronous) { - this.transport.onreadystatechange = this.onStateChange.bind(this); - setTimeout((function() {this.respondToReadyState(1)}).bind(this), 10); - } - - this.setRequestHeaders(); - - var body = this.options.postBody ? this.options.postBody : parameters; - this.transport.send(this.options.method == 'post' ? body : null); - - } catch (e) { - this.dispatchException(e); - } - }, - - setRequestHeaders: function() { - var requestHeaders = - ['X-Requested-With', 'XMLHttpRequest', - 'X-Prototype-Version', Prototype.Version]; - - if (this.options.method == 'post') { - requestHeaders.push('Content-type', - 'application/x-www-form-urlencoded'); - - /* Force "Connection: close" for Mozilla browsers to work around - * a bug where XMLHttpReqeuest sends an incorrect Content-length - * header. See Mozilla Bugzilla #246651. - */ - if (this.transport.overrideMimeType) - requestHeaders.push('Connection', 'close'); - } - - if (this.options.requestHeaders) - requestHeaders.push.apply(requestHeaders, this.options.requestHeaders); - - for (var i = 0; i < requestHeaders.length; i += 2) - this.transport.setRequestHeader(requestHeaders[i], requestHeaders[i+1]); - }, - - onStateChange: function() { - var readyState = this.transport.readyState; - if (readyState != 1) - this.respondToReadyState(this.transport.readyState); - }, - - header: function(name) { - try { - return this.transport.getResponseHeader(name); - } catch (e) {} - }, - - evalJSON: function() { - try { - return eval(this.header('X-JSON')); - } catch (e) {} - }, - - evalResponse: function() { - try { - return eval(this.transport.responseText); - } catch (e) { - this.dispatchException(e); - } - }, - - respondToReadyState: function(readyState) { - var event = Ajax.Request.Events[readyState]; - var transport = this.transport, json = this.evalJSON(); - - if (event == 'Complete') { - try { - (this.options['on' + this.transport.status] - || this.options['on' + (this.responseIsSuccess() ? 'Success' : 'Failure')] - || Prototype.emptyFunction)(transport, json); - } catch (e) { - this.dispatchException(e); - } - - if ((this.header('Content-type') || '').match(/^text\/javascript/i)) - this.evalResponse(); - } - - try { - (this.options['on' + event] || Prototype.emptyFunction)(transport, json); - Ajax.Responders.dispatch('on' + event, this, transport, json); - } catch (e) { - this.dispatchException(e); - } - - /* Avoid memory leak in MSIE: clean up the oncomplete event handler */ - if (event == 'Complete') - this.transport.onreadystatechange = Prototype.emptyFunction; - }, - - dispatchException: function(exception) { - (this.options.onException || Prototype.emptyFunction)(this, exception); - Ajax.Responders.dispatch('onException', this, exception); - } -}); - -Ajax.Updater = Class.create(); - -Object.extend(Object.extend(Ajax.Updater.prototype, Ajax.Request.prototype), { - initialize: function(container, url, options) { - this.containers = { - success: container.success ? $(container.success) : $(container), - failure: container.failure ? $(container.failure) : - (container.success ? null : $(container)) - } - - this.transport = Ajax.getTransport(); - this.setOptions(options); - - var onComplete = this.options.onComplete || Prototype.emptyFunction; - this.options.onComplete = (function(transport, object) { - this.updateContent(); - onComplete(transport, object); - }).bind(this); - - this.request(url); - }, - - updateContent: function() { - var receiver = this.responseIsSuccess() ? - this.containers.success : this.containers.failure; - var response = this.transport.responseText; - - if (!this.options.evalScripts) - response = response.stripScripts(); - - if (receiver) { - if (this.options.insertion) { - new this.options.insertion(receiver, response); - } else { - Element.update(receiver, response); - } - } - - if (this.responseIsSuccess()) { - if (this.onComplete) - setTimeout(this.onComplete.bind(this), 10); - } - } -}); - -Ajax.PeriodicalUpdater = Class.create(); -Ajax.PeriodicalUpdater.prototype = Object.extend(new Ajax.Base(), { - initialize: function(container, url, options) { - this.setOptions(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.onComplete = undefined; - clearTimeout(this.timer); - (this.onComplete || Prototype.emptyFunction).apply(this, arguments); - }, - - updateComplete: function(request) { - if (this.options.decay) { - this.decay = (request.responseText == this.lastText ? - this.decay * this.options.decay : 1); - - this.lastText = request.responseText; - } - this.timer = setTimeout(this.onTimerEvent.bind(this), - this.decay * this.frequency * 1000); - }, - - onTimerEvent: function() { - this.updater = new Ajax.Updater(this.container, this.url, this.options); - } -}); -document.getElementsByClassName = function(className, parentElement) { - var children = ($(parentElement) || document.body).getElementsByTagName('*'); - return $A(children).inject([], function(elements, child) { - if (child.className.match(new RegExp("(^|\\s)" + className + "(\\s|$)"))) - elements.push(child); - return elements; - }); -} - -/*--------------------------------------------------------------------------*/ - -if (!window.Element) { - var Element = new Object(); -} - -Object.extend(Element, { - visible: function(element) { - return $(element).style.display != 'none'; - }, - - toggle: function() { - for (var i = 0; i < arguments.length; i++) { - var element = $(arguments[i]); - Element[Element.visible(element) ? 'hide' : 'show'](element); - } - }, - - hide: function() { - for (var i = 0; i < arguments.length; i++) { - var element = $(arguments[i]); - element.style.display = 'none'; - } - }, - - show: function() { - for (var i = 0; i < arguments.length; i++) { - var element = $(arguments[i]); - element.style.display = ''; - } - }, - - remove: function(element) { - element = $(element); - element.parentNode.removeChild(element); - }, - - update: function(element, html) { - $(element).innerHTML = html.stripScripts(); - setTimeout(function() {html.evalScripts()}, 10); - }, - - getHeight: function(element) { - element = $(element); - return element.offsetHeight; - }, - - classNames: function(element) { - return new Element.ClassNames(element); - }, - - hasClassName: function(element, className) { - if (!(element = $(element))) return; - return Element.classNames(element).include(className); - }, - - addClassName: function(element, className) { - if (!(element = $(element))) return; - return Element.classNames(element).add(className); - }, - - removeClassName: function(element, className) { - if (!(element = $(element))) return; - return Element.classNames(element).remove(className); - }, - - // removes whitespace-only text node children - cleanWhitespace: function(element) { - element = $(element); - for (var i = 0; i < element.childNodes.length; i++) { - var node = element.childNodes[i]; - if (node.nodeType == 3 && !/\S/.test(node.nodeValue)) - Element.remove(node); - } - }, - - empty: function(element) { - return $(element).innerHTML.match(/^\s*$/); - }, - - scrollTo: function(element) { - element = $(element); - var x = element.x ? element.x : element.offsetLeft, - y = element.y ? element.y : element.offsetTop; - window.scrollTo(x, y); - }, - - getStyle: function(element, style) { - element = $(element); - var value = element.style[style.camelize()]; - if (!value) { - if (document.defaultView && document.defaultView.getComputedStyle) { - var css = document.defaultView.getComputedStyle(element, null); - value = css ? css.getPropertyValue(style) : null; - } else if (element.currentStyle) { - value = element.currentStyle[style.camelize()]; - } - } - - if (window.opera && ['left', 'top', 'right', 'bottom'].include(style)) - if (Element.getStyle(element, 'position') == 'static') value = 'auto'; - - return value == 'auto' ? null : value; - }, - - setStyle: function(element, style) { - element = $(element); - for (name in style) - element.style[name.camelize()] = style[name]; - }, - - getDimensions: function(element) { - element = $(element); - if (Element.getStyle(element, 'display') != 'none') - 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; - els.visibility = 'hidden'; - els.position = 'absolute'; - els.display = ''; - var originalWidth = element.clientWidth; - var originalHeight = element.clientHeight; - els.display = 'none'; - 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; - } - } - }, - - 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 = ''; - } - }, - - makeClipping: function(element) { - element = $(element); - if (element._overflow) return; - element._overflow = element.style.overflow; - if ((Element.getStyle(element, 'overflow') || 'visible') != 'hidden') - element.style.overflow = 'hidden'; - }, - - undoClipping: function(element) { - element = $(element); - if (element._overflow) return; - element.style.overflow = element._overflow; - element._overflow = undefined; - } -}); - -var Toggle = new Object(); -Toggle.display = Element.toggle; - -/*--------------------------------------------------------------------------*/ - -Abstract.Insertion = function(adjacency) { - this.adjacency = adjacency; -} - -Abstract.Insertion.prototype = { - initialize: function(element, content) { - this.element = $(element); - this.content = content.stripScripts(); - - if (this.adjacency && this.element.insertAdjacentHTML) { - try { - this.element.insertAdjacentHTML(this.adjacency, this.content); - } catch (e) { - if (this.element.tagName.toLowerCase() == 'tbody') { - this.insertContent(this.contentFromAnonymousTable()); - } else { - throw e; - } - } - } else { - this.range = this.element.ownerDocument.createRange(); - if (this.initializeRange) this.initializeRange(); - this.insertContent([this.range.createContextualFragment(this.content)]); - } - - setTimeout(function() {content.evalScripts()}, 10); - }, - - contentFromAnonymousTable: function() { - var div = document.createElement('div'); - div.innerHTML = '' + this.content + '
'; - return $A(div.childNodes[0].childNodes[0].childNodes); - } -} - -var Insertion = new Object(); - -Insertion.Before = Class.create(); -Insertion.Before.prototype = Object.extend(new Abstract.Insertion('beforeBegin'), { - initializeRange: function() { - this.range.setStartBefore(this.element); - }, - - insertContent: function(fragments) { - fragments.each((function(fragment) { - this.element.parentNode.insertBefore(fragment, this.element); - }).bind(this)); - } -}); - -Insertion.Top = Class.create(); -Insertion.Top.prototype = Object.extend(new Abstract.Insertion('afterBegin'), { - initializeRange: function() { - this.range.selectNodeContents(this.element); - this.range.collapse(true); - }, - - insertContent: function(fragments) { - fragments.reverse(false).each((function(fragment) { - this.element.insertBefore(fragment, this.element.firstChild); - }).bind(this)); - } -}); - -Insertion.Bottom = Class.create(); -Insertion.Bottom.prototype = Object.extend(new Abstract.Insertion('beforeEnd'), { - initializeRange: function() { - this.range.selectNodeContents(this.element); - this.range.collapse(this.element); - }, - - insertContent: function(fragments) { - fragments.each((function(fragment) { - this.element.appendChild(fragment); - }).bind(this)); - } -}); - -Insertion.After = Class.create(); -Insertion.After.prototype = Object.extend(new Abstract.Insertion('afterEnd'), { - initializeRange: function() { - this.range.setStartAfter(this.element); - }, - - insertContent: function(fragments) { - fragments.each((function(fragment) { - this.element.parentNode.insertBefore(fragment, - this.element.nextSibling); - }).bind(this)); - } -}); - -/*--------------------------------------------------------------------------*/ - -Element.ClassNames = Class.create(); -Element.ClassNames.prototype = { - initialize: function(element) { - this.element = $(element); - }, - - _each: function(iterator) { - this.element.className.split(/\s+/).select(function(name) { - return name.length > 0; - })._each(iterator); - }, - - set: function(className) { - this.element.className = className; - }, - - add: function(classNameToAdd) { - if (this.include(classNameToAdd)) return; - this.set(this.toArray().concat(classNameToAdd).join(' ')); - }, - - remove: function(classNameToRemove) { - if (!this.include(classNameToRemove)) return; - this.set(this.select(function(className) { - return className != classNameToRemove; - }).join(' ')); - }, - - toString: function() { - return this.toArray().join(' '); - } -} - -Object.extend(Element.ClassNames.prototype, Enumerable); -var Field = { - clear: function() { - for (var i = 0; i < arguments.length; i++) - $(arguments[i]).value = ''; - }, - - focus: function(element) { - $(element).focus(); - }, - - present: function() { - for (var i = 0; i < arguments.length; i++) - if ($(arguments[i]).value == '') return false; - return true; - }, - - select: function(element) { - $(element).select(); - }, - - activate: function(element) { - element = $(element); - element.focus(); - if (element.select) - element.select(); - } -} - -/*--------------------------------------------------------------------------*/ - -var Form = { - serialize: function(form) { - var elements = Form.getElements($(form)); - var queryComponents = new Array(); - - for (var i = 0; i < elements.length; i++) { - var queryComponent = Form.Element.serialize(elements[i]); - if (queryComponent) - queryComponents.push(queryComponent); - } - - return queryComponents.join('&'); - }, - - getElements: function(form) { - form = $(form); - var elements = new Array(); - - for (tagName in Form.Element.Serializers) { - var tagElements = form.getElementsByTagName(tagName); - for (var j = 0; j < tagElements.length; j++) - elements.push(tagElements[j]); - } - return elements; - }, - - getInputs: function(form, typeName, name) { - form = $(form); - var inputs = form.getElementsByTagName('input'); - - if (!typeName && !name) - return inputs; - - var matchingInputs = new Array(); - for (var i = 0; i < inputs.length; i++) { - var input = inputs[i]; - if ((typeName && input.type != typeName) || - (name && input.name != name)) - continue; - matchingInputs.push(input); - } - - return matchingInputs; - }, - - disable: function(form) { - var elements = Form.getElements(form); - for (var i = 0; i < elements.length; i++) { - var element = elements[i]; - element.blur(); - element.disabled = 'true'; - } - }, - - enable: function(form) { - var elements = Form.getElements(form); - for (var i = 0; i < elements.length; i++) { - var element = elements[i]; - element.disabled = ''; - } - }, - - findFirstElement: function(form) { - return Form.getElements(form).find(function(element) { - return element.type != 'hidden' && !element.disabled && - ['input', 'select', 'textarea'].include(element.tagName.toLowerCase()); - }); - }, - - focusFirstElement: function(form) { - Field.activate(Form.findFirstElement(form)); - }, - - reset: function(form) { - $(form).reset(); - } -} - -Form.Element = { - serialize: function(element) { - element = $(element); - var method = element.tagName.toLowerCase(); - var parameter = Form.Element.Serializers[method](element); - - if (parameter) { - var key = encodeURIComponent(parameter[0]); - if (key.length == 0) return; - - if (parameter[1].constructor != Array) - parameter[1] = [parameter[1]]; - - return parameter[1].map(function(value) { - return key + '=' + encodeURIComponent(value); - }).join('&'); - } - }, - - getValue: function(element) { - element = $(element); - var method = element.tagName.toLowerCase(); - var parameter = Form.Element.Serializers[method](element); - - if (parameter) - return parameter[1]; - } -} - -Form.Element.Serializers = { - input: function(element) { - switch (element.type.toLowerCase()) { - case 'submit': - case 'hidden': - case 'password': - case 'text': - return Form.Element.Serializers.textarea(element); - case 'checkbox': - case 'radio': - return Form.Element.Serializers.inputSelector(element); - } - return false; - }, - - inputSelector: function(element) { - if (element.checked) - return [element.name, element.value]; - }, - - textarea: function(element) { - return [element.name, element.value]; - }, - - select: function(element) { - return Form.Element.Serializers[element.type == 'select-one' ? - 'selectOne' : 'selectMany'](element); - }, - - selectOne: function(element) { - var value = '', opt, index = element.selectedIndex; - if (index >= 0) { - opt = element.options[index]; - value = opt.value; - if (!value && !('value' in opt)) - value = opt.text; - } - return [element.name, value]; - }, - - selectMany: function(element) { - var value = new Array(); - for (var i = 0; i < element.length; i++) { - var opt = element.options[i]; - if (opt.selected) { - var optValue = opt.value; - if (!optValue && !('value' in opt)) - optValue = opt.text; - value.push(optValue); - } - } - return [element.name, value]; - } -} - -/*--------------------------------------------------------------------------*/ - -var $F = Form.Element.getValue; - -/*--------------------------------------------------------------------------*/ - -Abstract.TimedObserver = function() {} -Abstract.TimedObserver.prototype = { - initialize: function(element, frequency, callback) { - this.frequency = frequency; - this.element = $(element); - this.callback = callback; - - this.lastValue = this.getValue(); - this.registerCallback(); - }, - - registerCallback: function() { - setInterval(this.onTimerEvent.bind(this), this.frequency * 1000); - }, - - onTimerEvent: function() { - var value = this.getValue(); - if (this.lastValue != value) { - this.callback(this.element, value); - this.lastValue = value; - } - } -} - -Form.Element.Observer = Class.create(); -Form.Element.Observer.prototype = Object.extend(new Abstract.TimedObserver(), { - getValue: function() { - return Form.Element.getValue(this.element); - } -}); - -Form.Observer = Class.create(); -Form.Observer.prototype = Object.extend(new Abstract.TimedObserver(), { - getValue: function() { - return Form.serialize(this.element); - } -}); - -/*--------------------------------------------------------------------------*/ - -Abstract.EventObserver = function() {} -Abstract.EventObserver.prototype = { - 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() { - var elements = Form.getElements(this.element); - for (var i = 0; i < elements.length; i++) - this.registerCallback(elements[i]); - }, - - registerCallback: function(element) { - if (element.type) { - switch (element.type.toLowerCase()) { - case 'checkbox': - case 'radio': - Event.observe(element, 'click', this.onElementEvent.bind(this)); - break; - case 'password': - case 'text': - case 'textarea': - case 'select-one': - case 'select-multiple': - Event.observe(element, 'change', this.onElementEvent.bind(this)); - break; - } - } - } -} - -Form.Element.EventObserver = Class.create(); -Form.Element.EventObserver.prototype = Object.extend(new Abstract.EventObserver(), { - getValue: function() { - return Form.Element.getValue(this.element); - } -}); - -Form.EventObserver = Class.create(); -Form.EventObserver.prototype = Object.extend(new Abstract.EventObserver(), { - getValue: function() { - return Form.serialize(this.element); - } -}); -if (!window.Event) { - var Event = new Object(); -} - -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, - - element: function(event) { - return event.target || event.srcElement; - }, - - isLeftClick: function(event) { - return (((event.which) && (event.which == 1)) || - ((event.button) && (event.button == 1))); - }, - - pointerX: function(event) { - return event.pageX || (event.clientX + - (document.documentElement.scrollLeft || document.body.scrollLeft)); - }, - - pointerY: function(event) { - return event.pageY || (event.clientY + - (document.documentElement.scrollTop || document.body.scrollTop)); - }, - - stop: function(event) { - if (event.preventDefault) { - event.preventDefault(); - event.stopPropagation(); - } else { - event.returnValue = false; - event.cancelBubble = true; - } - }, - - // find the first node with the given tagName, starting from the - // node the event was triggered on; traverses the DOM upwards - findElement: function(event, tagName) { - var element = Event.element(event); - while (element.parentNode && (!element.tagName || - (element.tagName.toUpperCase() != tagName.toUpperCase()))) - element = element.parentNode; - return element; - }, - - observers: false, - - _observeAndCache: function(element, name, observer, useCapture) { - if (!this.observers) this.observers = []; - if (element.addEventListener) { - this.observers.push([element, name, observer, useCapture]); - element.addEventListener(name, observer, useCapture); - } else if (element.attachEvent) { - this.observers.push([element, name, observer, useCapture]); - element.attachEvent('on' + name, observer); - } - }, - - unloadCache: function() { - if (!Event.observers) return; - for (var i = 0; i < Event.observers.length; i++) { - Event.stopObserving.apply(this, Event.observers[i]); - Event.observers[i][0] = null; - } - Event.observers = false; - }, - - observe: function(element, name, observer, useCapture) { - var element = $(element); - useCapture = useCapture || false; - - if (name == 'keypress' && - (navigator.appVersion.match(/Konqueror|Safari|KHTML/) - || element.attachEvent)) - name = 'keydown'; - - this._observeAndCache(element, name, observer, useCapture); - }, - - stopObserving: function(element, name, observer, useCapture) { - var element = $(element); - useCapture = useCapture || false; - - if (name == 'keypress' && - (navigator.appVersion.match(/Konqueror|Safari|KHTML/) - || element.detachEvent)) - name = 'keydown'; - - if (element.removeEventListener) { - element.removeEventListener(name, observer, useCapture); - } else if (element.detachEvent) { - element.detachEvent('on' + name, observer); - } - } -}); - -/* prevent memory leaks in IE */ -Event.observe(window, 'unload', Event.unloadCache, false); -var Position = { - // set to true if needed, warning: firefox performance problems - // NOT neeeded for page scrolling, only if draggable contained in - // scrollable elements - includeScrollOffsets: false, - - // must be called before calling withinIncludingScrolloffset, every time the - // page is scrolled - prepare: function() { - this.deltaX = window.pageXOffset - || document.documentElement.scrollLeft - || document.body.scrollLeft - || 0; - this.deltaY = window.pageYOffset - || document.documentElement.scrollTop - || document.body.scrollTop - || 0; - }, - - realOffset: function(element) { - var valueT = 0, valueL = 0; - do { - valueT += element.scrollTop || 0; - valueL += element.scrollLeft || 0; - element = element.parentNode; - } while (element); - return [valueL, valueT]; - }, - - cumulativeOffset: function(element) { - var valueT = 0, valueL = 0; - do { - valueT += element.offsetTop || 0; - valueL += element.offsetLeft || 0; - element = element.offsetParent; - } while (element); - return [valueL, valueT]; - }, - - positionedOffset: function(element) { - var valueT = 0, valueL = 0; - do { - valueT += element.offsetTop || 0; - valueL += element.offsetLeft || 0; - element = element.offsetParent; - if (element) { - p = Element.getStyle(element, 'position'); - if (p == 'relative' || p == 'absolute') break; - } - } while (element); - return [valueL, valueT]; - }, - - offsetParent: 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; - }, - - // caches x/y coordinate pair to use with overlap - within: function(element, x, y) { - if (this.includeScrollOffsets) - return this.withinIncludingScrolloffsets(element, x, y); - this.xcomp = x; - this.ycomp = y; - this.offset = this.cumulativeOffset(element); - - return (y >= this.offset[1] && - y < this.offset[1] + element.offsetHeight && - x >= this.offset[0] && - x < this.offset[0] + element.offsetWidth); - }, - - withinIncludingScrolloffsets: function(element, x, y) { - var offsetcache = this.realOffset(element); - - this.xcomp = x + offsetcache[0] - this.deltaX; - this.ycomp = y + offsetcache[1] - this.deltaY; - this.offset = this.cumulativeOffset(element); - - return (this.ycomp >= this.offset[1] && - this.ycomp < this.offset[1] + element.offsetHeight && - this.xcomp >= this.offset[0] && - this.xcomp < this.offset[0] + element.offsetWidth); - }, - - // within must be called directly before - overlap: function(mode, element) { - if (!mode) return 0; - if (mode == 'vertical') - return ((this.offset[1] + element.offsetHeight) - this.ycomp) / - element.offsetHeight; - if (mode == 'horizontal') - return ((this.offset[0] + element.offsetWidth) - this.xcomp) / - element.offsetWidth; - }, - - clone: function(source, target) { - source = $(source); - target = $(target); - target.style.position = 'absolute'; - var offsets = this.cumulativeOffset(source); - target.style.top = offsets[1] + 'px'; - target.style.left = offsets[0] + 'px'; - target.style.width = source.offsetWidth + 'px'; - target.style.height = source.offsetHeight + 'px'; - }, - - page: 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) - if (Element.getStyle(element,'position')=='absolute') break; - - } while (element = element.offsetParent); - - element = forElement; - do { - valueT -= element.scrollTop || 0; - valueL -= element.scrollLeft || 0; - } while (element = element.parentNode); - - return [valueL, valueT]; - }, - - clone: function(source, target) { - 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 = Position.page(source); - - // find coordinate system to use - target = $(target); - 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(target,'position') == 'absolute') { - parent = Position.offsetParent(target); - delta = Position.page(parent); - } - - // 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) target.style.left = (p[0] - delta[0] + options.offsetLeft) + 'px'; - if(options.setTop) target.style.top = (p[1] - delta[1] + options.offsetTop) + 'px'; - if(options.setWidth) target.style.width = source.offsetWidth + 'px'; - if(options.setHeight) target.style.height = source.offsetHeight + 'px'; - }, - - absolutize: function(element) { - element = $(element); - if (element.style.position == 'absolute') return; - Position.prepare(); - - var offsets = Position.positionedOffset(element); - 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';; - }, - - relativize: function(element) { - element = $(element); - if (element.style.position == 'relative') return; - Position.prepare(); - - 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; - } -} - -// Safari returns margins on body which is incorrect if the child is absolutely -// positioned. For performance reasons, redefine Position.cumulativeOffset for -// KHTML/WebKit only. -if (/Konqueror|Safari|KHTML/.test(navigator.userAgent)) { - Position.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 [valueL, valueT]; - } -} \ No newline at end of file diff --git a/tracks/vendor/plugins/javascript_generator_templates/lib/add_rjs_to_action_controller.rb b/tracks/vendor/plugins/javascript_generator_templates/lib/add_rjs_to_action_controller.rb deleted file mode 100644 index 91d79c15..00000000 --- a/tracks/vendor/plugins/javascript_generator_templates/lib/add_rjs_to_action_controller.rb +++ /dev/null @@ -1,67 +0,0 @@ -#-- -# Copyright (c) 2004 David Heinemeier Hansson -# -# 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. -#++ -module ActionController #:nodoc: - class Base - protected - def render_action(action_name, status = nil, with_layout = true) - template = default_template_name(action_name) - if with_layout && !template_exempt_from_layout?(template) - render_with_layout(template, status) - else - render_without_layout(template, status) - end - end - - private - def template_exempt_from_layout?(template_name = default_template_name) - @template.javascript_template_exists?(template_name) - end - - def default_template_name(default_action_name = action_name) - default_action_name = default_action_name.dup - strip_out_controller!(default_action_name) if template_path_includes_controller?(default_action_name) - "#{self.class.controller_path}/#{default_action_name}" - end - - def strip_out_controller!(path) - path.replace path.split('/', 2).last - end - - def template_path_includes_controller?(path) - path.to_s['/'] && self.class.controller_path.split('/')[-1] == path.split('/')[0] - end - end - - module Layout #:nodoc: - private - def apply_layout?(template_with_options, options) - template_with_options ? candidate_for_layout?(options) : !template_exempt_from_layout? - end - - def candidate_for_layout?(options) - (options.has_key?(:layout) && options[:layout] != false) || - options.values_at(:text, :file, :inline, :partial, :nothing).compact.empty? && - !template_exempt_from_layout?(default_template_name(options[:action] || options[:template])) - end - end -end diff --git a/tracks/vendor/plugins/javascript_generator_templates/lib/add_rjs_to_action_view.rb b/tracks/vendor/plugins/javascript_generator_templates/lib/add_rjs_to_action_view.rb deleted file mode 100644 index 7b2c2de2..00000000 --- a/tracks/vendor/plugins/javascript_generator_templates/lib/add_rjs_to_action_view.rb +++ /dev/null @@ -1,142 +0,0 @@ -#-- -# Copyright (c) 2004 David Heinemeier Hansson -# -# 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. -#++ -module ActionView - class Base - def pick_template_extension(template_path)#:nodoc: - if match = delegate_template_exists?(template_path) - match.first - elsif erb_template_exists?(template_path): 'rhtml' - elsif builder_template_exists?(template_path): 'rxml' - elsif javascript_template_exists?(template_path): 'rjs' - else - raise ActionViewError, "No rhtml, rxml, rjs or delegate template found for #{template_path}" - end - end - - def javascript_template_exists?(template_path)#:nodoc: - template_exists?(template_path, :rjs) - end - - def file_exists?(template_path)#:nodoc: - %w(erb builder javascript delegate).any? do |template_type| - send("#{template_type}_template_exists?", template_path) - end - end - - private - # Create source code for given template - def create_template_source(extension, template, render_symbol, locals) - if template_requires_setup?(extension) - body = case extension.to_sym - when :rxml - "xml = Builder::XmlMarkup.new(:indent => 2)\n" + - "@controller.headers['Content-Type'] ||= 'text/xml'\n" + - template - when :rjs - "@controller.headers['Content-Type'] ||= 'text/javascript'\n" + - "update_page do |page|\n#{template}\nend" - end - else - body = ERB.new(template, nil, @@erb_trim_mode).src - end - - @@template_args[render_symbol] ||= {} - locals_keys = @@template_args[render_symbol].keys | locals - @@template_args[render_symbol] = locals_keys.inject({}) { |h, k| h[k] = true; h } - - locals_code = "" - locals_keys.each do |key| - locals_code << "#{key} = local_assigns[:#{key}] if local_assigns.has_key?(:#{key})\n" - end - - "def #{render_symbol}(local_assigns)\n#{locals_code}#{body}\nend" - end - - def template_requires_setup?(extension) - templates_requiring_setup.include? extension.to_s - end - - def templates_requiring_setup - %w(rxml rjs) - end - - def assign_method_name(extension, template, file_name) - method_name = '_run_' - method_name << "#{extension}_" if extension - - if file_name - file_path = File.expand_path(file_name) - base_path = File.expand_path(@base_path) - - i = file_path.index(base_path) - l = base_path.length - - method_name_file_part = i ? file_path[i+l+1,file_path.length-l-1] : file_path.clone - method_name_file_part.sub!(/\.r(html|xml|js)$/,'') - method_name_file_part.tr!('/:-', '_') - method_name_file_part.gsub!(/[^a-zA-Z0-9_]/){|s| s[0].to_s} - - method_name += method_name_file_part - else - @@inline_template_count += 1 - method_name << @@inline_template_count.to_s - end - - @@method_names[file_name || template] = method_name.intern - end - - def compile_template(extension, template, file_name, local_assigns) - method_key = file_name || template - - render_symbol = @@method_names[method_key] || assign_method_name(extension, template, file_name) - render_source = create_template_source(extension, template, render_symbol, local_assigns.keys) - - line_offset = @@template_args[render_symbol].size - if extension - case extension.to_sym - when :rxml, :rjs - line_offset += 2 - end - end - - begin - unless file_name.blank? - CompiledTemplates.module_eval(render_source, file_name, -line_offset) - else - CompiledTemplates.module_eval(render_source, 'compiled-template', -line_offset) - end - rescue Object => e - if logger - logger.debug "ERROR: compiling #{render_symbol} RAISED #{e}" - logger.debug "Function body: #{render_source}" - logger.debug "Backtrace: #{e.backtrace.join("\n")}" - end - - raise TemplateError.new(@base_path, method_key, @assigns, template, e) - end - - @@compile_time[render_symbol] = Time.now - # logger.debug "Compiled template #{method_key}\n ==> #{render_symbol}" if logger - end - end -end diff --git a/tracks/vendor/plugins/javascript_generator_templates/lib/add_rjs_to_javascript_helper.rb b/tracks/vendor/plugins/javascript_generator_templates/lib/add_rjs_to_javascript_helper.rb deleted file mode 100644 index 04201e46..00000000 --- a/tracks/vendor/plugins/javascript_generator_templates/lib/add_rjs_to_javascript_helper.rb +++ /dev/null @@ -1,204 +0,0 @@ -#-- -# Copyright (c) 2004 David Heinemeier Hansson -# -# 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. -#++ -module ActionView - module Helpers - module JavaScriptHelper - # JavaScriptGenerator generates blocks of JavaScript code that allow you - # to change the content and presentation of multiple DOM elements. Use - # this in your Ajax response bodies, either in a ), - periodically_call_remote(:update => "schremser_bier", :url => { :action => "mehr_bier" }) - end - - def test_form_remote_tag - assert_dom_equal %(
), - form_remote_tag(:update => "glass_of_beer", :url => { :action => :fast }) - assert_dom_equal %(), - form_remote_tag(:update => { :success => "glass_of_beer" }, :url => { :action => :fast }) - assert_dom_equal %(), - form_remote_tag(:update => { :failure => "glass_of_water" }, :url => { :action => :fast }) - assert_dom_equal %(), - form_remote_tag(:update => { :success => 'glass_of_beer', :failure => "glass_of_water" }, :url => { :action => :fast }) - end - - def test_on_callbacks - callbacks = [:uninitialized, :loading, :loaded, :interactive, :complete, :success, :failure] - callbacks.each do |callback| - assert_dom_equal %(), - form_remote_tag(:update => "glass_of_beer", :url => { :action => :fast }, callback=>"monkeys();") - assert_dom_equal %(), - form_remote_tag(:update => { :success => "glass_of_beer" }, :url => { :action => :fast }, callback=>"monkeys();") - assert_dom_equal %(), - form_remote_tag(:update => { :failure => "glass_of_beer" }, :url => { :action => :fast }, callback=>"monkeys();") - assert_dom_equal %(), - form_remote_tag(:update => { :success => "glass_of_beer", :failure => "glass_of_water" }, :url => { :action => :fast }, callback=>"monkeys();") - end - - #HTTP status codes 200 up to 599 have callbacks - #these should work - 100.upto(599) do |callback| - assert_dom_equal %(), - form_remote_tag(:update => "glass_of_beer", :url => { :action => :fast }, callback=>"monkeys();") - end - - #test 200 and 404 - assert_dom_equal %(), - form_remote_tag(:update => "glass_of_beer", :url => { :action => :fast }, 200=>"monkeys();", 404=>"bananas();") - - #these shouldn't - 1.upto(99) do |callback| - assert_dom_equal %(), - form_remote_tag(:update => "glass_of_beer", :url => { :action => :fast }, callback=>"monkeys();") - end - 600.upto(999) do |callback| - assert_dom_equal %(), - form_remote_tag(:update => "glass_of_beer", :url => { :action => :fast }, callback=>"monkeys();") - end - - #test ultimate combo - assert_dom_equal %(), - form_remote_tag(:update => "glass_of_beer", :url => { :action => :fast }, :loading => "c1()", :success => "s()", :failure => "f();", :complete => "c();", 200=>"monkeys();", 404=>"bananas();") - - end - - def test_submit_to_remote - assert_dom_equal %(), - submit_to_remote("More beer!", 1_000_000, :update => "empty_bottle") - end - - def test_observe_field - assert_dom_equal %(), - observe_field("glass", :frequency => 5.minutes, :url => { :action => "reorder_if_empty" }) - end - - def test_observe_form - assert_dom_equal %(), - observe_form("cart", :frequency => 2, :url => { :action => "cart_changed" }) - end - - def test_effect - assert_equal "new Effect.Highlight('posts',{});", visual_effect(:highlight, "posts") - assert_equal "new Effect.Highlight('posts',{});", visual_effect("highlight", :posts) - assert_equal "new Effect.Highlight('posts',{});", visual_effect(:highlight, :posts) - assert_equal "new Effect.Fade('fademe',{duration:4.0});", visual_effect(:fade, "fademe", :duration => 4.0) - assert_equal "new Effect.Shake(element,{});", visual_effect(:shake) - assert_equal "new Effect.DropOut('dropme',{queue:'end'});", visual_effect(:drop_out, 'dropme', :queue => :end) - end - - def test_sortable_element - assert_dom_equal %(), - sortable_element("mylist", :url => { :action => "order" }) - assert_equal %(), - sortable_element("mylist", :tag => "div", :constraint => "horizontal", :url => { :action => "order" }) - assert_dom_equal %||, - sortable_element("mylist", :containment => ['list1','list2'], :constraint => "horizontal", :url => { :action => "order" }) - assert_dom_equal %(), - sortable_element("mylist", :containment => 'list1', :constraint => "horizontal", :url => { :action => "order" }) - end - - def test_draggable_element - assert_dom_equal %(), - draggable_element('product_13') - assert_equal %(), - draggable_element('product_13', :revert => true) - end - - def test_drop_receiving_element - assert_dom_equal %(), - drop_receiving_element('droptarget1') - assert_dom_equal %(), - drop_receiving_element('droptarget1', :accept => 'products') - assert_dom_equal %(), - drop_receiving_element('droptarget1', :accept => 'products', :update => 'infobox') - assert_dom_equal %(), - drop_receiving_element('droptarget1', :accept => ['tshirts','mugs'], :update => 'infobox') - end - - def test_update_element_function - assert_equal %($('myelement').innerHTML = 'blub';\n), - update_element_function('myelement', :content => 'blub') - assert_equal %($('myelement').innerHTML = 'blub';\n), - update_element_function('myelement', :action => :update, :content => 'blub') - assert_equal %($('myelement').innerHTML = '';\n), - update_element_function('myelement', :action => :empty) - assert_equal %(Element.remove('myelement');\n), - update_element_function('myelement', :action => :remove) - - assert_equal %(new Insertion.Bottom('myelement','blub');\n), - update_element_function('myelement', :position => 'bottom', :content => 'blub') - assert_equal %(new Insertion.Bottom('myelement','blub');\n), - update_element_function('myelement', :action => :update, :position => :bottom, :content => 'blub') - - _erbout = "" - assert_equal %($('myelement').innerHTML = 'test';\n), - update_element_function('myelement') { _erbout << "test" } - - _erbout = "" - assert_equal %($('myelement').innerHTML = 'blockstuff';\n), - update_element_function('myelement', :content => 'paramstuff') { _erbout << "blockstuff" } - end - - def test_update_page - block = Proc.new { |page| page.replace_html('foo', 'bar') } - assert_equal create_generator(&block).to_s, update_page(&block) - end - - def test_update_page_tag - block = Proc.new { |page| page.replace_html('foo', 'bar') } - assert_equal javascript_tag(create_generator(&block).to_s), update_page_tag(&block) - end -end - -class JavaScriptGeneratorTest < Test::Unit::TestCase - include BaseTest - - def setup - super - @generator = create_generator - end - - def test_insert_html_with_string - assert_equal 'new Insertion.Top("element", "

This is a test

");', - @generator.insert_html(:top, 'element', '

This is a test

') - assert_equal 'new Insertion.Bottom("element", "

This is a test

");', - @generator.insert_html(:bottom, 'element', '

This is a test

') - assert_equal 'new Insertion.Before("element", "

This is a test

");', - @generator.insert_html(:before, 'element', '

This is a test

') - assert_equal 'new Insertion.After("element", "

This is a test

");', - @generator.insert_html(:after, 'element', '

This is a test

') - end - - def test_replace_html_with_string - assert_equal 'Element.update("element", "

This is a test

");', - @generator.replace_html('element', '

This is a test

') - end - - def test_remove - assert_equal '["foo"].each(Element.remove);', - @generator.remove('foo') - assert_equal '["foo", "bar", "baz"].each(Element.remove);', - @generator.remove('foo', 'bar', 'baz') - end - - def test_show - assert_equal 'Element.show("foo");', - @generator.show('foo') - assert_equal 'Element.show("foo", "bar", "baz");', - @generator.show('foo', 'bar', 'baz') - end - - def test_hide - assert_equal 'Element.hide("foo");', - @generator.hide('foo') - assert_equal 'Element.hide("foo", "bar", "baz");', - @generator.hide('foo', 'bar', 'baz') - end - - def test_alert - assert_equal 'alert("hello");', @generator.alert('hello') - end - - def test_redirect_to - assert_equal 'window.location.href = "http://www.example.com/welcome";', - @generator.redirect_to(:action => 'welcome') - end - - def test_delay - @generator.delay(20) do - @generator.hide('foo') - end - - assert_equal "setTimeout(function() {\n;\nElement.hide(\"foo\");\n}, 20000);", @generator.to_s - end - - def test_to_s - @generator.insert_html(:top, 'element', '

This is a test

') - @generator.insert_html(:bottom, 'element', '

This is a test

') - @generator.remove('foo', 'bar') - @generator.replace_html('baz', '

This is a test

') - - assert_equal <<-EOS.chomp, @generator.to_s -new Insertion.Top("element", "

This is a test

"); -new Insertion.Bottom("element", "

This is a test

"); -["foo", "bar"].each(Element.remove); -Element.update("baz", "

This is a test

"); - EOS - end -end diff --git a/tracks/vendor/rails/actionmailer/CHANGELOG b/tracks/vendor/rails/actionmailer/CHANGELOG deleted file mode 100644 index d81ebf82..00000000 --- a/tracks/vendor/rails/actionmailer/CHANGELOG +++ /dev/null @@ -1,211 +0,0 @@ -*1.1.5* (December 13th, 2005) - -* Become part of Rails 1.0 - - -*1.1.4* (December 7th, 2005) - -* Rename Version constant to VERSION. #2802 [Marcel Molina Jr.] - - -*1.1.3* (November 7th, 2005) - -* Allow Mailers to have custom initialize methods that set default instance variables for all mail actions #2563 [mrj@bigpond.net.au] - - -*1.1.2* (October 26th, 2005) - -* Upgraded to Action Pack 1.10.2 - - -*1.1.1* (October 19th, 2005) - -* Upgraded to Action Pack 1.10.1 - - -*1.1.0* (October 16th, 2005) - -* Update and extend documentation (rdoc) - -* Minero Aoki made TMail available to Rails/ActionMailer under the MIT license (instead of LGPL) [RubyConf '05] - -* Austin Ziegler made Text::Simple available to Rails/ActionMailer under a MIT-like licens [See rails ML, subject "Text::Format Licence Exception" on Oct 15, 2005] - -* Fix vendor require paths to prevent files being required twice - -* Don't add charset to content-type header for a part that contains subparts (for AOL compatibility) #2013 [John Long] - -* Preserve underscores when unquoting message bodies #1930 - -* Encode multibyte characters correctly #1894 - -* Multipart messages specify a MIME-Version header automatically #2003 [John Long] - -* Add a unified render method to ActionMailer (delegates to ActionView::Base#render) - -* Move mailer initialization to a separate (overridable) method, so that subclasses may alter the various defaults #1727 - -* Look at content-location header (if available) to determine filename of attachments #1670 - -* ActionMailer::Base.deliver(email) had been accidentally removed, but was documented in the Rails book #1849 - -* Fix problem with sendmail delivery where headers should be delimited by \n characters instead of \r\n, which confuses some mail readers #1742 [Kent Sibilev] - - -*1.0.1* (11 July, 2005) - -* Bind to Action Pack 1.9.1 - - -*1.0.0* (6 July, 2005) - -* Avoid adding nil header values #1392 - -* Better multipart support with implicit multipart/alternative and sorting of subparts [John Long] - -* Allow for nested parts in multipart mails #1570 [Flurin Egger] - -* Normalize line endings in outgoing mail bodies to "\n" #1536 [John Long] - -* Allow template to be explicitly specified #1448 [tuxie@dekadance.se] - -* Allow specific "multipart/xxx" content-type to be set on multipart messages #1412 [Flurin Egger] - -* Unquoted @ characters in headers are now accepted in spite of RFC 822 #1206 - -* Helper support (borrowed from ActionPack) - -* Silently ignore Errno::EINVAL errors when converting text. - -* Don't cause an error when parsing an encoded attachment name #1340 [lon@speedymac.com] - -* Nested multipart message parts are correctly processed in TMail::Mail#body - -* BCC headers are removed when sending via SMTP #1402 - -* Added 'content_type' accessor, to allow content type to be set on a per-message basis. content_type defaults to "text/plain". - -* Silently ignore Iconv::IllegalSequence errors when converting text #1341 [lon@speedymac.com] - -* Support attachments and multipart messages. - -* Added new accessors for the various mail properties. - -* Fix to only perform the charset conversion if a 'from' and a 'to' charset are given (make no assumptions about what the charset was) #1276 [Jamis Buck] - -* Fix attachments and content-type problems #1276 [Jamis Buck] - -* Fixed the TMail#body method to look at the content-transfer-encoding header and unquote the body according to the rules it specifies #1265 [Jamis Buck] - -* Added unquoting even if the iconv lib can't be loaded--in that case, only the charset conversion is skipped #1265 [Jamis Buck] - -* Added automatic decoding of base64 bodies #1214 [Jamis Buck] - -* Added that delivery errors are caught in a way so the mail is still returned whether the delivery was successful or not - -* Fixed that email address like "Jamis Buck, M.D." would cause the quoter to generate emails resulting in "bad address" errors from the mail server #1220 [Jamis Buck] - - -*0.9.1* (20th April, 2005) - -* Depend on Action Pack 1.8.1 - - -*0.9.0* (19th April, 2005) - -* Added that deliver_* will now return the email that was sent - -* Added that quoting to UTF-8 only happens if the characters used are in that range #955 [Jamis Buck] - -* Fixed quoting for all address headers, not just to #955 [Jamis Buck] - -* Fixed unquoting of emails that doesn't have an explicit charset #1036 [wolfgang@stufenlos.net] - - -*0.8.1* (27th March, 2005) - -* Fixed that if charset was found that the end of a mime part declaration TMail would throw an error #919 [lon@speedymac.com] - -* Fixed that TMail::Unquoter would fail to recognize quoting method if it was in lowercase #919 [lon@speedymac.com] - -* Fixed that TMail::Encoder would fail when it attempts to parse e-mail addresses which are encoded using something other than the messages encoding method #919 [lon@speedymac.com] - -* Added rescue for missing iconv library and throws warnings if subject/body is called on a TMail object without it instead - - -*0.8.0* (22th March, 2005) - -* Added framework support for processing incoming emails with an Action Mailer class. See example in README. - - -*0.7.1* (7th March, 2005) - -* Bind to newest Action Pack (1.5.1) - - -*0.7.0* (24th February, 2005) - -* Added support for charsets for both subject and body. The default charset is now UTF-8 #673 [Jamis Buck]. Examples: - - def iso_charset(recipient) - @recipients = recipient - @subject = "testing iso charsets" - @from = "system@loudthinking.com" - @body = "Nothing to see here." - @charset = "iso-8859-1" - end - - def unencoded_subject(recipient) - @recipients = recipient - @subject = "testing unencoded subject" - @from = "system@loudthinking.com" - @body = "Nothing to see here." - @encode_subject = false - @charset = "iso-8859-1" - end - - -*0.6.1* (January 18th, 2005) - -* Fixed sending of emails to use Tmail#from not the deprecated Tmail#from_address - - -*0.6* (January 17th, 2005) - -* Fixed that bcc and cc should be settable through @bcc and @cc -- not just @headers["Bcc"] and @headers["Cc"] #453 [Eric Hodel] - -* Fixed Action Mailer to be "warnings safe" so you can run with ruby -w and not get framework warnings #453 [Eric Hodel] - - -*0.5* - -* Added access to custom headers, like cc, bcc, and reply-to #268 [Andreas Schwarz]. Example: - - def post_notification(recipients, post) - @recipients = recipients - @from = post.author.email_address_with_name - @headers["bcc"] = SYSTEM_ADMINISTRATOR_EMAIL - @headers["reply-to"] = "notifications@example.com" - @subject = "[#{post.account.name} #{post.title}]" - @body["post"] = post - end - -*0.4* (5) - -* Consolidated the server configuration options into Base#server_settings= and expanded that with controls for authentication and more [Marten] - NOTE: This is an API change that could potentially break your application if you used the old application form. Please do change! - -* Added Base#deliveries as an accessor for an array of emails sent out through that ActionMailer class when using the :test delivery option. [Jeremy Kemper] - -* Added Base#perform_deliveries= which can be set to false to turn off the actual delivery of the email through smtp or sendmail. - This is especially useful for functional testing that shouldn't send off real emails, but still trigger delivery_* methods. - -* Added option to specify delivery method with Base#delivery_method=. Default is :smtp and :sendmail is currently the only other option. - Sendmail is assumed to be present at "/usr/sbin/sendmail" if that option is used. [Kent Sibilev] - -* Dropped "include TMail" as it added to much baggage into the default namespace (like Version) [Chad Fowler] - - -*0.3* - -* First release diff --git a/tracks/vendor/rails/actionmailer/MIT-LICENSE b/tracks/vendor/rails/actionmailer/MIT-LICENSE deleted file mode 100644 index 26f55e77..00000000 --- a/tracks/vendor/rails/actionmailer/MIT-LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -Copyright (c) 2004 David Heinemeier Hansson - -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 --git a/tracks/vendor/rails/actionmailer/README b/tracks/vendor/rails/actionmailer/README deleted file mode 100644 index 8c85e1ae..00000000 --- a/tracks/vendor/rails/actionmailer/README +++ /dev/null @@ -1,148 +0,0 @@ -= Action Mailer -- Easy email delivery and testing - -Action Mailer is a framework for designing email-service layers. These layers -are used to consolidate code for sending out forgotten passwords, welcoming -wishes on signup, invoices for billing, and any other use case that requires -a written notification to either a person or another system. - -Additionally, an Action Mailer class can be used to process incoming email, -such as allowing a weblog to accept new posts from an email (which could even -have been sent from a phone). - -== Sending emails - -The framework works by setting up all the email details, except the body, -in methods on the service layer. Subject, recipients, sender, and timestamp -are all set up this way. An example of such a method: - - def signed_up(recipient) - recipients recipient - subject "[Signed up] Welcome #{recipient}" - from "system@loudthinking.com" - - body(:recipient => recipient) - end - -The body of the email is created by using an Action View template (regular -ERb) that has the content of the body hash parameter available as instance variables. -So the corresponding body template for the method above could look like this: - - Hello there, - - Mr. <%= @recipient %> - -And if the recipient was given as "david@loudthinking.com", the email -generated would look like this: - - Date: Sun, 12 Dec 2004 00:00:00 +0100 - From: system@loudthinking.com - To: david@loudthinking.com - Subject: [Signed up] Welcome david@loudthinking.com - - Hello there, - - Mr. david@loudthinking.com - -You never actually call the instance methods like signed_up directly. Instead, -you call class methods like deliver_* and create_* that are automatically -created for each instance method. So if the signed_up method sat on -ApplicationMailer, it would look like this: - - ApplicationMailer.create_signed_up("david@loudthinking.com") # => tmail object for testing - ApplicationMailer.deliver_signed_up("david@loudthinking.com") # sends the email - ApplicationMailer.new.signed_up("david@loudthinking.com") # won't work! - -== Receiving emails - -To receive emails, you need to implement a public instance method called receive that takes a -tmail object as its single parameter. The Action Mailer framework has a corresponding class method, -which is also called receive, that accepts a raw, unprocessed email as a string, which it then turns -into the tmail object and calls the receive instance method. - -Example: - - class Mailman < ActionMailer::Base - def receive(email) - page = Page.find_by_address(email.to.first) - page.emails.create( - :subject => email.subject, :body => email.body - ) - - if email.has_attachments? - for attachment in email.attachments - page.attachments.create({ - :file => attachment, :description => email.subject - }) - end - end - end - end - -This Mailman can be the target for Postfix. In Rails, you would use the runner like this: - - ./script/runner 'Mailman.receive(STDIN.read)' - -== Configuration - -The Base class has the full list of configuration options. Here's an example: - -ActionMailer::Base.server_settings = { - :address=>'smtp.yourserver.com', # default: localhost - :port=>'25', # default: 25 - :user_name=>'user', - :password=>'pass', - :authentication=>:plain # :plain, :login or :cram_md5 -} - -== Dependencies - -Action Mailer requires that the Action Pack is either available to be required immediately -or is accessible as a GEM. - - -== Bundled software - -* tmail 0.10.8 by Minero Aoki released under LGPL - Read more on http://i.loveruby.net/en/prog/tmail.html - -* Text::Format 0.63 by Austin Ziegler released under OpenSource - Read more on http://www.halostatue.ca/ruby/Text__Format.html - - -== Download - -The latest version of Action Mailer can be found at - -* http://rubyforge.org/project/showfiles.php?group_id=361 - -Documentation can be found at - -* http://actionmailer.rubyonrails.org - - -== Installation - -You can install Action Mailer with the following command. - - % [sudo] ruby install.rb - -from its distribution directory. - - -== License - -Action Mailer is released under the MIT license. - - -== Support - -The Action Mailer homepage is http://actionmailer.rubyonrails.org. You can find -the Action Mailer RubyForge page at http://rubyforge.org/projects/actionmailer. -And as Jim from Rake says: - - Feel free to submit commits or feature requests. If you send a patch, - remember to update the corresponding unit tests. If fact, I prefer - new feature to be submitted in the form of new unit tests. - -For other information, feel free to ask on the ruby-talk mailing list (which -is mirrored to comp.lang.ruby) or contact mailto:david@loudthinking.com. diff --git a/tracks/vendor/rails/actionmailer/install.rb b/tracks/vendor/rails/actionmailer/install.rb deleted file mode 100644 index c559edff..00000000 --- a/tracks/vendor/rails/actionmailer/install.rb +++ /dev/null @@ -1,30 +0,0 @@ -require 'rbconfig' -require 'find' -require 'ftools' - -include Config - -# this was adapted from rdoc's install.rb by way of Log4r - -$sitedir = CONFIG["sitelibdir"] -unless $sitedir - version = CONFIG["MAJOR"] + "." + CONFIG["MINOR"] - $libdir = File.join(CONFIG["libdir"], "ruby", version) - $sitedir = $:.find {|x| x =~ /site_ruby/ } - if !$sitedir - $sitedir = File.join($libdir, "site_ruby") - elsif $sitedir !~ Regexp.quote(version) - $sitedir = File.join($sitedir, version) - end -end - -# the acual gruntwork -Dir.chdir("lib") - -Find.find("action_mailer", "action_mailer.rb") { |f| - if f[-3..-1] == ".rb" - File::install(f, File.join($sitedir, *f.split(/\//)), 0644, true) - else - File::makedirs(File.join($sitedir, *f.split(/\//))) - end -} diff --git a/tracks/vendor/rails/actionmailer/lib/action_mailer.rb b/tracks/vendor/rails/actionmailer/lib/action_mailer.rb deleted file mode 100644 index a489e32b..00000000 --- a/tracks/vendor/rails/actionmailer/lib/action_mailer.rb +++ /dev/null @@ -1,51 +0,0 @@ -#-- -# Copyright (c) 2004 David Heinemeier Hansson -# -# 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. -#++ - -begin - require 'action_controller' -rescue LoadError - begin - require File.dirname(__FILE__) + '/../../actionpack/lib/action_controller' - rescue LoadError - require 'rubygems' - require_gem 'actionpack', '>= 1.9.1' - end -end - -$:.unshift(File.dirname(__FILE__) + "/action_mailer/vendor/") - -require 'action_mailer/base' -require 'action_mailer/helpers' -require 'action_mailer/mail_helper' -require 'action_mailer/quoting' -require 'tmail' -require 'net/smtp' - -ActionMailer::Base.class_eval do - include ActionMailer::Quoting - include ActionMailer::Helpers - - helper MailHelper -end - -silence_warnings { TMail::Encoder.const_set("MAX_LINE_LEN", 200) } \ No newline at end of file diff --git a/tracks/vendor/rails/actionmailer/lib/action_mailer/adv_attr_accessor.rb b/tracks/vendor/rails/actionmailer/lib/action_mailer/adv_attr_accessor.rb deleted file mode 100644 index a8b83c5e..00000000 --- a/tracks/vendor/rails/actionmailer/lib/action_mailer/adv_attr_accessor.rb +++ /dev/null @@ -1,27 +0,0 @@ -module ActionMailer - module AdvAttrAccessor #:nodoc: - def self.append_features(base) - super - base.extend(ClassMethods) - end - - module ClassMethods #:nodoc: - def adv_attr_accessor(*names) - names.each do |name| - define_method("#{name}=") do |value| - instance_variable_set("@#{name}", value) - end - - define_method(name) do |*parameters| - raise ArgumentError, "expected 0 or 1 parameters" unless parameters.length <= 1 - if parameters.empty? - instance_variable_get("@#{name}") - else - instance_variable_set("@#{name}", parameters.first) - end - end - end - end - end - end -end diff --git a/tracks/vendor/rails/actionmailer/lib/action_mailer/base.rb b/tracks/vendor/rails/actionmailer/lib/action_mailer/base.rb deleted file mode 100644 index cc996790..00000000 --- a/tracks/vendor/rails/actionmailer/lib/action_mailer/base.rb +++ /dev/null @@ -1,453 +0,0 @@ -require 'action_mailer/adv_attr_accessor' -require 'action_mailer/part' -require 'action_mailer/part_container' -require 'action_mailer/utils' -require 'tmail/net' - -module ActionMailer - # Usage: - # - # class ApplicationMailer < ActionMailer::Base - # # Set up properties - # # Properties can also be specified via accessor methods - # # (i.e. self.subject = "foo") and instance variables (@subject = "foo"). - # def signup_notification(recipient) - # recipients recipient.email_address_with_name - # subject "New account information" - # body { "account" => recipient } - # from "system@example.com" - # end - # - # # explicitly specify multipart messages - # def signup_notification(recipient) - # recipients recipient.email_address_with_name - # subject "New account information" - # from "system@example.com" - # - # part :content_type => "text/html", - # :body => render_message("signup-as-html", :account => recipient) - # - # part "text/plain" do |p| - # p.body = render_message("signup-as-plain", :account => recipient) - # p.transfer_encoding = "base64" - # end - # end - # - # # attachments - # def signup_notification(recipient) - # recipients recipient.email_address_with_name - # subject "New account information" - # from "system@example.com" - # - # attachment :content_type => "image/jpeg", - # :body => File.read("an-image.jpg") - # - # attachment "application/pdf" do |a| - # a.body = generate_your_pdf_here() - # end - # end - # - # # implicitly multipart messages - # def signup_notification(recipient) - # recipients recipient.email_address_with_name - # subject "New account information" - # from "system@example.com" - # body(:account => "recipient") - # - # # ActionMailer will automatically detect and use multipart templates, - # # where each template is named after the name of the action, followed - # # by the content type. Each such detected template will be added as - # # a separate part to the message. - # # - # # for example, if the following templates existed: - # # * signup_notification.text.plain.rhtml - # # * signup_notification.text.html.rhtml - # # * signup_notification.text.xml.rxml - # # * signup_notification.text.x-yaml.rhtml - # # - # # Each would be rendered and added as a separate part to the message, - # # with the corresponding content type. The same body hash is passed to - # # each template. - # end - # end - # - # # After this, post_notification will look for "templates/application_mailer/post_notification.rhtml" - # ApplicationMailer.template_root = "templates" - # - # ApplicationMailer.create_comment_notification(david, hello_world) # => a tmail object - # ApplicationMailer.deliver_comment_notification(david, hello_world) # sends the email - # - # = Configuration options - # - # These options are specified on the class level, like ActionMailer::Base.template_root = "/my/templates" - # - # * template_root - template root determines the base from which template references will be made. - # - # * logger - the logger is used for generating information on the mailing run if available. - # Can be set to nil for no logging. Compatible with both Ruby's own Logger and Log4r loggers. - # - # * server_settings - Allows detailed configuration of the server: - # * :address Allows you to use a remote mail server. Just change it from its default "localhost" setting. - # * :port On the off chance that your mail server doesn't run on port 25, you can change it. - # * :domain If you need to specify a HELO domain, you can do it here. - # * :user_name If your mail server requires authentication, set the username in this setting. - # * :password If your mail server requires authentication, set the password in this setting. - # * :authentication If your mail server requires authentication, you need to specify the authentication type here. - # This is a symbol and one of :plain, :login, :cram_md5 - # - # * raise_delivery_errors - whether or not errors should be raised if the email fails to be delivered. - # - # * delivery_method - Defines a delivery method. Possible values are :smtp (default), :sendmail, and :test. - # Sendmail is assumed to be present at "/usr/sbin/sendmail". - # - # * perform_deliveries - Determines whether deliver_* methods are actually carried out. By default they are, - # but this can be turned off to help functional testing. - # - # * deliveries - Keeps an array of all the emails sent out through the Action Mailer with delivery_method :test. Most useful - # for unit and functional testing. - # - # * default_charset - The default charset used for the body and to encode the subject. Defaults to UTF-8. You can also - # pick a different charset from inside a method with @charset. - # * default_content_type - The default content type used for the main part of the message. Defaults to "text/plain". You - # can also pick a different content type from inside a method with @content_type. - # * default_mime_version - The default mime version used for the message. Defaults to nil. You - # can also pick a different value from inside a method with @mime_version. When multipart messages are in - # use, @mime_version will be set to "1.0" if it is not set inside a method. - # * default_implicit_parts_order - When a message is built implicitly (i.e. multiple parts are assembled from templates - # which specify the content type in their filenames) this variable controls how the parts are ordered. Defaults to - # ["text/html", "text/enriched", "text/plain"]. Items that appear first in the array have higher priority in the mail client - # and appear last in the mime encoded message. You can also pick a different order from inside a method with - # @implicit_parts_order. - class Base - include AdvAttrAccessor, PartContainer - - private_class_method :new #:nodoc: - - cattr_accessor :template_root - cattr_accessor :logger - - @@server_settings = { - :address => "localhost", - :port => 25, - :domain => 'localhost.localdomain', - :user_name => nil, - :password => nil, - :authentication => nil - } - cattr_accessor :server_settings - - @@raise_delivery_errors = true - cattr_accessor :raise_delivery_errors - - @@delivery_method = :smtp - cattr_accessor :delivery_method - - @@perform_deliveries = true - cattr_accessor :perform_deliveries - - @@deliveries = [] - cattr_accessor :deliveries - - @@default_charset = "utf-8" - cattr_accessor :default_charset - - @@default_content_type = "text/plain" - cattr_accessor :default_content_type - - @@default_mime_version = nil - cattr_accessor :default_mime_version - - @@default_implicit_parts_order = [ "text/html", "text/enriched", "text/plain" ] - cattr_accessor :default_implicit_parts_order - - # Specify the BCC addresses for the message - adv_attr_accessor :bcc - - # Define the body of the message. This is either a Hash (in which case it - # specifies the variables to pass to the template when it is rendered), - # or a string, in which case it specifies the actual text of the message. - adv_attr_accessor :body - - # Specify the CC addresses for the message. - adv_attr_accessor :cc - - # Specify the charset to use for the message. This defaults to the - # +default_charset+ specified for ActionMailer::Base. - adv_attr_accessor :charset - - # Specify the content type for the message. This defaults to text/plain - # in most cases, but can be automatically set in some situations. - adv_attr_accessor :content_type - - # Specify the from address for the message. - adv_attr_accessor :from - - # Specify additional headers to be added to the message. - adv_attr_accessor :headers - - # Specify the order in which parts should be sorted, based on content-type. - # This defaults to the value for the +default_implicit_parts_order+. - adv_attr_accessor :implicit_parts_order - - # Override the mailer name, which defaults to an inflected version of the - # mailer's class name. If you want to use a template in a non-standard - # location, you can use this to specify that location. - adv_attr_accessor :mailer_name - - # Defaults to "1.0", but may be explicitly given if needed. - adv_attr_accessor :mime_version - - # The recipient addresses for the message, either as a string (for a single - # address) or an array (for multiple addresses). - adv_attr_accessor :recipients - - # The date on which the message was sent. If not set (the default), the - # header will be set by the delivery agent. - adv_attr_accessor :sent_on - - # Specify the subject of the message. - adv_attr_accessor :subject - - # Specify the template name to use for current message. This is the "base" - # template name, without the extension or directory, and may be used to - # have multiple mailer methods share the same template. - adv_attr_accessor :template - - # The mail object instance referenced by this mailer. - attr_reader :mail - - class << self - def method_missing(method_symbol, *parameters)#:nodoc: - case method_symbol.id2name - when /^create_([_a-z]\w*)/ then new($1, *parameters).mail - when /^deliver_([_a-z]\w*)/ then new($1, *parameters).deliver! - when "new" then nil - else super - end - end - - # Receives a raw email, parses it into an email object, decodes it, - # instantiates a new mailer, and passes the email object to the mailer - # object's #receive method. If you want your mailer to be able to - # process incoming messages, you'll need to implement a #receive - # method that accepts the email object as a parameter: - # - # class MyMailer < ActionMailer::Base - # def receive(mail) - # ... - # end - # end - def receive(raw_email) - logger.info "Received mail:\n #{raw_email}" unless logger.nil? - mail = TMail::Mail.parse(raw_email) - mail.base64_decode - new.receive(mail) - end - - # Deliver the given mail object directly. This can be used to deliver - # a preconstructed mail object, like: - # - # email = MyMailer.create_some_mail(parameters) - # email.set_some_obscure_header "frobnicate" - # MyMailer.deliver(email) - def deliver(mail) - new.deliver!(mail) - end - end - - # Instantiate a new mailer object. If +method_name+ is not +nil+, the mailer - # will be initialized according to the named method. If not, the mailer will - # remain uninitialized (useful when you only need to invoke the "receive" - # method, for instance). - def initialize(method_name=nil, *parameters) #:nodoc: - create!(method_name, *parameters) if method_name - end - - # Initialize the mailer via the given +method_name+. The body will be - # rendered and a new TMail::Mail object created. - def create!(method_name, *parameters) #:nodoc: - initialize_defaults(method_name) - send(method_name, *parameters) - - # If an explicit, textual body has not been set, we check assumptions. - unless String === @body - # First, we look to see if there are any likely templates that match, - # which include the content-type in their file name (i.e., - # "the_template_file.text.html.rhtml", etc.). Only do this if parts - # have not already been specified manually. - if @parts.empty? - templates = Dir.glob("#{template_path}/#{@template}.*") - templates.each do |path| - type = (File.basename(path).split(".")[1..-2] || []).join("/") - next if type.empty? - @parts << Part.new(:content_type => type, - :disposition => "inline", :charset => charset, - :body => render_message(File.basename(path).split(".")[0..-2].join('.'), @body)) - end - unless @parts.empty? - @content_type = "multipart/alternative" - @charset = nil - @parts = sort_parts(@parts, @implicit_parts_order) - end - end - - # Then, if there were such templates, we check to see if we ought to - # also render a "normal" template (without the content type). If a - # normal template exists (or if there were no implicit parts) we render - # it. - template_exists = @parts.empty? - template_exists ||= Dir.glob("#{template_path}/#{@template}.*").any? { |i| i.split(".").length == 2 } - @body = render_message(@template, @body) if template_exists - - # Finally, if there are other message parts and a textual body exists, - # we shift it onto the front of the parts and set the body to nil (so - # that create_mail doesn't try to render it in addition to the parts). - if !@parts.empty? && String === @body - @parts.unshift Part.new(:charset => charset, :body => @body) - @body = nil - end - end - - # If this is a multipart e-mail add the mime_version if it is not - # already set. - @mime_version ||= "1.0" if !@parts.empty? - - # build the mail object itself - @mail = create_mail - end - - # Delivers a TMail::Mail object. By default, it delivers the cached mail - # object (from the #create! method). If no cached mail object exists, and - # no alternate has been given as the parameter, this will fail. - def deliver!(mail = @mail) - raise "no mail object available for delivery!" unless mail - logger.info "Sent mail:\n #{mail.encoded}" unless logger.nil? - - begin - send("perform_delivery_#{delivery_method}", mail) if perform_deliveries - rescue Object => e - raise e if raise_delivery_errors - end - - return mail - end - - private - # Set up the default values for the various instance variables of this - # mailer. Subclasses may override this method to provide different - # defaults. - def initialize_defaults(method_name) - @charset ||= @@default_charset.dup - @content_type ||= @@default_content_type.dup - @implicit_parts_order ||= @@default_implicit_parts_order.dup - @template ||= method_name - @mailer_name ||= Inflector.underscore(self.class.name) - @parts ||= [] - @headers ||= {} - @body ||= {} - @mime_version = @@default_mime_version.dup if @@default_mime_version - end - - def render_message(method_name, body) - render :file => method_name, :body => body - end - - def render(opts) - body = opts.delete(:body) - initialize_template_class(body).render(opts) - end - - def template_path - "#{template_root}/#{mailer_name}" - end - - def initialize_template_class(assigns) - ActionView::Base.new(template_path, assigns, self) - end - - def sort_parts(parts, order = []) - order = order.collect { |s| s.downcase } - - parts = parts.sort do |a, b| - a_ct = a.content_type.downcase - b_ct = b.content_type.downcase - - a_in = order.include? a_ct - b_in = order.include? b_ct - - s = case - when a_in && b_in - order.index(a_ct) <=> order.index(b_ct) - when a_in - -1 - when b_in - 1 - else - a_ct <=> b_ct - end - - # reverse the ordering because parts that come last are displayed - # first in mail clients - (s * -1) - end - - parts - end - - def create_mail - m = TMail::Mail.new - - m.subject, = quote_any_if_necessary(charset, subject) - m.to, m.from = quote_any_address_if_necessary(charset, recipients, from) - m.bcc = quote_address_if_necessary(bcc, charset) unless bcc.nil? - m.cc = quote_address_if_necessary(cc, charset) unless cc.nil? - - m.mime_version = mime_version unless mime_version.nil? - m.date = sent_on.to_time rescue sent_on if sent_on - headers.each { |k, v| m[k] = v } - - if @parts.empty? - m.set_content_type content_type, nil, { "charset" => charset } - m.body = Utils.normalize_new_lines(body) - else - if String === body - part = TMail::Mail.new - part.body = Utils.normalize_new_lines(body) - part.set_content_type content_type, nil, { "charset" => charset } - part.set_content_disposition "inline" - m.parts << part - end - - @parts.each do |p| - part = (TMail::Mail === p ? p : p.to_mail(self)) - m.parts << part - end - - m.set_content_type(content_type, nil, { "charset" => charset }) if content_type =~ /multipart/ - end - - @mail = m - end - - def perform_delivery_smtp(mail) - destinations = mail.destinations - mail.ready_to_send - - Net::SMTP.start(server_settings[:address], server_settings[:port], server_settings[:domain], - server_settings[:user_name], server_settings[:password], server_settings[:authentication]) do |smtp| - smtp.sendmail(mail.encoded, mail.from, destinations) - end - end - - def perform_delivery_sendmail(mail) - IO.popen("/usr/sbin/sendmail -i -t","w+") do |sm| - sm.print(mail.encoded.gsub(/\r/, '')) - sm.flush - end - end - - def perform_delivery_test(mail) - deliveries << mail - end - end -end diff --git a/tracks/vendor/rails/actionmailer/lib/action_mailer/helpers.rb b/tracks/vendor/rails/actionmailer/lib/action_mailer/helpers.rb deleted file mode 100644 index b53326ca..00000000 --- a/tracks/vendor/rails/actionmailer/lib/action_mailer/helpers.rb +++ /dev/null @@ -1,115 +0,0 @@ -module ActionMailer - module Helpers #:nodoc: - def self.append_features(base) #:nodoc: - super - - # Initialize the base module to aggregate its helpers. - base.class_inheritable_accessor :master_helper_module - base.master_helper_module = Module.new - - # Extend base with class methods to declare helpers. - base.extend(ClassMethods) - - base.class_eval do - # Wrap inherited to create a new master helper module for subclasses. - class << self - alias_method :inherited_without_helper, :inherited - alias_method :inherited, :inherited_with_helper - end - - # Wrap initialize_template_class to extend new template class - # instances with the master helper module. - alias_method :initialize_template_class_without_helper, :initialize_template_class - alias_method :initialize_template_class, :initialize_template_class_with_helper - end - end - - module ClassMethods - # Makes all the (instance) methods in the helper module available to templates rendered through this controller. - # See ActionView::Helpers (link:classes/ActionView/Helpers.html) for more about making your own helper modules - # available to the templates. - def add_template_helper(helper_module) #:nodoc: - master_helper_module.module_eval "include #{helper_module}" - end - - # Declare a helper: - # helper :foo - # requires 'foo_helper' and includes FooHelper in the template class. - # helper FooHelper - # includes FooHelper in the template class. - # helper { def foo() "#{bar} is the very best" end } - # evaluates the block in the template class, adding method #foo. - # helper(:three, BlindHelper) { def mice() 'mice' end } - # does all three. - def helper(*args, &block) - args.flatten.each do |arg| - case arg - when Module - add_template_helper(arg) - when String, Symbol - file_name = arg.to_s.underscore + '_helper' - class_name = file_name.camelize - - begin - require_dependency(file_name) - rescue LoadError => load_error - requiree = / -- (.*?)(\.rb)?$/.match(load_error).to_a[1] - msg = (requiree == file_name) ? "Missing helper file helpers/#{file_name}.rb" : "Can't load file: #{requiree}" - raise LoadError.new(msg).copy_blame!(load_error) - end - - add_template_helper(class_name.constantize) - else - raise ArgumentError, 'helper expects String, Symbol, or Module argument' - end - end - - # Evaluate block in template class if given. - master_helper_module.module_eval(&block) if block_given? - end - - # Declare a controller method as a helper. For example, - # helper_method :link_to - # def link_to(name, options) ... end - # makes the link_to controller method available in the view. - def helper_method(*methods) - methods.flatten.each do |method| - master_helper_module.module_eval <<-end_eval - def #{method}(*args, &block) - controller.send(%(#{method}), *args, &block) - end - end_eval - end - end - - # Declare a controller attribute as a helper. For example, - # helper_attr :name - # attr_accessor :name - # makes the name and name= controller methods available in the view. - # The is a convenience wrapper for helper_method. - def helper_attr(*attrs) - attrs.flatten.each { |attr| helper_method(attr, "#{attr}=") } - end - - private - def inherited_with_helper(child) - inherited_without_helper(child) - begin - child.master_helper_module = Module.new - child.master_helper_module.send :include, master_helper_module - child.helper child.name.underscore - rescue MissingSourceFile => e - raise unless e.is_missing?("helpers/#{child.name.underscore}_helper") - end - end - end - - private - # Extend the template class instance with our controller's helper module. - def initialize_template_class_with_helper(assigns) - returning(template = initialize_template_class_without_helper(assigns)) do - template.extend self.class.master_helper_module - end - end - end -end \ No newline at end of file diff --git a/tracks/vendor/rails/actionmailer/lib/action_mailer/mail_helper.rb b/tracks/vendor/rails/actionmailer/lib/action_mailer/mail_helper.rb deleted file mode 100644 index 11fd7d77..00000000 --- a/tracks/vendor/rails/actionmailer/lib/action_mailer/mail_helper.rb +++ /dev/null @@ -1,19 +0,0 @@ -require 'text/format' - -module MailHelper - # Uses Text::Format to take the text and format it, indented two spaces for - # each line, and wrapped at 72 columns. - def block_format(text) - formatted = text.split(/\n\r\n/).collect { |paragraph| - Text::Format.new( - :columns => 72, :first_indent => 2, :body_indent => 2, :text => paragraph - ).format - }.join("\n") - - # Make list points stand on their own line - formatted.gsub!(/[ ]*([*]+) ([^*]*)/) { |s| " #{$1} #{$2.strip}\n" } - formatted.gsub!(/[ ]*([#]+) ([^#]*)/) { |s| " #{$1} #{$2.strip}\n" } - - formatted - end -end diff --git a/tracks/vendor/rails/actionmailer/lib/action_mailer/part.rb b/tracks/vendor/rails/actionmailer/lib/action_mailer/part.rb deleted file mode 100644 index 0036d04d..00000000 --- a/tracks/vendor/rails/actionmailer/lib/action_mailer/part.rb +++ /dev/null @@ -1,108 +0,0 @@ -require 'action_mailer/adv_attr_accessor' -require 'action_mailer/part_container' -require 'action_mailer/utils' - -module ActionMailer - # Represents a subpart of an email message. It shares many similar - # attributes of ActionMailer::Base. Although you can create parts manually - # and add them to the #parts list of the mailer, it is easier - # to use the helper methods in ActionMailer::PartContainer. - class Part - include ActionMailer::AdvAttrAccessor - include ActionMailer::PartContainer - - # Represents the body of the part, as a string. This should not be a - # Hash (like ActionMailer::Base), but if you want a template to be rendered - # into the body of a subpart you can do it with the mailer's #render method - # and assign the result here. - adv_attr_accessor :body - - # Specify the charset for this subpart. By default, it will be the charset - # of the containing part or mailer. - adv_attr_accessor :charset - - # The content disposition of this part, typically either "inline" or - # "attachment". - adv_attr_accessor :content_disposition - - # The content type of the part. - adv_attr_accessor :content_type - - # The filename to use for this subpart (usually for attachments). - adv_attr_accessor :filename - - # Accessor for specifying additional headers to include with this part. - adv_attr_accessor :headers - - # The transfer encoding to use for this subpart, like "base64" or - # "quoted-printable". - adv_attr_accessor :transfer_encoding - - # Create a new part from the given +params+ hash. The valid params keys - # correspond to the accessors. - def initialize(params) - @content_type = params[:content_type] - @content_disposition = params[:disposition] || "inline" - @charset = params[:charset] - @body = params[:body] - @filename = params[:filename] - @transfer_encoding = params[:transfer_encoding] || "quoted-printable" - @headers = params[:headers] || {} - @parts = [] - end - - # Convert the part to a mail object which can be included in the parts - # list of another mail object. - def to_mail(defaults) - part = TMail::Mail.new - - if @parts.empty? - part.content_transfer_encoding = transfer_encoding || "quoted-printable" - case (transfer_encoding || "").downcase - when "base64" then - part.body = TMail::Base64.folding_encode(body) - when "quoted-printable" - part.body = [Utils.normalize_new_lines(body)].pack("M*") - else - part.body = body - end - - # Always set the content_type after setting the body and or parts! - # Also don't set filename and name when there is none (like in - # non-attachment parts) - if content_disposition == "attachment" - part.set_content_type(content_type || defaults.content_type, nil, - squish("charset" => nil, "name" => filename)) - part.set_content_disposition(content_disposition, - squish("filename" => filename)) - else - part.set_content_type(content_type || defaults.content_type, nil, - "charset" => (charset || defaults.charset)) - part.set_content_disposition(content_disposition) - end - else - if String === body - part = TMail::Mail.new - part.body = body - part.set_content_type content_type, nil, { "charset" => charset } - part.set_content_disposition "inline" - m.parts << part - end - - @parts.each do |p| - prt = (TMail::Mail === p ? p : p.to_mail(defaults)) - part.parts << prt - end - - part.set_content_type(content_type, nil, { "charset" => charset }) if content_type =~ /multipart/ - end - - part - end - - private - def squish(values={}) - values.delete_if { |k,v| v.nil? } - end - end -end diff --git a/tracks/vendor/rails/actionmailer/lib/action_mailer/part_container.rb b/tracks/vendor/rails/actionmailer/lib/action_mailer/part_container.rb deleted file mode 100644 index 6199fe0b..00000000 --- a/tracks/vendor/rails/actionmailer/lib/action_mailer/part_container.rb +++ /dev/null @@ -1,42 +0,0 @@ -module ActionMailer - # Accessors and helpers that ActionMailer::Base and ActionMailer::Part have - # in common. Using these helpers you can easily add subparts or attachments - # to your message: - # - # def my_mail_message(...) - # ... - # part "text/plain" do |p| - # p.body "hello, world" - # p.transfer_encoding "base64" - # end - # - # attachment "image/jpg" do |a| - # a.body = File.read("hello.jpg") - # a.filename = "hello.jpg" - # end - # end - module PartContainer - # The list of subparts of this container - attr_reader :parts - - # Add a part to a multipart message, with the given content-type. The - # part itself is yielded to the block so that other properties (charset, - # body, headers, etc.) can be set on it. - def part(params) - params = {:content_type => params} if String === params - part = Part.new(params) - yield part if block_given? - @parts << part - end - - # Add an attachment to a multipart message. This is simply a part with the - # content-disposition set to "attachment". - def attachment(params, &block) - params = { :content_type => params } if String === params - params = { :disposition => "attachment", - :transfer_encoding => "base64" }.merge(params) - part(params, &block) - end - - end -end diff --git a/tracks/vendor/rails/actionmailer/lib/action_mailer/quoting.rb b/tracks/vendor/rails/actionmailer/lib/action_mailer/quoting.rb deleted file mode 100644 index d6e04e4d..00000000 --- a/tracks/vendor/rails/actionmailer/lib/action_mailer/quoting.rb +++ /dev/null @@ -1,59 +0,0 @@ -module ActionMailer - module Quoting #:nodoc: - # Convert the given text into quoted printable format, with an instruction - # that the text be eventually interpreted in the given charset. - def quoted_printable(text, charset) - text = text.gsub( /[^a-z ]/i ) { quoted_printable_encode($&) }. - gsub( / /, "_" ) - "=?#{charset}?Q?#{text}?=" - end - - # Convert the given character to quoted printable format, taking into - # account multi-byte characters (if executing with $KCODE="u", for instance) - def quoted_printable_encode(character) - result = "" - character.each_byte { |b| result << "=%02x" % b } - result - end - - # A quick-and-dirty regexp for determining whether a string contains any - # characters that need escaping. - if !defined?(CHARS_NEEDING_QUOTING) - CHARS_NEEDING_QUOTING = /[\000-\011\013\014\016-\037\177-\377]/ - end - - # Quote the given text if it contains any "illegal" characters - def quote_if_necessary(text, charset) - (text =~ CHARS_NEEDING_QUOTING) ? - quoted_printable(text, charset) : - text - end - - # Quote any of the given strings if they contain any "illegal" characters - def quote_any_if_necessary(charset, *args) - args.map { |v| quote_if_necessary(v, charset) } - end - - # Quote the given address if it needs to be. The address may be a - # regular email address, or it can be a phrase followed by an address in - # brackets. The phrase is the only part that will be quoted, and only if - # it needs to be. This allows extended characters to be used in the - # "to", "from", "cc", and "bcc" headers. - def quote_address_if_necessary(address, charset) - if Array === address - address.map { |a| quote_address_if_necessary(a, charset) } - elsif address =~ /^(\S.*)\s+(<.*>)$/ - address = $2 - phrase = quote_if_necessary($1.gsub(/^['"](.*)['"]$/, '\1'), charset) - "\"#{phrase}\" #{address}" - else - address - end - end - - # Quote any of the given addresses, if they need to be. - def quote_any_address_if_necessary(charset, *args) - args.map { |v| quote_address_if_necessary(v, charset) } - end - end -end diff --git a/tracks/vendor/rails/actionmailer/lib/action_mailer/utils.rb b/tracks/vendor/rails/actionmailer/lib/action_mailer/utils.rb deleted file mode 100644 index 552f695a..00000000 --- a/tracks/vendor/rails/actionmailer/lib/action_mailer/utils.rb +++ /dev/null @@ -1,8 +0,0 @@ -module ActionMailer - module Utils #:nodoc: - def normalize_new_lines(text) - text.to_s.gsub(/\r\n?/, "\n") - end - module_function :normalize_new_lines - end -end diff --git a/tracks/vendor/rails/actionmailer/lib/action_mailer/vendor/text/format.rb b/tracks/vendor/rails/actionmailer/lib/action_mailer/vendor/text/format.rb deleted file mode 100644 index de054db8..00000000 --- a/tracks/vendor/rails/actionmailer/lib/action_mailer/vendor/text/format.rb +++ /dev/null @@ -1,1466 +0,0 @@ -#-- -# Text::Format for Ruby -# Version 0.63 -# -# Copyright (c) 2002 - 2003 Austin Ziegler -# -# $Id: format.rb,v 1.1.1.1 2004/10/14 11:59:57 webster132 Exp $ -# -# ========================================================================== -# Revision History :: -# YYYY.MM.DD Change ID Developer -# Description -# -------------------------------------------------------------------------- -# 2002.10.18 Austin Ziegler -# Fixed a minor problem with tabs not being counted. Changed -# abbreviations from Hash to Array to better suit Ruby's -# capabilities. Fixed problems with the way that Array arguments -# are handled in calls to the major object types, excepting in -# Text::Format#expand and Text::Format#unexpand (these will -# probably need to be fixed). -# 2002.10.30 Austin Ziegler -# Fixed the ordering of the <=> for binary tests. Fixed -# Text::Format#expand and Text::Format#unexpand to handle array -# arguments better. -# 2003.01.24 Austin Ziegler -# Fixed a problem with Text::Format::RIGHT_FILL handling where a -# single word is larger than #columns. Removed Comparable -# capabilities (<=> doesn't make sense; == does). Added Symbol -# equivalents for the Hash initialization. Hash initialization has -# been modified so that values are set as follows (Symbols are -# highest priority; strings are middle; defaults are lowest): -# @columns = arg[:columns] || arg['columns'] || @columns -# Added #hard_margins, #split_rules, #hyphenator, and #split_words. -# 2003.02.07 Austin Ziegler -# Fixed the installer for proper case-sensitive handling. -# 2003.03.28 Austin Ziegler -# Added the ability for a hyphenator to receive the formatter -# object. Fixed a bug for strings matching /\A\s*\Z/ failing -# entirely. Fixed a test case failing under 1.6.8. -# 2003.04.04 Austin Ziegler -# Handle the case of hyphenators returning nil for first/rest. -# 2003.09.17 Austin Ziegler -# Fixed a problem where #paragraphs(" ") was raising -# NoMethodError. -# -# ========================================================================== -#++ - -module Text #:nodoc: - # Text::Format for Ruby is copyright 2002 - 2005 by Austin Ziegler. It - # is available under Ruby's licence, the Perl Artistic licence, or the - # GNU GPL version 2 (or at your option, any later version). As a - # special exception, for use with official Rails (provided by the - # rubyonrails.org development team) and any project created with - # official Rails, the following alternative MIT-style licence may be - # used: - # - # == Text::Format Licence for Rails and Rails Applications - # 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 names of its contributors may not be used to endorse or - # promote products derived from this software without specific prior - # written permission. - # - # 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. - class Format - VERSION = '0.63' - - # Local abbreviations. More can be added with Text::Format.abbreviations - ABBREV = [ 'Mr', 'Mrs', 'Ms', 'Jr', 'Sr' ] - - # Formatting values - LEFT_ALIGN = 0 - RIGHT_ALIGN = 1 - RIGHT_FILL = 2 - JUSTIFY = 3 - - # Word split modes (only applies when #hard_margins is true). - SPLIT_FIXED = 1 - SPLIT_CONTINUATION = 2 - SPLIT_HYPHENATION = 4 - SPLIT_CONTINUATION_FIXED = SPLIT_CONTINUATION | SPLIT_FIXED - SPLIT_HYPHENATION_FIXED = SPLIT_HYPHENATION | SPLIT_FIXED - SPLIT_HYPHENATION_CONTINUATION = SPLIT_HYPHENATION | SPLIT_CONTINUATION - SPLIT_ALL = SPLIT_HYPHENATION | SPLIT_CONTINUATION | SPLIT_FIXED - - # Words forcibly split by Text::Format will be stored as split words. - # This class represents a word forcibly split. - class SplitWord - # The word that was split. - attr_reader :word - # The first part of the word that was split. - attr_reader :first - # The remainder of the word that was split. - attr_reader :rest - - def initialize(word, first, rest) #:nodoc: - @word = word - @first = first - @rest = rest - end - end - - private - LEQ_RE = /[.?!]['"]?$/ - - def brk_re(i) #:nodoc: - %r/((?:\S+\s+){#{i}})(.+)/ - end - - def posint(p) #:nodoc: - p.to_i.abs - end - - public - # Compares two Text::Format objects. All settings of the objects are - # compared *except* #hyphenator. Generated results (e.g., #split_words) - # are not compared, either. - def ==(o) - (@text == o.text) && - (@columns == o.columns) && - (@left_margin == o.left_margin) && - (@right_margin == o.right_margin) && - (@hard_margins == o.hard_margins) && - (@split_rules == o.split_rules) && - (@first_indent == o.first_indent) && - (@body_indent == o.body_indent) && - (@tag_text == o.tag_text) && - (@tabstop == o.tabstop) && - (@format_style == o.format_style) && - (@extra_space == o.extra_space) && - (@tag_paragraph == o.tag_paragraph) && - (@nobreak == o.nobreak) && - (@abbreviations == o.abbreviations) && - (@nobreak_regex == o.nobreak_regex) - end - - # The text to be manipulated. Note that value is optional, but if the - # formatting functions are called without values, this text is what will - # be formatted. - # - # *Default*:: [] - # Used in:: All methods - attr_accessor :text - - # The total width of the format area. The margins, indentation, and text - # are formatted into this space. - # - # COLUMNS - # <--------------------------------------------------------------> - # <-----------><------><---------------------------><------------> - # left margin indent text is formatted into here right margin - # - # *Default*:: 72 - # Used in:: #format, #paragraphs, - # #center - attr_reader :columns - - # The total width of the format area. The margins, indentation, and text - # are formatted into this space. The value provided is silently - # converted to a positive integer. - # - # COLUMNS - # <--------------------------------------------------------------> - # <-----------><------><---------------------------><------------> - # left margin indent text is formatted into here right margin - # - # *Default*:: 72 - # Used in:: #format, #paragraphs, - # #center - def columns=(c) - @columns = posint(c) - end - - # The number of spaces used for the left margin. - # - # columns - # <--------------------------------------------------------------> - # <-----------><------><---------------------------><------------> - # LEFT MARGIN indent text is formatted into here right margin - # - # *Default*:: 0 - # Used in:: #format, #paragraphs, - # #center - attr_reader :left_margin - - # The number of spaces used for the left margin. The value provided is - # silently converted to a positive integer value. - # - # columns - # <--------------------------------------------------------------> - # <-----------><------><---------------------------><------------> - # LEFT MARGIN indent text is formatted into here right margin - # - # *Default*:: 0 - # Used in:: #format, #paragraphs, - # #center - def left_margin=(left) - @left_margin = posint(left) - end - - # The number of spaces used for the right margin. - # - # columns - # <--------------------------------------------------------------> - # <-----------><------><---------------------------><------------> - # left margin indent text is formatted into here RIGHT MARGIN - # - # *Default*:: 0 - # Used in:: #format, #paragraphs, - # #center - attr_reader :right_margin - - # The number of spaces used for the right margin. The value provided is - # silently converted to a positive integer value. - # - # columns - # <--------------------------------------------------------------> - # <-----------><------><---------------------------><------------> - # left margin indent text is formatted into here RIGHT MARGIN - # - # *Default*:: 0 - # Used in:: #format, #paragraphs, - # #center - def right_margin=(r) - @right_margin = posint(r) - end - - # The number of spaces to indent the first line of a paragraph. - # - # columns - # <--------------------------------------------------------------> - # <-----------><------><---------------------------><------------> - # left margin INDENT text is formatted into here right margin - # - # *Default*:: 4 - # Used in:: #format, #paragraphs - attr_reader :first_indent - - # The number of spaces to indent the first line of a paragraph. The - # value provided is silently converted to a positive integer value. - # - # columns - # <--------------------------------------------------------------> - # <-----------><------><---------------------------><------------> - # left margin INDENT text is formatted into here right margin - # - # *Default*:: 4 - # Used in:: #format, #paragraphs - def first_indent=(f) - @first_indent = posint(f) - end - - # The number of spaces to indent all lines after the first line of a - # paragraph. - # - # columns - # <--------------------------------------------------------------> - # <-----------><------><---------------------------><------------> - # left margin INDENT text is formatted into here right margin - # - # *Default*:: 0 - # Used in:: #format, #paragraphs - attr_reader :body_indent - - # The number of spaces to indent all lines after the first line of - # a paragraph. The value provided is silently converted to a - # positive integer value. - # - # columns - # <--------------------------------------------------------------> - # <-----------><------><---------------------------><------------> - # left margin INDENT text is formatted into here right margin - # - # *Default*:: 0 - # Used in:: #format, #paragraphs - def body_indent=(b) - @body_indent = posint(b) - end - - # Normally, words larger than the format area will be placed on a line - # by themselves. Setting this to +true+ will force words larger than the - # format area to be split into one or more "words" each at most the size - # of the format area. The first line and the original word will be - # placed into #split_words. Note that this will cause the - # output to look *similar* to a #format_style of JUSTIFY. (Lines will be - # filled as much as possible.) - # - # *Default*:: +false+ - # Used in:: #format, #paragraphs - attr_accessor :hard_margins - - # An array of words split during formatting if #hard_margins is set to - # +true+. - # #split_words << Text::Format::SplitWord.new(word, first, rest) - attr_reader :split_words - - # The object responsible for hyphenating. It must respond to - # #hyphenate_to(word, size) or #hyphenate_to(word, size, formatter) and - # return an array of the word split into two parts; if there is a - # hyphenation mark to be applied, responsibility belongs to the - # hyphenator object. The size is the MAXIMUM size permitted, including - # any hyphenation marks. If the #hyphenate_to method has an arity of 3, - # the formatter will be provided to the method. This allows the - # hyphenator to make decisions about the hyphenation based on the - # formatting rules. - # - # *Default*:: +nil+ - # Used in:: #format, #paragraphs - attr_reader :hyphenator - - # The object responsible for hyphenating. It must respond to - # #hyphenate_to(word, size) and return an array of the word hyphenated - # into two parts. The size is the MAXIMUM size permitted, including any - # hyphenation marks. - # - # *Default*:: +nil+ - # Used in:: #format, #paragraphs - def hyphenator=(h) - raise ArgumentError, "#{h.inspect} is not a valid hyphenator." unless h.respond_to?(:hyphenate_to) - arity = h.method(:hyphenate_to).arity - raise ArgumentError, "#{h.inspect} must have exactly two or three arguments." unless [2, 3].include?(arity) - @hyphenator = h - @hyphenator_arity = arity - end - - # Specifies the split mode; used only when #hard_margins is set to - # +true+. Allowable values are: - # [+SPLIT_FIXED+] The word will be split at the number of - # characters needed, with no marking at all. - # repre - # senta - # ion - # [+SPLIT_CONTINUATION+] The word will be split at the number of - # characters needed, with a C-style continuation - # character. If a word is the only item on a - # line and it cannot be split into an - # appropriate size, SPLIT_FIXED will be used. - # repr\ - # esen\ - # tati\ - # on - # [+SPLIT_HYPHENATION+] The word will be split according to the - # hyphenator specified in #hyphenator. If there - # is no #hyphenator specified, works like - # SPLIT_CONTINUATION. The example is using - # TeX::Hyphen. If a word is the only item on a - # line and it cannot be split into an - # appropriate size, SPLIT_CONTINUATION mode will - # be used. - # rep- - # re- - # sen- - # ta- - # tion - # - # *Default*:: Text::Format::SPLIT_FIXED - # Used in:: #format, #paragraphs - attr_reader :split_rules - - # Specifies the split mode; used only when #hard_margins is set to - # +true+. Allowable values are: - # [+SPLIT_FIXED+] The word will be split at the number of - # characters needed, with no marking at all. - # repre - # senta - # ion - # [+SPLIT_CONTINUATION+] The word will be split at the number of - # characters needed, with a C-style continuation - # character. - # repr\ - # esen\ - # tati\ - # on - # [+SPLIT_HYPHENATION+] The word will be split according to the - # hyphenator specified in #hyphenator. If there - # is no #hyphenator specified, works like - # SPLIT_CONTINUATION. The example is using - # TeX::Hyphen as the #hyphenator. - # rep- - # re- - # sen- - # ta- - # tion - # - # These values can be bitwise ORed together (e.g., SPLIT_FIXED | - # SPLIT_CONTINUATION) to provide fallback split methods. In the - # example given, an attempt will be made to split the word using the - # rules of SPLIT_CONTINUATION; if there is not enough room, the word - # will be split with the rules of SPLIT_FIXED. These combinations are - # also available as the following values: - # * +SPLIT_CONTINUATION_FIXED+ - # * +SPLIT_HYPHENATION_FIXED+ - # * +SPLIT_HYPHENATION_CONTINUATION+ - # * +SPLIT_ALL+ - # - # *Default*:: Text::Format::SPLIT_FIXED - # Used in:: #format, #paragraphs - def split_rules=(s) - raise ArgumentError, "Invalid value provided for split_rules." if ((s < SPLIT_FIXED) || (s > SPLIT_ALL)) - @split_rules = s - end - - # Indicates whether sentence terminators should be followed by a single - # space (+false+), or two spaces (+true+). - # - # *Default*:: +false+ - # Used in:: #format, #paragraphs - attr_accessor :extra_space - - # Defines the current abbreviations as an array. This is only used if - # extra_space is turned on. - # - # If one is abbreviating "President" as "Pres." (abbreviations = - # ["Pres"]), then the results of formatting will be as illustrated in - # the table below: - # - # extra_space | include? | !include? - # true | Pres. Lincoln | Pres. Lincoln - # false | Pres. Lincoln | Pres. Lincoln - # - # *Default*:: {} - # Used in:: #format, #paragraphs - attr_accessor :abbreviations - - # Indicates whether the formatting of paragraphs should be done with - # tagged paragraphs. Useful only with #tag_text. - # - # *Default*:: +false+ - # Used in:: #format, #paragraphs - attr_accessor :tag_paragraph - - # The array of text to be placed before each paragraph when - # #tag_paragraph is +true+. When #format() is called, - # only the first element of the array is used. When #paragraphs - # is called, then each entry in the array will be used once, with - # corresponding paragraphs. If the tag elements are exhausted before the - # text is exhausted, then the remaining paragraphs will not be tagged. - # Regardless of indentation settings, a blank line will be inserted - # between all paragraphs when #tag_paragraph is +true+. - # - # *Default*:: [] - # Used in:: #format, #paragraphs - attr_accessor :tag_text - - # Indicates whether or not the non-breaking space feature should be - # used. - # - # *Default*:: +false+ - # Used in:: #format, #paragraphs - attr_accessor :nobreak - - # A hash which holds the regular expressions on which spaces should not - # be broken. The hash is set up such that the key is the first word and - # the value is the second word. - # - # For example, if +nobreak_regex+ contains the following hash: - # - # { '^Mrs?\.$' => '\S+$', '^\S+$' => '^(?:S|J)r\.$'} - # - # Then "Mr. Jones", "Mrs. Jones", and "Jones Jr." would not be broken. - # If this simple matching algorithm indicates that there should not be a - # break at the current end of line, then a backtrack is done until there - # are two words on which line breaking is permitted. If two such words - # are not found, then the end of the line will be broken *regardless*. - # If there is a single word on the current line, then no backtrack is - # done and the word is stuck on the end. - # - # *Default*:: {} - # Used in:: #format, #paragraphs - attr_accessor :nobreak_regex - - # Indicates the number of spaces that a single tab represents. - # - # *Default*:: 8 - # Used in:: #expand, #unexpand, - # #paragraphs - attr_reader :tabstop - - # Indicates the number of spaces that a single tab represents. - # - # *Default*:: 8 - # Used in:: #expand, #unexpand, - # #paragraphs - def tabstop=(t) - @tabstop = posint(t) - end - - # Specifies the format style. Allowable values are: - # [+LEFT_ALIGN+] Left justified, ragged right. - # |A paragraph that is| - # |left aligned.| - # [+RIGHT_ALIGN+] Right justified, ragged left. - # |A paragraph that is| - # | right aligned.| - # [+RIGHT_FILL+] Left justified, right ragged, filled to width by - # spaces. (Essentially the same as +LEFT_ALIGN+ except - # that lines are padded on the right.) - # |A paragraph that is| - # |left aligned. | - # [+JUSTIFY+] Fully justified, words filled to width by spaces, - # except the last line. - # |A paragraph that| - # |is justified.| - # - # *Default*:: Text::Format::LEFT_ALIGN - # Used in:: #format, #paragraphs - attr_reader :format_style - - # Specifies the format style. Allowable values are: - # [+LEFT_ALIGN+] Left justified, ragged right. - # |A paragraph that is| - # |left aligned.| - # [+RIGHT_ALIGN+] Right justified, ragged left. - # |A paragraph that is| - # | right aligned.| - # [+RIGHT_FILL+] Left justified, right ragged, filled to width by - # spaces. (Essentially the same as +LEFT_ALIGN+ except - # that lines are padded on the right.) - # |A paragraph that is| - # |left aligned. | - # [+JUSTIFY+] Fully justified, words filled to width by spaces. - # |A paragraph that| - # |is justified.| - # - # *Default*:: Text::Format::LEFT_ALIGN - # Used in:: #format, #paragraphs - def format_style=(fs) - raise ArgumentError, "Invalid value provided for format_style." if ((fs < LEFT_ALIGN) || (fs > JUSTIFY)) - @format_style = fs - end - - # Indicates that the format style is left alignment. - # - # *Default*:: +true+ - # Used in:: #format, #paragraphs - def left_align? - return @format_style == LEFT_ALIGN - end - - # Indicates that the format style is right alignment. - # - # *Default*:: +false+ - # Used in:: #format, #paragraphs - def right_align? - return @format_style == RIGHT_ALIGN - end - - # Indicates that the format style is right fill. - # - # *Default*:: +false+ - # Used in:: #format, #paragraphs - def right_fill? - return @format_style == RIGHT_FILL - end - - # Indicates that the format style is full justification. - # - # *Default*:: +false+ - # Used in:: #format, #paragraphs - def justify? - return @format_style == JUSTIFY - end - - # The default implementation of #hyphenate_to implements - # SPLIT_CONTINUATION. - def hyphenate_to(word, size) - [word[0 .. (size - 2)] + "\\", word[(size - 1) .. -1]] - end - - private - def __do_split_word(word, size) #:nodoc: - [word[0 .. (size - 1)], word[size .. -1]] - end - - def __format(to_wrap) #:nodoc: - words = to_wrap.split(/\s+/).compact - words.shift if words[0].nil? or words[0].empty? - to_wrap = [] - - abbrev = false - width = @columns - @first_indent - @left_margin - @right_margin - indent_str = ' ' * @first_indent - first_line = true - line = words.shift - abbrev = __is_abbrev(line) unless line.nil? || line.empty? - - while w = words.shift - if (w.size + line.size < (width - 1)) || - ((line !~ LEQ_RE || abbrev) && (w.size + line.size < width)) - line << " " if (line =~ LEQ_RE) && (not abbrev) - line << " #{w}" - else - line, w = __do_break(line, w) if @nobreak - line, w = __do_hyphenate(line, w, width) if @hard_margins - if w.index(/\s+/) - w, *w2 = w.split(/\s+/) - words.unshift(w2) - words.flatten! - end - to_wrap << __make_line(line, indent_str, width, w.nil?) unless line.nil? - if first_line - first_line = false - width = @columns - @body_indent - @left_margin - @right_margin - indent_str = ' ' * @body_indent - end - line = w - end - - abbrev = __is_abbrev(w) unless w.nil? - end - - loop do - break if line.nil? or line.empty? - line, w = __do_hyphenate(line, w, width) if @hard_margins - to_wrap << __make_line(line, indent_str, width, w.nil?) - line = w - end - - if (@tag_paragraph && (to_wrap.size > 0)) then - clr = %r{`(\w+)'}.match([caller(1)].flatten[0])[1] - clr = "" if clr.nil? - - if ((not @tag_text[0].nil?) && (@tag_cur.size < 1) && - (clr != "__paragraphs")) then - @tag_cur = @tag_text[0] - end - - fchar = /(\S)/.match(to_wrap[0])[1] - white = to_wrap[0].index(fchar) - if ((white - @left_margin - 1) > @tag_cur.size) then - white = @tag_cur.size + @left_margin - to_wrap[0].gsub!(/^ {#{white}}/, "#{' ' * @left_margin}#{@tag_cur}") - else - to_wrap.unshift("#{' ' * @left_margin}#{@tag_cur}\n") - end - end - to_wrap.join('') - end - - # format lines in text into paragraphs with each element of @wrap a - # paragraph; uses Text::Format.format for the formatting - def __paragraphs(to_wrap) #:nodoc: - if ((@first_indent == @body_indent) || @tag_paragraph) then - p_end = "\n" - else - p_end = '' - end - - cnt = 0 - ret = [] - to_wrap.each do |tw| - @tag_cur = @tag_text[cnt] if @tag_paragraph - @tag_cur = '' if @tag_cur.nil? - line = __format(tw) - ret << "#{line}#{p_end}" if (not line.nil?) && (line.size > 0) - cnt += 1 - end - - ret[-1].chomp! unless ret.empty? - ret.join('') - end - - # center text using spaces on left side to pad it out empty lines - # are preserved - def __center(to_center) #:nodoc: - tabs = 0 - width = @columns - @left_margin - @right_margin - centered = [] - to_center.each do |tc| - s = tc.strip - tabs = s.count("\t") - tabs = 0 if tabs.nil? - ct = ((width - s.size - (tabs * @tabstop) + tabs) / 2) - ct = (width - @left_margin - @right_margin) - ct - centered << "#{s.rjust(ct)}\n" - end - centered.join('') - end - - # expand tabs to spaces should be similar to Text::Tabs::expand - def __expand(to_expand) #:nodoc: - expanded = [] - to_expand.split("\n").each { |te| expanded << te.gsub(/\t/, ' ' * @tabstop) } - expanded.join('') - end - - def __unexpand(to_unexpand) #:nodoc: - unexpanded = [] - to_unexpand.split("\n").each { |tu| unexpanded << tu.gsub(/ {#{@tabstop}}/, "\t") } - unexpanded.join('') - end - - def __is_abbrev(word) #:nodoc: - # remove period if there is one. - w = word.gsub(/\.$/, '') unless word.nil? - return true if (!@extra_space || ABBREV.include?(w) || @abbreviations.include?(w)) - false - end - - def __make_line(line, indent, width, last = false) #:nodoc: - lmargin = " " * @left_margin - fill = " " * (width - line.size) if right_fill? && (line.size <= width) - - if (justify? && ((not line.nil?) && (not line.empty?)) && line =~ /\S+\s+\S+/ && !last) - spaces = width - line.size - words = line.split(/(\s+)/) - ws = spaces / (words.size / 2) - spaces = spaces % (words.size / 2) if ws > 0 - words.reverse.each do |rw| - next if (rw =~ /^\S/) - rw.sub!(/^/, " " * ws) - next unless (spaces > 0) - rw.sub!(/^/, " ") - spaces -= 1 - end - line = words.join('') - end - line = "#{lmargin}#{indent}#{line}#{fill}\n" unless line.nil? - if right_align? && (not line.nil?) - line.sub(/^/, " " * (@columns - @right_margin - (line.size - 1))) - else - line - end - end - - def __do_hyphenate(line, next_line, width) #:nodoc: - rline = line.dup rescue line - rnext = next_line.dup rescue next_line - loop do - if rline.size == width - break - elsif rline.size > width - words = rline.strip.split(/\s+/) - word = words[-1].dup - size = width - rline.size + word.size - if (size <= 0) - words[-1] = nil - rline = words.join(' ').strip - rnext = "#{word} #{rnext}".strip - next - end - - first = rest = nil - - if ((@split_rules & SPLIT_HYPHENATION) != 0) - if @hyphenator_arity == 2 - first, rest = @hyphenator.hyphenate_to(word, size) - else - first, rest = @hyphenator.hyphenate_to(word, size, self) - end - end - - if ((@split_rules & SPLIT_CONTINUATION) != 0) and first.nil? - first, rest = self.hyphenate_to(word, size) - end - - if ((@split_rules & SPLIT_FIXED) != 0) and first.nil? - first.nil? or @split_rules == SPLIT_FIXED - first, rest = __do_split_word(word, size) - end - - if first.nil? - words[-1] = nil - rest = word - else - words[-1] = first - @split_words << SplitWord.new(word, first, rest) - end - rline = words.join(' ').strip - rnext = "#{rest} #{rnext}".strip - break - else - break if rnext.nil? or rnext.empty? or rline.nil? or rline.empty? - words = rnext.split(/\s+/) - word = words.shift - size = width - rline.size - 1 - - if (size <= 0) - rnext = "#{word} #{words.join(' ')}".strip - break - end - - first = rest = nil - - if ((@split_rules & SPLIT_HYPHENATION) != 0) - if @hyphenator_arity == 2 - first, rest = @hyphenator.hyphenate_to(word, size) - else - first, rest = @hyphenator.hyphenate_to(word, size, self) - end - end - - first, rest = self.hyphenate_to(word, size) if ((@split_rules & SPLIT_CONTINUATION) != 0) and first.nil? - - first, rest = __do_split_word(word, size) if ((@split_rules & SPLIT_FIXED) != 0) and first.nil? - - if (rline.size + (first ? first.size : 0)) < width - @split_words << SplitWord.new(word, first, rest) - rline = "#{rline} #{first}".strip - rnext = "#{rest} #{words.join(' ')}".strip - end - break - end - end - [rline, rnext] - end - - def __do_break(line, next_line) #:nodoc: - no_brk = false - words = [] - words = line.split(/\s+/) unless line.nil? - last_word = words[-1] - - @nobreak_regex.each { |k, v| no_brk = ((last_word =~ /#{k}/) and (next_line =~ /#{v}/)) } - - if no_brk && words.size > 1 - i = words.size - while i > 0 - no_brk = false - @nobreak_regex.each { |k, v| no_brk = ((words[i + 1] =~ /#{k}/) && (words[i] =~ /#{v}/)) } - i -= 1 - break if not no_brk - end - if i > 0 - l = brk_re(i).match(line) - line.sub!(brk_re(i), l[1]) - next_line = "#{l[2]} #{next_line}" - line.sub!(/\s+$/, '') - end - end - [line, next_line] - end - - def __create(arg = nil, &block) #:nodoc: - # Format::Text.new(text-to-wrap) - @text = arg unless arg.nil? - # Defaults - @columns = 72 - @tabstop = 8 - @first_indent = 4 - @body_indent = 0 - @format_style = LEFT_ALIGN - @left_margin = 0 - @right_margin = 0 - @extra_space = false - @text = Array.new if @text.nil? - @tag_paragraph = false - @tag_text = Array.new - @tag_cur = "" - @abbreviations = Array.new - @nobreak = false - @nobreak_regex = Hash.new - @split_words = Array.new - @hard_margins = false - @split_rules = SPLIT_FIXED - @hyphenator = self - @hyphenator_arity = self.method(:hyphenate_to).arity - - instance_eval(&block) unless block.nil? - end - - public - # Formats text into a nice paragraph format. The text is separated - # into words and then reassembled a word at a time using the settings - # of this Format object. If a word is larger than the number of - # columns available for formatting, then that word will appear on the - # line by itself. - # - # If +to_wrap+ is +nil+, then the value of #text will be - # worked on. - def format(to_wrap = nil) - to_wrap = @text if to_wrap.nil? - if to_wrap.class == Array - __format(to_wrap[0]) - else - __format(to_wrap) - end - end - - # Considers each element of text (provided or internal) as a paragraph. - # If #first_indent is the same as #body_indent, then - # paragraphs will be separated by a single empty line in the result; - # otherwise, the paragraphs will follow immediately after each other. - # Uses #format to do the heavy lifting. - def paragraphs(to_wrap = nil) - to_wrap = @text if to_wrap.nil? - __paragraphs([to_wrap].flatten) - end - - # Centers the text, preserving empty lines and tabs. - def center(to_center = nil) - to_center = @text if to_center.nil? - __center([to_center].flatten) - end - - # Replaces all tab characters in the text with #tabstop spaces. - def expand(to_expand = nil) - to_expand = @text if to_expand.nil? - if to_expand.class == Array - to_expand.collect { |te| __expand(te) } - else - __expand(to_expand) - end - end - - # Replaces all occurrences of #tabstop consecutive spaces - # with a tab character. - def unexpand(to_unexpand = nil) - to_unexpand = @text if to_unexpand.nil? - if to_unexpand.class == Array - to_unexpand.collect { |te| v << __unexpand(te) } - else - __unexpand(to_unexpand) - end - end - - # This constructor takes advantage of a technique for Ruby object - # construction introduced by Andy Hunt and Dave Thomas (see reference), - # where optional values are set using commands in a block. - # - # Text::Format.new { - # columns = 72 - # left_margin = 0 - # right_margin = 0 - # first_indent = 4 - # body_indent = 0 - # format_style = Text::Format::LEFT_ALIGN - # extra_space = false - # abbreviations = {} - # tag_paragraph = false - # tag_text = [] - # nobreak = false - # nobreak_regex = {} - # tabstop = 8 - # text = nil - # } - # - # As shown above, +arg+ is optional. If +arg+ is specified and is a - # +String+, then arg is used as the default value of #text. - # Alternately, an existing Text::Format object can be used or a Hash can - # be used. With all forms, a block can be specified. - # - # *Reference*:: "Object Construction and Blocks" - # - # - def initialize(arg = nil, &block) - case arg - when Text::Format - __create(arg.text) do - @columns = arg.columns - @tabstop = arg.tabstop - @first_indent = arg.first_indent - @body_indent = arg.body_indent - @format_style = arg.format_style - @left_margin = arg.left_margin - @right_margin = arg.right_margin - @extra_space = arg.extra_space - @tag_paragraph = arg.tag_paragraph - @tag_text = arg.tag_text - @abbreviations = arg.abbreviations - @nobreak = arg.nobreak - @nobreak_regex = arg.nobreak_regex - @text = arg.text - @hard_margins = arg.hard_margins - @split_words = arg.split_words - @split_rules = arg.split_rules - @hyphenator = arg.hyphenator - end - instance_eval(&block) unless block.nil? - when Hash - __create do - @columns = arg[:columns] || arg['columns'] || @columns - @tabstop = arg[:tabstop] || arg['tabstop'] || @tabstop - @first_indent = arg[:first_indent] || arg['first_indent'] || @first_indent - @body_indent = arg[:body_indent] || arg['body_indent'] || @body_indent - @format_style = arg[:format_style] || arg['format_style'] || @format_style - @left_margin = arg[:left_margin] || arg['left_margin'] || @left_margin - @right_margin = arg[:right_margin] || arg['right_margin'] || @right_margin - @extra_space = arg[:extra_space] || arg['extra_space'] || @extra_space - @text = arg[:text] || arg['text'] || @text - @tag_paragraph = arg[:tag_paragraph] || arg['tag_paragraph'] || @tag_paragraph - @tag_text = arg[:tag_text] || arg['tag_text'] || @tag_text - @abbreviations = arg[:abbreviations] || arg['abbreviations'] || @abbreviations - @nobreak = arg[:nobreak] || arg['nobreak'] || @nobreak - @nobreak_regex = arg[:nobreak_regex] || arg['nobreak_regex'] || @nobreak_regex - @hard_margins = arg[:hard_margins] || arg['hard_margins'] || @hard_margins - @split_rules = arg[:split_rules] || arg['split_rules'] || @split_rules - @hyphenator = arg[:hyphenator] || arg['hyphenator'] || @hyphenator - end - instance_eval(&block) unless block.nil? - when String - __create(arg, &block) - when NilClass - __create(&block) - else - raise TypeError - end - end - end -end - -if __FILE__ == $0 - require 'test/unit' - - class TestText__Format < Test::Unit::TestCase #:nodoc: - attr_accessor :format_o - - GETTYSBURG = <<-'EOS' - Four score and seven years ago our fathers brought forth on this - continent a new nation, conceived in liberty and dedicated to the - proposition that all men are created equal. Now we are engaged in - a great civil war, testing whether that nation or any nation so - conceived and so dedicated can long endure. We are met on a great - battlefield of that war. We have come to dedicate a portion of - that field as a final resting-place for those who here gave their - lives that that nation might live. It is altogether fitting and - proper that we should do this. But in a larger sense, we cannot - dedicate, we cannot consecrate, we cannot hallow this ground. - The brave men, living and dead who struggled here have consecrated - it far above our poor power to add or detract. The world will - little note nor long remember what we say here, but it can never - forget what they did here. It is for us the living rather to be - dedicated here to the unfinished work which they who fought here - have thus far so nobly advanced. It is rather for us to be here - dedicated to the great task remaining before us--that from these - honored dead we take increased devotion to that cause for which - they gave the last full measure of devotion--that we here highly - resolve that these dead shall not have died in vain, that this - nation under God shall have a new birth of freedom, and that - government of the people, by the people, for the people shall - not perish from the earth. - - -- Pres. Abraham Lincoln, 19 November 1863 - EOS - - FIVE_COL = "Four \nscore\nand s\neven \nyears\nago o\nur fa\nthers\nbroug\nht fo\nrth o\nn thi\ns con\ntinen\nt a n\new na\ntion,\nconce\nived \nin li\nberty\nand d\nedica\nted t\no the\npropo\nsitio\nn tha\nt all\nmen a\nre cr\neated\nequal\n. Now\nwe ar\ne eng\naged \nin a \ngreat\ncivil\nwar, \ntesti\nng wh\nether\nthat \nnatio\nn or \nany n\nation\nso co\nnceiv\ned an\nd so \ndedic\nated \ncan l\nong e\nndure\n. We \nare m\net on\na gre\nat ba\nttlef\nield \nof th\nat wa\nr. We\nhave \ncome \nto de\ndicat\ne a p\nortio\nn of \nthat \nfield\nas a \nfinal\nresti\nng-pl\nace f\nor th\nose w\nho he\nre ga\nve th\neir l\nives \nthat \nthat \nnatio\nn mig\nht li\nve. I\nt is \naltog\nether\nfitti\nng an\nd pro\nper t\nhat w\ne sho\nuld d\no thi\ns. Bu\nt in \na lar\nger s\nense,\nwe ca\nnnot \ndedic\nate, \nwe ca\nnnot \nconse\ncrate\n, we \ncanno\nt hal\nlow t\nhis g\nround\n. The\nbrave\nmen, \nlivin\ng and\ndead \nwho s\ntrugg\nled h\nere h\nave c\nonsec\nrated\nit fa\nr abo\nve ou\nr poo\nr pow\ner to\nadd o\nr det\nract.\nThe w\norld \nwill \nlittl\ne not\ne nor\nlong \nremem\nber w\nhat w\ne say\nhere,\nbut i\nt can\nnever\nforge\nt wha\nt the\ny did\nhere.\nIt is\nfor u\ns the\nlivin\ng rat\nher t\no be \ndedic\nated \nhere \nto th\ne unf\ninish\ned wo\nrk wh\nich t\nhey w\nho fo\nught \nhere \nhave \nthus \nfar s\no nob\nly ad\nvance\nd. It\nis ra\nther \nfor u\ns to \nbe he\nre de\ndicat\ned to\nthe g\nreat \ntask \nremai\nning \nbefor\ne us-\n-that\nfrom \nthese\nhonor\ned de\nad we\ntake \nincre\nased \ndevot\nion t\no tha\nt cau\nse fo\nr whi\nch th\ney ga\nve th\ne las\nt ful\nl mea\nsure \nof de\nvotio\nn--th\nat we\nhere \nhighl\ny res\nolve \nthat \nthese\ndead \nshall\nnot h\nave d\nied i\nn vai\nn, th\nat th\nis na\ntion \nunder\nGod s\nhall \nhave \na new\nbirth\nof fr\needom\n, and\nthat \ngover\nnment\nof th\ne peo\nple, \nby th\ne peo\nple, \nfor t\nhe pe\nople \nshall\nnot p\nerish\nfrom \nthe e\narth.\n-- Pr\nes. A\nbraha\nm Lin\ncoln,\n19 No\nvembe\nr 186\n3 \n" - - FIVE_CNT = "Four \nscore\nand \nseven\nyears\nago \nour \nfath\\\ners \nbrou\\\nght \nforth\non t\\\nhis \ncont\\\ninent\na new\nnati\\\non, \nconc\\\neived\nin l\\\niber\\\nty a\\\nnd d\\\nedic\\\nated \nto t\\\nhe p\\\nropo\\\nsiti\\\non t\\\nhat \nall \nmen \nare \ncrea\\\nted \nequa\\\nl. N\\\now we\nare \nenga\\\nged \nin a \ngreat\ncivil\nwar, \ntest\\\ning \nwhet\\\nher \nthat \nnati\\\non or\nany \nnati\\\non so\nconc\\\neived\nand \nso d\\\nedic\\\nated \ncan \nlong \nendu\\\nre. \nWe a\\\nre m\\\net on\na gr\\\neat \nbatt\\\nlefi\\\neld \nof t\\\nhat \nwar. \nWe h\\\nave \ncome \nto d\\\nedic\\\nate a\nport\\\nion \nof t\\\nhat \nfield\nas a \nfinal\nrest\\\ning-\\\nplace\nfor \nthose\nwho \nhere \ngave \ntheir\nlives\nthat \nthat \nnati\\\non m\\\night \nlive.\nIt is\nalto\\\ngeth\\\ner f\\\nitti\\\nng a\\\nnd p\\\nroper\nthat \nwe s\\\nhould\ndo t\\\nhis. \nBut \nin a \nlarg\\\ner s\\\nense,\nwe c\\\nannot\ndedi\\\ncate,\nwe c\\\nannot\ncons\\\necra\\\nte, \nwe c\\\nannot\nhall\\\now t\\\nhis \ngrou\\\nnd. \nThe \nbrave\nmen, \nlivi\\\nng a\\\nnd d\\\nead \nwho \nstru\\\nggled\nhere \nhave \ncons\\\necra\\\nted \nit f\\\nar a\\\nbove \nour \npoor \npower\nto a\\\ndd or\ndetr\\\nact. \nThe \nworld\nwill \nlitt\\\nle n\\\note \nnor \nlong \nreme\\\nmber \nwhat \nwe s\\\nay h\\\nere, \nbut \nit c\\\nan n\\\never \nforg\\\net w\\\nhat \nthey \ndid \nhere.\nIt is\nfor \nus t\\\nhe l\\\niving\nrath\\\ner to\nbe d\\\nedic\\\nated \nhere \nto t\\\nhe u\\\nnfin\\\nished\nwork \nwhich\nthey \nwho \nfoug\\\nht h\\\nere \nhave \nthus \nfar \nso n\\\nobly \nadva\\\nnced.\nIt is\nrath\\\ner f\\\nor us\nto be\nhere \ndedi\\\ncated\nto t\\\nhe g\\\nreat \ntask \nrema\\\nining\nbefo\\\nre u\\\ns--t\\\nhat \nfrom \nthese\nhono\\\nred \ndead \nwe t\\\nake \nincr\\\neased\ndevo\\\ntion \nto t\\\nhat \ncause\nfor \nwhich\nthey \ngave \nthe \nlast \nfull \nmeas\\\nure \nof d\\\nevot\\\nion-\\\n-that\nwe h\\\nere \nhigh\\\nly r\\\nesol\\\nve t\\\nhat \nthese\ndead \nshall\nnot \nhave \ndied \nin v\\\nain, \nthat \nthis \nnati\\\non u\\\nnder \nGod \nshall\nhave \na new\nbirth\nof f\\\nreed\\\nom, \nand \nthat \ngove\\\nrnme\\\nnt of\nthe \npeop\\\nle, \nby t\\\nhe p\\\neopl\\\ne, f\\\nor t\\\nhe p\\\neople\nshall\nnot \nperi\\\nsh f\\\nrom \nthe \neart\\\nh. --\nPres.\nAbra\\\nham \nLinc\\\noln, \n19 N\\\novem\\\nber \n1863 \n" - - # Tests both abbreviations and abbreviations= - def test_abbreviations - abbr = [" Pres. Abraham Lincoln\n", " Pres. Abraham Lincoln\n"] - assert_nothing_raised { @format_o = Text::Format.new } - assert_equal([], @format_o.abbreviations) - assert_nothing_raised { @format_o.abbreviations = [ 'foo', 'bar' ] } - assert_equal([ 'foo', 'bar' ], @format_o.abbreviations) - assert_equal(abbr[0], @format_o.format(abbr[0])) - assert_nothing_raised { @format_o.extra_space = true } - assert_equal(abbr[1], @format_o.format(abbr[0])) - assert_nothing_raised { @format_o.abbreviations = [ "Pres" ] } - assert_equal([ "Pres" ], @format_o.abbreviations) - assert_equal(abbr[0], @format_o.format(abbr[0])) - assert_nothing_raised { @format_o.extra_space = false } - assert_equal(abbr[0], @format_o.format(abbr[0])) - end - - # Tests both body_indent and body_indent= - def test_body_indent - assert_nothing_raised { @format_o = Text::Format.new } - assert_equal(0, @format_o.body_indent) - assert_nothing_raised { @format_o.body_indent = 7 } - assert_equal(7, @format_o.body_indent) - assert_nothing_raised { @format_o.body_indent = -3 } - assert_equal(3, @format_o.body_indent) - assert_nothing_raised { @format_o.body_indent = "9" } - assert_equal(9, @format_o.body_indent) - assert_nothing_raised { @format_o.body_indent = "-2" } - assert_equal(2, @format_o.body_indent) - assert_match(/^ [^ ]/, @format_o.format(GETTYSBURG).split("\n")[1]) - end - - # Tests both columns and columns= - def test_columns - assert_nothing_raised { @format_o = Text::Format.new } - assert_equal(72, @format_o.columns) - assert_nothing_raised { @format_o.columns = 7 } - assert_equal(7, @format_o.columns) - assert_nothing_raised { @format_o.columns = -3 } - assert_equal(3, @format_o.columns) - assert_nothing_raised { @format_o.columns = "9" } - assert_equal(9, @format_o.columns) - assert_nothing_raised { @format_o.columns = "-2" } - assert_equal(2, @format_o.columns) - assert_nothing_raised { @format_o.columns = 40 } - assert_equal(40, @format_o.columns) - assert_match(/this continent$/, - @format_o.format(GETTYSBURG).split("\n")[1]) - end - - # Tests both extra_space and extra_space= - def test_extra_space - assert_nothing_raised { @format_o = Text::Format.new } - assert(!@format_o.extra_space) - assert_nothing_raised { @format_o.extra_space = true } - assert(@format_o.extra_space) - # The behaviour of extra_space is tested in test_abbreviations. There - # is no need to reproduce it here. - end - - # Tests both first_indent and first_indent= - def test_first_indent - assert_nothing_raised { @format_o = Text::Format.new } - assert_equal(4, @format_o.first_indent) - assert_nothing_raised { @format_o.first_indent = 7 } - assert_equal(7, @format_o.first_indent) - assert_nothing_raised { @format_o.first_indent = -3 } - assert_equal(3, @format_o.first_indent) - assert_nothing_raised { @format_o.first_indent = "9" } - assert_equal(9, @format_o.first_indent) - assert_nothing_raised { @format_o.first_indent = "-2" } - assert_equal(2, @format_o.first_indent) - assert_match(/^ [^ ]/, @format_o.format(GETTYSBURG).split("\n")[0]) - end - - def test_format_style - assert_nothing_raised { @format_o = Text::Format.new } - assert_equal(Text::Format::LEFT_ALIGN, @format_o.format_style) - assert_match(/^November 1863$/, - @format_o.format(GETTYSBURG).split("\n")[-1]) - assert_nothing_raised { - @format_o.format_style = Text::Format::RIGHT_ALIGN - } - assert_equal(Text::Format::RIGHT_ALIGN, @format_o.format_style) - assert_match(/^ +November 1863$/, - @format_o.format(GETTYSBURG).split("\n")[-1]) - assert_nothing_raised { - @format_o.format_style = Text::Format::RIGHT_FILL - } - assert_equal(Text::Format::RIGHT_FILL, @format_o.format_style) - assert_match(/^November 1863 +$/, - @format_o.format(GETTYSBURG).split("\n")[-1]) - assert_nothing_raised { @format_o.format_style = Text::Format::JUSTIFY } - assert_equal(Text::Format::JUSTIFY, @format_o.format_style) - assert_match(/^of freedom, and that government of the people, by the people, for the$/, - @format_o.format(GETTYSBURG).split("\n")[-3]) - assert_raises(ArgumentError) { @format_o.format_style = 33 } - end - - def test_tag_paragraph - assert_nothing_raised { @format_o = Text::Format.new } - assert(!@format_o.tag_paragraph) - assert_nothing_raised { @format_o.tag_paragraph = true } - assert(@format_o.tag_paragraph) - assert_not_equal(@format_o.paragraphs([GETTYSBURG, GETTYSBURG]), - Text::Format.new.paragraphs([GETTYSBURG, GETTYSBURG])) - end - - def test_tag_text - assert_nothing_raised { @format_o = Text::Format.new } - assert_equal([], @format_o.tag_text) - assert_equal(@format_o.format(GETTYSBURG), - Text::Format.new.format(GETTYSBURG)) - assert_nothing_raised { - @format_o.tag_paragraph = true - @format_o.tag_text = ["Gettysburg Address", "---"] - } - assert_not_equal(@format_o.format(GETTYSBURG), - Text::Format.new.format(GETTYSBURG)) - assert_not_equal(@format_o.paragraphs([GETTYSBURG, GETTYSBURG]), - Text::Format.new.paragraphs([GETTYSBURG, GETTYSBURG])) - assert_not_equal(@format_o.paragraphs([GETTYSBURG, GETTYSBURG, - GETTYSBURG]), - Text::Format.new.paragraphs([GETTYSBURG, GETTYSBURG, - GETTYSBURG])) - end - - def test_justify? - assert_nothing_raised { @format_o = Text::Format.new } - assert(!@format_o.justify?) - assert_nothing_raised { - @format_o.format_style = Text::Format::RIGHT_ALIGN - } - assert(!@format_o.justify?) - assert_nothing_raised { - @format_o.format_style = Text::Format::RIGHT_FILL - } - assert(!@format_o.justify?) - assert_nothing_raised { - @format_o.format_style = Text::Format::JUSTIFY - } - assert(@format_o.justify?) - # The format testing is done in test_format_style - end - - def test_left_align? - assert_nothing_raised { @format_o = Text::Format.new } - assert(@format_o.left_align?) - assert_nothing_raised { - @format_o.format_style = Text::Format::RIGHT_ALIGN - } - assert(!@format_o.left_align?) - assert_nothing_raised { - @format_o.format_style = Text::Format::RIGHT_FILL - } - assert(!@format_o.left_align?) - assert_nothing_raised { @format_o.format_style = Text::Format::JUSTIFY } - assert(!@format_o.left_align?) - # The format testing is done in test_format_style - end - - def test_left_margin - assert_nothing_raised { @format_o = Text::Format.new } - assert_equal(0, @format_o.left_margin) - assert_nothing_raised { @format_o.left_margin = -3 } - assert_equal(3, @format_o.left_margin) - assert_nothing_raised { @format_o.left_margin = "9" } - assert_equal(9, @format_o.left_margin) - assert_nothing_raised { @format_o.left_margin = "-2" } - assert_equal(2, @format_o.left_margin) - assert_nothing_raised { @format_o.left_margin = 7 } - assert_equal(7, @format_o.left_margin) - assert_nothing_raised { - ft = @format_o.format(GETTYSBURG).split("\n") - assert_match(/^ {11}Four score/, ft[0]) - assert_match(/^ {7}November/, ft[-1]) - } - end - - def test_hard_margins - assert_nothing_raised { @format_o = Text::Format.new } - assert(!@format_o.hard_margins) - assert_nothing_raised { - @format_o.hard_margins = true - @format_o.columns = 5 - @format_o.first_indent = 0 - @format_o.format_style = Text::Format::RIGHT_FILL - } - assert(@format_o.hard_margins) - assert_equal(FIVE_COL, @format_o.format(GETTYSBURG)) - assert_nothing_raised { - @format_o.split_rules |= Text::Format::SPLIT_CONTINUATION - assert_equal(Text::Format::SPLIT_CONTINUATION_FIXED, - @format_o.split_rules) - } - assert_equal(FIVE_CNT, @format_o.format(GETTYSBURG)) - end - - # Tests both nobreak and nobreak_regex, since one is only useful - # with the other. - def test_nobreak - assert_nothing_raised { @format_o = Text::Format.new } - assert(!@format_o.nobreak) - assert(@format_o.nobreak_regex.empty?) - assert_nothing_raised { - @format_o.nobreak = true - @format_o.nobreak_regex = { '^this$' => '^continent$' } - @format_o.columns = 77 - } - assert(@format_o.nobreak) - assert_equal({ '^this$' => '^continent$' }, @format_o.nobreak_regex) - assert_match(/^this continent/, - @format_o.format(GETTYSBURG).split("\n")[1]) - end - - def test_right_align? - assert_nothing_raised { @format_o = Text::Format.new } - assert(!@format_o.right_align?) - assert_nothing_raised { - @format_o.format_style = Text::Format::RIGHT_ALIGN - } - assert(@format_o.right_align?) - assert_nothing_raised { - @format_o.format_style = Text::Format::RIGHT_FILL - } - assert(!@format_o.right_align?) - assert_nothing_raised { @format_o.format_style = Text::Format::JUSTIFY } - assert(!@format_o.right_align?) - # The format testing is done in test_format_style - end - - def test_right_fill? - assert_nothing_raised { @format_o = Text::Format.new } - assert(!@format_o.right_fill?) - assert_nothing_raised { - @format_o.format_style = Text::Format::RIGHT_ALIGN - } - assert(!@format_o.right_fill?) - assert_nothing_raised { - @format_o.format_style = Text::Format::RIGHT_FILL - } - assert(@format_o.right_fill?) - assert_nothing_raised { - @format_o.format_style = Text::Format::JUSTIFY - } - assert(!@format_o.right_fill?) - # The format testing is done in test_format_style - end - - def test_right_margin - assert_nothing_raised { @format_o = Text::Format.new } - assert_equal(0, @format_o.right_margin) - assert_nothing_raised { @format_o.right_margin = -3 } - assert_equal(3, @format_o.right_margin) - assert_nothing_raised { @format_o.right_margin = "9" } - assert_equal(9, @format_o.right_margin) - assert_nothing_raised { @format_o.right_margin = "-2" } - assert_equal(2, @format_o.right_margin) - assert_nothing_raised { @format_o.right_margin = 7 } - assert_equal(7, @format_o.right_margin) - assert_nothing_raised { - ft = @format_o.format(GETTYSBURG).split("\n") - assert_match(/^ {4}Four score.*forth on$/, ft[0]) - assert_match(/^November/, ft[-1]) - } - end - - def test_tabstop - assert_nothing_raised { @format_o = Text::Format.new } - assert_equal(8, @format_o.tabstop) - assert_nothing_raised { @format_o.tabstop = 7 } - assert_equal(7, @format_o.tabstop) - assert_nothing_raised { @format_o.tabstop = -3 } - assert_equal(3, @format_o.tabstop) - assert_nothing_raised { @format_o.tabstop = "9" } - assert_equal(9, @format_o.tabstop) - assert_nothing_raised { @format_o.tabstop = "-2" } - assert_equal(2, @format_o.tabstop) - end - - def test_text - assert_nothing_raised { @format_o = Text::Format.new } - assert_equal([], @format_o.text) - assert_nothing_raised { @format_o.text = "Test Text" } - assert_equal("Test Text", @format_o.text) - assert_nothing_raised { @format_o.text = ["Line 1", "Line 2"] } - assert_equal(["Line 1", "Line 2"], @format_o.text) - end - - def test_s_new - # new(NilClass) { block } - assert_nothing_raised do - @format_o = Text::Format.new { - self.text = "Test 1, 2, 3" - } - end - assert_equal("Test 1, 2, 3", @format_o.text) - - # new(Hash Symbols) - assert_nothing_raised { @format_o = Text::Format.new(:columns => 72) } - assert_equal(72, @format_o.columns) - - # new(Hash String) - assert_nothing_raised { @format_o = Text::Format.new('columns' => 72) } - assert_equal(72, @format_o.columns) - - # new(Hash) { block } - assert_nothing_raised do - @format_o = Text::Format.new('columns' => 80) { - self.text = "Test 4, 5, 6" - } - end - assert_equal("Test 4, 5, 6", @format_o.text) - assert_equal(80, @format_o.columns) - - # new(Text::Format) - assert_nothing_raised do - fo = Text::Format.new(@format_o) - assert(fo == @format_o) - end - - # new(Text::Format) { block } - assert_nothing_raised do - fo = Text::Format.new(@format_o) { self.columns = 79 } - assert(fo != @format_o) - end - - # new(String) - assert_nothing_raised { @format_o = Text::Format.new("Test A, B, C") } - assert_equal("Test A, B, C", @format_o.text) - - # new(String) { block } - assert_nothing_raised do - @format_o = Text::Format.new("Test X, Y, Z") { self.columns = -5 } - end - assert_equal("Test X, Y, Z", @format_o.text) - assert_equal(5, @format_o.columns) - end - - def test_center - assert_nothing_raised { @format_o = Text::Format.new } - assert_nothing_raised do - ct = @format_o.center(GETTYSBURG.split("\n")).split("\n") - assert_match(/^ Four score and seven years ago our fathers brought forth on this/, ct[0]) - assert_match(/^ not perish from the earth./, ct[-3]) - end - end - - def test_expand - assert_nothing_raised { @format_o = Text::Format.new } - assert_equal(" ", @format_o.expand("\t ")) - assert_nothing_raised { @format_o.tabstop = 4 } - assert_equal(" ", @format_o.expand("\t ")) - end - - def test_unexpand - assert_nothing_raised { @format_o = Text::Format.new } - assert_equal("\t ", @format_o.unexpand(" ")) - assert_nothing_raised { @format_o.tabstop = 4 } - assert_equal("\t ", @format_o.unexpand(" ")) - end - - def test_space_only - assert_equal("", Text::Format.new.format(" ")) - assert_equal("", Text::Format.new.format("\n")) - assert_equal("", Text::Format.new.format(" ")) - assert_equal("", Text::Format.new.format(" \n")) - assert_equal("", Text::Format.new.paragraphs("\n")) - assert_equal("", Text::Format.new.paragraphs(" ")) - assert_equal("", Text::Format.new.paragraphs(" ")) - assert_equal("", Text::Format.new.paragraphs(" \n")) - assert_equal("", Text::Format.new.paragraphs(["\n"])) - assert_equal("", Text::Format.new.paragraphs([" "])) - assert_equal("", Text::Format.new.paragraphs([" "])) - assert_equal("", Text::Format.new.paragraphs([" \n"])) - end - - def test_splendiferous - h = nil - test = "This is a splendiferous test" - assert_nothing_raised { @format_o = Text::Format.new(:columns => 6, :left_margin => 0, :indent => 0, :first_indent => 0) } - assert_match(/^splendiferous$/, @format_o.format(test)) - assert_nothing_raised { @format_o.hard_margins = true } - assert_match(/^lendif$/, @format_o.format(test)) - assert_nothing_raised { h = Object.new } - assert_nothing_raised do - @format_o.split_rules = Text::Format::SPLIT_HYPHENATION - class << h #:nodoc: - def hyphenate_to(word, size) - return ["", word] if size < 2 - [word[0 ... size], word[size .. -1]] - end - end - @format_o.hyphenator = h - end - assert_match(/^iferou$/, @format_o.format(test)) - assert_nothing_raised { h = Object.new } - assert_nothing_raised do - class << h #:nodoc: - def hyphenate_to(word, size, formatter) - return ["", word] if word.size < formatter.columns - [word[0 ... size], word[size .. -1]] - end - end - @format_o.hyphenator = h - end - assert_match(/^ferous$/, @format_o.format(test)) - end - end -end diff --git a/tracks/vendor/rails/actionmailer/lib/action_mailer/vendor/tmail.rb b/tracks/vendor/rails/actionmailer/lib/action_mailer/vendor/tmail.rb deleted file mode 100644 index 8cea88d3..00000000 --- a/tracks/vendor/rails/actionmailer/lib/action_mailer/vendor/tmail.rb +++ /dev/null @@ -1,3 +0,0 @@ -require 'tmail/info' -require 'tmail/mail' -require 'tmail/mailbox' diff --git a/tracks/vendor/rails/actionmailer/lib/action_mailer/vendor/tmail/address.rb b/tracks/vendor/rails/actionmailer/lib/action_mailer/vendor/tmail/address.rb deleted file mode 100644 index 235ec761..00000000 --- a/tracks/vendor/rails/actionmailer/lib/action_mailer/vendor/tmail/address.rb +++ /dev/null @@ -1,242 +0,0 @@ -# -# address.rb -# -#-- -# Copyright (c) 1998-2003 Minero Aoki -# -# 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. -# -# Note: Originally licensed under LGPL v2+. Using MIT license for Rails -# with permission of Minero Aoki. -#++ - -require 'tmail/encode' -require 'tmail/parser' - - -module TMail - - class Address - - include TextUtils - - def Address.parse( str ) - Parser.parse :ADDRESS, str - end - - def address_group? - false - end - - def initialize( local, domain ) - if domain - domain.each do |s| - raise SyntaxError, 'empty word in domain' if s.empty? - end - end - @local = local - @domain = domain - @name = nil - @routes = [] - end - - attr_reader :name - - def name=( str ) - @name = str - @name = nil if str and str.empty? - end - - alias phrase name - alias phrase= name= - - attr_reader :routes - - def inspect - "#<#{self.class} #{address()}>" - end - - def local - return nil unless @local - return '""' if @local.size == 1 and @local[0].empty? - @local.map {|i| quote_atom(i) }.join('.') - end - - def domain - return nil unless @domain - join_domain(@domain) - end - - def spec - s = self.local - d = self.domain - if s and d - s + '@' + d - else - s - end - end - - alias address spec - - - def ==( other ) - other.respond_to? :spec and self.spec == other.spec - end - - alias eql? == - - def hash - @local.hash ^ @domain.hash - end - - def dup - obj = self.class.new(@local.dup, @domain.dup) - obj.name = @name.dup if @name - obj.routes.replace @routes - obj - end - - include StrategyInterface - - def accept( strategy, dummy1 = nil, dummy2 = nil ) - unless @local - strategy.meta '<>' # empty return-path - return - end - - spec_p = (not @name and @routes.empty?) - if @name - strategy.phrase @name - strategy.space - end - tmp = spec_p ? '' : '<' - unless @routes.empty? - tmp << @routes.map {|i| '@' + i }.join(',') << ':' - end - tmp << self.spec - tmp << '>' unless spec_p - strategy.meta tmp - strategy.lwsp '' - end - - end - - - class AddressGroup - - include Enumerable - - def address_group? - true - end - - def initialize( name, addrs ) - @name = name - @addresses = addrs - end - - attr_reader :name - - def ==( other ) - other.respond_to? :to_a and @addresses == other.to_a - end - - alias eql? == - - def hash - map {|i| i.hash }.hash - end - - def []( idx ) - @addresses[idx] - end - - def size - @addresses.size - end - - def empty? - @addresses.empty? - end - - def each( &block ) - @addresses.each(&block) - end - - def to_a - @addresses.dup - end - - alias to_ary to_a - - def include?( a ) - @addresses.include? a - end - - def flatten - set = [] - @addresses.each do |a| - if a.respond_to? :flatten - set.concat a.flatten - else - set.push a - end - end - set - end - - def each_address( &block ) - flatten.each(&block) - end - - def add( a ) - @addresses.push a - end - - alias push add - - def delete( a ) - @addresses.delete a - end - - include StrategyInterface - - def accept( strategy, dummy1 = nil, dummy2 = nil ) - strategy.phrase @name - strategy.meta ':' - strategy.space - first = true - each do |mbox| - if first - first = false - else - strategy.meta ',' - end - strategy.space - mbox.accept strategy - end - strategy.meta ';' - strategy.lwsp '' - end - - end - -end # module TMail diff --git a/tracks/vendor/rails/actionmailer/lib/action_mailer/vendor/tmail/attachments.rb b/tracks/vendor/rails/actionmailer/lib/action_mailer/vendor/tmail/attachments.rb deleted file mode 100644 index cdc4ba86..00000000 --- a/tracks/vendor/rails/actionmailer/lib/action_mailer/vendor/tmail/attachments.rb +++ /dev/null @@ -1,34 +0,0 @@ -require 'stringio' - -module TMail - class Attachment < StringIO - attr_accessor :original_filename, :content_type - end - - class Mail - def has_attachments? - multipart? && parts.any? { |part| part.header["content-type"].main_type != "text" } - end - - def attachments - if multipart? - parts.collect { |part| - if part.header["content-type"].main_type != "text" - content = part.body # unquoted automatically by TMail#body - file_name = (part['content-location'] && - part['content-location'].body) || - part.sub_header("content-type", "name") || - part.sub_header("content-disposition", "filename") - - next if file_name.blank? || content.blank? - - attachment = Attachment.new(content) - attachment.original_filename = file_name.strip - attachment.content_type = part.content_type - attachment - end - }.compact - end - end - end -end diff --git a/tracks/vendor/rails/actionmailer/lib/action_mailer/vendor/tmail/base64.rb b/tracks/vendor/rails/actionmailer/lib/action_mailer/vendor/tmail/base64.rb deleted file mode 100644 index 8f89a489..00000000 --- a/tracks/vendor/rails/actionmailer/lib/action_mailer/vendor/tmail/base64.rb +++ /dev/null @@ -1,71 +0,0 @@ -# -# base64.rb -# -#-- -# Copyright (c) 1998-2003 Minero Aoki -# -# 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. -# -# Note: Originally licensed under LGPL v2+. Using MIT license for Rails -# with permission of Minero Aoki. -#++ - -module TMail - - module Base64 - - module_function - - def rb_folding_encode( str, eol = "\n", limit = 60 ) - [str].pack('m') - end - - def rb_encode( str ) - [str].pack('m').tr( "\r\n", '' ) - end - - def rb_decode( str, strict = false ) - str.unpack('m') - end - - begin - require 'tmail/base64.so' - alias folding_encode c_folding_encode - alias encode c_encode - alias decode c_decode - class << self - alias folding_encode c_folding_encode - alias encode c_encode - alias decode c_decode - end - rescue LoadError - alias folding_encode rb_folding_encode - alias encode rb_encode - alias decode rb_decode - class << self - alias folding_encode rb_folding_encode - alias encode rb_encode - alias decode rb_decode - end - end - - end - -end diff --git a/tracks/vendor/rails/actionmailer/lib/action_mailer/vendor/tmail/config.rb b/tracks/vendor/rails/actionmailer/lib/action_mailer/vendor/tmail/config.rb deleted file mode 100644 index b075299b..00000000 --- a/tracks/vendor/rails/actionmailer/lib/action_mailer/vendor/tmail/config.rb +++ /dev/null @@ -1,69 +0,0 @@ -# -# config.rb -# -#-- -# Copyright (c) 1998-2003 Minero Aoki -# -# 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. -# -# Note: Originally licensed under LGPL v2+. Using MIT license for Rails -# with permission of Minero Aoki. -#++ - -module TMail - - class Config - - def initialize( strict ) - @strict_parse = strict - @strict_base64decode = strict - end - - def strict_parse? - @strict_parse - end - - attr_writer :strict_parse - - def strict_base64decode? - @strict_base64decode - end - - attr_writer :strict_base64decode - - def new_body_port( mail ) - StringPort.new - end - - alias new_preamble_port new_body_port - alias new_part_port new_body_port - - end - - DEFAULT_CONFIG = Config.new(false) - DEFAULT_STRICT_CONFIG = Config.new(true) - - def Config.to_config( arg ) - return DEFAULT_STRICT_CONFIG if arg == true - return DEFAULT_CONFIG if arg == false - arg or DEFAULT_CONFIG - end - -end diff --git a/tracks/vendor/rails/actionmailer/lib/action_mailer/vendor/tmail/encode.rb b/tracks/vendor/rails/actionmailer/lib/action_mailer/vendor/tmail/encode.rb deleted file mode 100644 index 91bd289c..00000000 --- a/tracks/vendor/rails/actionmailer/lib/action_mailer/vendor/tmail/encode.rb +++ /dev/null @@ -1,467 +0,0 @@ -# -# encode.rb -# -#-- -# Copyright (c) 1998-2003 Minero Aoki -# -# 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. -# -# Note: Originally licensed under LGPL v2+. Using MIT license for Rails -# with permission of Minero Aoki. -#++ - -require 'nkf' -require 'tmail/base64.rb' -require 'tmail/stringio' -require 'tmail/utils' - - -module TMail - - module StrategyInterface - - def create_dest( obj ) - case obj - when nil - StringOutput.new - when String - StringOutput.new(obj) - when IO, StringOutput - obj - else - raise TypeError, 'cannot handle this type of object for dest' - end - end - module_function :create_dest - - def encoded( eol = "\r\n", charset = 'j', dest = nil ) - accept_strategy Encoder, eol, charset, dest - end - - def decoded( eol = "\n", charset = 'e', dest = nil ) - accept_strategy Decoder, eol, charset, dest - end - - alias to_s decoded - - def accept_strategy( klass, eol, charset, dest = nil ) - dest ||= '' - accept klass.new(create_dest(dest), charset, eol) - dest - end - - end - - - ### - ### MIME B encoding decoder - ### - - class Decoder - - include TextUtils - - encoded = '=\?(?:iso-2022-jp|euc-jp|shift_jis)\?[QB]\?[a-z0-9+/=]+\?=' - ENCODED_WORDS = /#{encoded}(?:\s+#{encoded})*/i - - OUTPUT_ENCODING = { - 'EUC' => 'e', - 'SJIS' => 's', - } - - def self.decode( str, encoding = nil ) - encoding ||= (OUTPUT_ENCODING[$KCODE] || 'j') - opt = '-m' + encoding - str.gsub(ENCODED_WORDS) {|s| NKF.nkf(opt, s) } - end - - def initialize( dest, encoding = nil, eol = "\n" ) - @f = StrategyInterface.create_dest(dest) - @encoding = (/\A[ejs]/ === encoding) ? encoding[0,1] : nil - @eol = eol - end - - def decode( str ) - self.class.decode(str, @encoding) - end - private :decode - - def terminate - end - - def header_line( str ) - @f << decode(str) - end - - def header_name( nm ) - @f << nm << ': ' - end - - def header_body( str ) - @f << decode(str) - end - - def space - @f << ' ' - end - - alias spc space - - def lwsp( str ) - @f << str - end - - def meta( str ) - @f << str - end - - def text( str ) - @f << decode(str) - end - - def phrase( str ) - @f << quote_phrase(decode(str)) - end - - def kv_pair( k, v ) - @f << k << '=' << v - end - - def puts( str = nil ) - @f << str if str - @f << @eol - end - - def write( str ) - @f << str - end - - end - - - ### - ### MIME B-encoding encoder - ### - - # - # FIXME: This class can handle only (euc-jp/shift_jis -> iso-2022-jp). - # - class Encoder - - include TextUtils - - BENCODE_DEBUG = false unless defined?(BENCODE_DEBUG) - - def Encoder.encode( str ) - e = new() - e.header_body str - e.terminate - e.dest.string - end - - SPACER = "\t" - MAX_LINE_LEN = 70 - - OPTIONS = { - 'EUC' => '-Ej -m0', - 'SJIS' => '-Sj -m0', - 'UTF8' => nil, # FIXME - 'NONE' => nil - } - - def initialize( dest = nil, encoding = nil, eol = "\r\n", limit = nil ) - @f = StrategyInterface.create_dest(dest) - @opt = OPTIONS[$KCODE] - @eol = eol - reset - end - - def normalize_encoding( str ) - if @opt - then NKF.nkf(@opt, str) - else str - end - end - - def reset - @text = '' - @lwsp = '' - @curlen = 0 - end - - def terminate - add_lwsp '' - reset - end - - def dest - @f - end - - def puts( str = nil ) - @f << str if str - @f << @eol - end - - def write( str ) - @f << str - end - - # - # add - # - - def header_line( line ) - scanadd line - end - - def header_name( name ) - add_text name.split(/-/).map {|i| i.capitalize }.join('-') - add_text ':' - add_lwsp ' ' - end - - def header_body( str ) - scanadd normalize_encoding(str) - end - - def space - add_lwsp ' ' - end - - alias spc space - - def lwsp( str ) - add_lwsp str.sub(/[\r\n]+[^\r\n]*\z/, '') - end - - def meta( str ) - add_text str - end - - def text( str ) - scanadd normalize_encoding(str) - end - - def phrase( str ) - str = normalize_encoding(str) - if CONTROL_CHAR === str - scanadd str - else - add_text quote_phrase(str) - end - end - - # FIXME: implement line folding - # - def kv_pair( k, v ) - return if v.nil? - v = normalize_encoding(v) - if token_safe?(v) - add_text k + '=' + v - elsif not CONTROL_CHAR === v - add_text k + '=' + quote_token(v) - else - # apply RFC2231 encoding - kv = k + '*=' + "iso-2022-jp'ja'" + encode_value(v) - add_text kv - end - end - - def encode_value( str ) - str.gsub(TOKEN_UNSAFE) {|s| '%%%02x' % s[0] } - end - - private - - def scanadd( str, force = false ) - types = '' - strs = [] - - until str.empty? - if m = /\A[^\e\t\r\n ]+/.match(str) - types << (force ? 'j' : 'a') - strs.push m[0] - - elsif m = /\A[\t\r\n ]+/.match(str) - types << 's' - strs.push m[0] - - elsif m = /\A\e../.match(str) - esc = m[0] - str = m.post_match - if esc != "\e(B" and m = /\A[^\e]+/.match(str) - types << 'j' - strs.push m[0] - end - - else - raise 'TMail FATAL: encoder scan fail' - end - (str = m.post_match) unless m.nil? - end - - do_encode types, strs - end - - def do_encode( types, strs ) - # - # result : (A|E)(S(A|E))* - # E : W(SW)* - # W : (J|A)+ but must contain J # (J|A)*J(J|A)* - # A : <> - # J : <> - # S : <> - # - # An encoding unit is `E'. - # Input (parameter `types') is (J|A)(J|A|S)*(J|A) - # - if BENCODE_DEBUG - puts - puts '-- do_encode ------------' - puts types.split(//).join(' ') - p strs - end - - e = /[ja]*j[ja]*(?:s[ja]*j[ja]*)*/ - - while m = e.match(types) - pre = m.pre_match - concat_A_S pre, strs[0, pre.size] unless pre.empty? - concat_E m[0], strs[m.begin(0) ... m.end(0)] - types = m.post_match - strs.slice! 0, m.end(0) - end - concat_A_S types, strs - end - - def concat_A_S( types, strs ) - i = 0 - types.each_byte do |t| - case t - when ?a then add_text strs[i] - when ?s then add_lwsp strs[i] - else - raise "TMail FATAL: unknown flag: #{t.chr}" - end - i += 1 - end - end - - METHOD_ID = { - ?j => :extract_J, - ?e => :extract_E, - ?a => :extract_A, - ?s => :extract_S - } - - def concat_E( types, strs ) - if BENCODE_DEBUG - puts '---- concat_E' - puts "types=#{types.split(//).join(' ')}" - puts "strs =#{strs.inspect}" - end - - flush() unless @text.empty? - - chunk = '' - strs.each_with_index do |s,i| - mid = METHOD_ID[types[i]] - until s.empty? - unless c = __send__(mid, chunk.size, s) - add_with_encode chunk unless chunk.empty? - flush - chunk = '' - fold - c = __send__(mid, 0, s) - raise 'TMail FATAL: extract fail' unless c - end - chunk << c - end - end - add_with_encode chunk unless chunk.empty? - end - - def extract_J( chunksize, str ) - size = max_bytes(chunksize, str.size) - 6 - size = (size % 2 == 0) ? (size) : (size - 1) - return nil if size <= 0 - "\e$B#{str.slice!(0, size)}\e(B" - end - - def extract_A( chunksize, str ) - size = max_bytes(chunksize, str.size) - return nil if size <= 0 - str.slice!(0, size) - end - - alias extract_S extract_A - - def max_bytes( chunksize, ssize ) - (restsize() - '=?iso-2022-jp?B??='.size) / 4 * 3 - chunksize - end - - # - # free length buffer - # - - def add_text( str ) - @text << str - # puts '---- text -------------------------------------' - # puts "+ #{str.inspect}" - # puts "txt >>>#{@text.inspect}<<<" - end - - def add_with_encode( str ) - @text << "=?iso-2022-jp?B?#{Base64.encode(str)}?=" - end - - def add_lwsp( lwsp ) - # puts '---- lwsp -------------------------------------' - # puts "+ #{lwsp.inspect}" - fold if restsize() <= 0 - flush - @lwsp = lwsp - end - - def flush - # puts '---- flush ----' - # puts "spc >>>#{@lwsp.inspect}<<<" - # puts "txt >>>#{@text.inspect}<<<" - @f << @lwsp << @text - @curlen += (@lwsp.size + @text.size) - @text = '' - @lwsp = '' - end - - def fold - # puts '---- fold ----' - @f << @eol - @curlen = 0 - @lwsp = SPACER - end - - def restsize - MAX_LINE_LEN - (@curlen + @lwsp.size + @text.size) - end - - end - -end # module TMail diff --git a/tracks/vendor/rails/actionmailer/lib/action_mailer/vendor/tmail/facade.rb b/tracks/vendor/rails/actionmailer/lib/action_mailer/vendor/tmail/facade.rb deleted file mode 100644 index 1ecd64bf..00000000 --- a/tracks/vendor/rails/actionmailer/lib/action_mailer/vendor/tmail/facade.rb +++ /dev/null @@ -1,552 +0,0 @@ -# -# facade.rb -# -#-- -# Copyright (c) 1998-2003 Minero Aoki -# -# 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. -# -# Note: Originally licensed under LGPL v2+. Using MIT license for Rails -# with permission of Minero Aoki. -#++ - -require 'tmail/utils' - - -module TMail - - class Mail - - def header_string( name, default = nil ) - h = @header[name.downcase] or return default - h.to_s - end - - ### - ### attributes - ### - - include TextUtils - - def set_string_array_attr( key, strs ) - strs.flatten! - if strs.empty? - @header.delete key.downcase - else - store key, strs.join(', ') - end - strs - end - private :set_string_array_attr - - def set_string_attr( key, str ) - if str - store key, str - else - @header.delete key.downcase - end - str - end - private :set_string_attr - - def set_addrfield( name, arg ) - if arg - h = HeaderField.internal_new(name, @config) - h.addrs.replace [arg].flatten - @header[name] = h - else - @header.delete name - end - arg - end - private :set_addrfield - - def addrs2specs( addrs ) - return nil unless addrs - list = addrs.map {|addr| - if addr.address_group? - then addr.map {|a| a.spec } - else addr.spec - end - }.flatten - return nil if list.empty? - list - end - private :addrs2specs - - - # - # date time - # - - def date( default = nil ) - if h = @header['date'] - h.date - else - default - end - end - - def date=( time ) - if time - store 'Date', time2str(time) - else - @header.delete 'date' - end - time - end - - def strftime( fmt, default = nil ) - if t = date - t.strftime(fmt) - else - default - end - end - - - # - # destination - # - - def to_addrs( default = nil ) - if h = @header['to'] - h.addrs - else - default - end - end - - def cc_addrs( default = nil ) - if h = @header['cc'] - h.addrs - else - default - end - end - - def bcc_addrs( default = nil ) - if h = @header['bcc'] - h.addrs - else - default - end - end - - def to_addrs=( arg ) - set_addrfield 'to', arg - end - - def cc_addrs=( arg ) - set_addrfield 'cc', arg - end - - def bcc_addrs=( arg ) - set_addrfield 'bcc', arg - end - - def to( default = nil ) - addrs2specs(to_addrs(nil)) || default - end - - def cc( default = nil ) - addrs2specs(cc_addrs(nil)) || default - end - - def bcc( default = nil ) - addrs2specs(bcc_addrs(nil)) || default - end - - def to=( *strs ) - set_string_array_attr 'To', strs - end - - def cc=( *strs ) - set_string_array_attr 'Cc', strs - end - - def bcc=( *strs ) - set_string_array_attr 'Bcc', strs - end - - - # - # originator - # - - def from_addrs( default = nil ) - if h = @header['from'] - h.addrs - else - default - end - end - - def from_addrs=( arg ) - set_addrfield 'from', arg - end - - def from( default = nil ) - addrs2specs(from_addrs(nil)) || default - end - - def from=( *strs ) - set_string_array_attr 'From', strs - end - - def friendly_from( default = nil ) - h = @header['from'] - a, = h.addrs - return default unless a - return a.phrase if a.phrase - return h.comments.join(' ') unless h.comments.empty? - a.spec - end - - - def reply_to_addrs( default = nil ) - if h = @header['reply-to'] - h.addrs - else - default - end - end - - def reply_to_addrs=( arg ) - set_addrfield 'reply-to', arg - end - - def reply_to( default = nil ) - addrs2specs(reply_to_addrs(nil)) || default - end - - def reply_to=( *strs ) - set_string_array_attr 'Reply-To', strs - end - - - def sender_addr( default = nil ) - f = @header['sender'] or return default - f.addr or return default - end - - def sender_addr=( addr ) - if addr - h = HeaderField.internal_new('sender', @config) - h.addr = addr - @header['sender'] = h - else - @header.delete 'sender' - end - addr - end - - def sender( default ) - f = @header['sender'] or return default - a = f.addr or return default - a.spec - end - - def sender=( str ) - set_string_attr 'Sender', str - end - - - # - # subject - # - - def subject( default = nil ) - if h = @header['subject'] - h.body - else - default - end - end - alias quoted_subject subject - - def subject=( str ) - set_string_attr 'Subject', str - end - - - # - # identity & threading - # - - def message_id( default = nil ) - if h = @header['message-id'] - h.id || default - else - default - end - end - - def message_id=( str ) - set_string_attr 'Message-Id', str - end - - def in_reply_to( default = nil ) - if h = @header['in-reply-to'] - h.ids - else - default - end - end - - def in_reply_to=( *idstrs ) - set_string_array_attr 'In-Reply-To', idstrs - end - - def references( default = nil ) - if h = @header['references'] - h.refs - else - default - end - end - - def references=( *strs ) - set_string_array_attr 'References', strs - end - - - # - # MIME headers - # - - def mime_version( default = nil ) - if h = @header['mime-version'] - h.version || default - else - default - end - end - - def mime_version=( m, opt = nil ) - if opt - if h = @header['mime-version'] - h.major = m - h.minor = opt - else - store 'Mime-Version', "#{m}.#{opt}" - end - else - store 'Mime-Version', m - end - m - end - - - def content_type( default = nil ) - if h = @header['content-type'] - h.content_type || default - else - default - end - end - - def main_type( default = nil ) - if h = @header['content-type'] - h.main_type || default - else - default - end - end - - def sub_type( default = nil ) - if h = @header['content-type'] - h.sub_type || default - else - default - end - end - - def set_content_type( str, sub = nil, param = nil ) - if sub - main, sub = str, sub - else - main, sub = str.split(%r, 2) - raise ArgumentError, "sub type missing: #{str.inspect}" unless sub - end - if h = @header['content-type'] - h.main_type = main - h.sub_type = sub - h.params.clear - else - store 'Content-Type', "#{main}/#{sub}" - end - @header['content-type'].params.replace param if param - - str - end - - alias content_type= set_content_type - - def type_param( name, default = nil ) - if h = @header['content-type'] - h[name] || default - else - default - end - end - - def charset( default = nil ) - if h = @header['content-type'] - h['charset'] or default - else - default - end - end - - def charset=( str ) - if str - if h = @header[ 'content-type' ] - h['charset'] = str - else - store 'Content-Type', "text/plain; charset=#{str}" - end - end - str - end - - - def transfer_encoding( default = nil ) - if h = @header['content-transfer-encoding'] - h.encoding || default - else - default - end - end - - def transfer_encoding=( str ) - set_string_attr 'Content-Transfer-Encoding', str - end - - alias encoding transfer_encoding - alias encoding= transfer_encoding= - alias content_transfer_encoding transfer_encoding - alias content_transfer_encoding= transfer_encoding= - - - def disposition( default = nil ) - if h = @header['content-disposition'] - h.disposition || default - else - default - end - end - - alias content_disposition disposition - - def set_disposition( str, params = nil ) - if h = @header['content-disposition'] - h.disposition = str - h.params.clear - else - store('Content-Disposition', str) - h = @header['content-disposition'] - end - h.params.replace params if params - end - - alias disposition= set_disposition - alias set_content_disposition set_disposition - alias content_disposition= set_disposition - - def disposition_param( name, default = nil ) - if h = @header['content-disposition'] - h[name] || default - else - default - end - end - - ### - ### utils - ### - - def create_reply - mail = TMail::Mail.parse('') - mail.subject = 'Re: ' + subject('').sub(/\A(?:\[[^\]]+\])?(?:\s*Re:)*\s*/i, '') - mail.to_addrs = reply_addresses([]) - mail.in_reply_to = [message_id(nil)].compact - mail.references = references([]) + [message_id(nil)].compact - mail.mime_version = '1.0' - mail - end - - - def base64_encode - store 'Content-Transfer-Encoding', 'Base64' - self.body = Base64.folding_encode(self.body) - end - - def base64_decode - if /base64/i === self.transfer_encoding('') - store 'Content-Transfer-Encoding', '8bit' - self.body = Base64.decode(self.body, @config.strict_base64decode?) - end - end - - - def destinations( default = nil ) - ret = [] - %w( to cc bcc ).each do |nm| - if h = @header[nm] - h.addrs.each {|i| ret.push i.address } - end - end - ret.empty? ? default : ret - end - - def each_destination( &block ) - destinations([]).each do |i| - if Address === i - yield i - else - i.each(&block) - end - end - end - - alias each_dest each_destination - - - def reply_addresses( default = nil ) - reply_to_addrs(nil) or from_addrs(nil) or default - end - - def error_reply_addresses( default = nil ) - if s = sender(nil) - [s] - else - from_addrs(default) - end - end - - - def multipart? - main_type('').downcase == 'multipart' - end - - end # class Mail - -end # module TMail diff --git a/tracks/vendor/rails/actionmailer/lib/action_mailer/vendor/tmail/header.rb b/tracks/vendor/rails/actionmailer/lib/action_mailer/vendor/tmail/header.rb deleted file mode 100644 index be97803d..00000000 --- a/tracks/vendor/rails/actionmailer/lib/action_mailer/vendor/tmail/header.rb +++ /dev/null @@ -1,914 +0,0 @@ -# -# header.rb -# -#-- -# Copyright (c) 1998-2003 Minero Aoki -# -# 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. -# -# Note: Originally licensed under LGPL v2+. Using MIT license for Rails -# with permission of Minero Aoki. -#++ - -require 'tmail/encode' -require 'tmail/address' -require 'tmail/parser' -require 'tmail/config' -require 'tmail/utils' - - -module TMail - - class HeaderField - - include TextUtils - - class << self - - alias newobj new - - def new( name, body, conf = DEFAULT_CONFIG ) - klass = FNAME_TO_CLASS[name.downcase] || UnstructuredHeader - klass.newobj body, conf - end - - def new_from_port( port, name, conf = DEFAULT_CONFIG ) - re = Regep.new('\A(' + Regexp.quote(name) + '):', 'i') - str = nil - port.ropen {|f| - f.each do |line| - if m = re.match(line) then str = m.post_match.strip - elsif str and /\A[\t ]/ === line then str << ' ' << line.strip - elsif /\A-*\s*\z/ === line then break - elsif str then break - end - end - } - new(name, str, Config.to_config(conf)) - end - - def internal_new( name, conf ) - FNAME_TO_CLASS[name].newobj('', conf, true) - end - - end # class << self - - def initialize( body, conf, intern = false ) - @body = body - @config = conf - - @illegal = false - @parsed = false - if intern - @parsed = true - parse_init - end - end - - def inspect - "#<#{self.class} #{@body.inspect}>" - end - - def illegal? - @illegal - end - - def empty? - ensure_parsed - return true if @illegal - isempty? - end - - private - - def ensure_parsed - return if @parsed - @parsed = true - parse - end - - # defabstract parse - # end - - def clear_parse_status - @parsed = false - @illegal = false - end - - public - - def body - ensure_parsed - v = Decoder.new(s = '') - do_accept v - v.terminate - s - end - - def body=( str ) - @body = str - clear_parse_status - end - - include StrategyInterface - - def accept( strategy, dummy1 = nil, dummy2 = nil ) - ensure_parsed - do_accept strategy - strategy.terminate - end - - # abstract do_accept - - end - - - class UnstructuredHeader < HeaderField - - def body - ensure_parsed - @body - end - - def body=( arg ) - ensure_parsed - @body = arg - end - - private - - def parse_init - end - - def parse - @body = Decoder.decode(@body.gsub(/\n|\r\n|\r/, '')) - end - - def isempty? - not @body - end - - def do_accept( strategy ) - strategy.text @body - end - - end - - - class StructuredHeader < HeaderField - - def comments - ensure_parsed - @comments - end - - private - - def parse - save = nil - - begin - parse_init - do_parse - rescue SyntaxError - if not save and mime_encoded? @body - save = @body - @body = Decoder.decode(save) - retry - elsif save - @body = save - end - - @illegal = true - raise if @config.strict_parse? - end - end - - def parse_init - @comments = [] - init - end - - def do_parse - obj = Parser.parse(self.class::PARSE_TYPE, @body, @comments) - set obj if obj - end - - end - - - class DateTimeHeader < StructuredHeader - - PARSE_TYPE = :DATETIME - - def date - ensure_parsed - @date - end - - def date=( arg ) - ensure_parsed - @date = arg - end - - private - - def init - @date = nil - end - - def set( t ) - @date = t - end - - def isempty? - not @date - end - - def do_accept( strategy ) - strategy.meta time2str(@date) - end - - end - - - class AddressHeader < StructuredHeader - - PARSE_TYPE = :MADDRESS - - def addrs - ensure_parsed - @addrs - end - - private - - def init - @addrs = [] - end - - def set( a ) - @addrs = a - end - - def isempty? - @addrs.empty? - end - - def do_accept( strategy ) - first = true - @addrs.each do |a| - if first - first = false - else - strategy.meta ',' - strategy.space - end - a.accept strategy - end - - @comments.each do |c| - strategy.space - strategy.meta '(' - strategy.text c - strategy.meta ')' - end - end - - end - - - class ReturnPathHeader < AddressHeader - - PARSE_TYPE = :RETPATH - - def addr - addrs()[0] - end - - def spec - a = addr() or return nil - a.spec - end - - def routes - a = addr() or return nil - a.routes - end - - private - - def do_accept( strategy ) - a = addr() - - strategy.meta '<' - unless a.routes.empty? - strategy.meta a.routes.map {|i| '@' + i }.join(',') - strategy.meta ':' - end - spec = a.spec - strategy.meta spec if spec - strategy.meta '>' - end - - end - - - class SingleAddressHeader < AddressHeader - - def addr - addrs()[0] - end - - private - - def do_accept( strategy ) - a = addr() - a.accept strategy - @comments.each do |c| - strategy.space - strategy.meta '(' - strategy.text c - strategy.meta ')' - end - end - - end - - - class MessageIdHeader < StructuredHeader - - def id - ensure_parsed - @id - end - - def id=( arg ) - ensure_parsed - @id = arg - end - - private - - def init - @id = nil - end - - def isempty? - not @id - end - - def do_parse - @id = @body.slice(MESSAGE_ID) or - raise SyntaxError, "wrong Message-ID format: #{@body}" - end - - def do_accept( strategy ) - strategy.meta @id - end - - end - - - class ReferencesHeader < StructuredHeader - - def refs - ensure_parsed - @refs - end - - def each_id - self.refs.each do |i| - yield i if MESSAGE_ID === i - end - end - - def ids - ensure_parsed - @ids - end - - def each_phrase - self.refs.each do |i| - yield i unless MESSAGE_ID === i - end - end - - def phrases - ret = [] - each_phrase {|i| ret.push i } - ret - end - - private - - def init - @refs = [] - @ids = [] - end - - def isempty? - @ids.empty? - end - - def do_parse - str = @body - while m = MESSAGE_ID.match(str) - pre = m.pre_match.strip - @refs.push pre unless pre.empty? - @refs.push s = m[0] - @ids.push s - str = m.post_match - end - str = str.strip - @refs.push str unless str.empty? - end - - def do_accept( strategy ) - first = true - @ids.each do |i| - if first - first = false - else - strategy.space - end - strategy.meta i - end - end - - end - - - class ReceivedHeader < StructuredHeader - - PARSE_TYPE = :RECEIVED - - def from - ensure_parsed - @from - end - - def from=( arg ) - ensure_parsed - @from = arg - end - - def by - ensure_parsed - @by - end - - def by=( arg ) - ensure_parsed - @by = arg - end - - def via - ensure_parsed - @via - end - - def via=( arg ) - ensure_parsed - @via = arg - end - - def with - ensure_parsed - @with - end - - def id - ensure_parsed - @id - end - - def id=( arg ) - ensure_parsed - @id = arg - end - - def _for - ensure_parsed - @_for - end - - def _for=( arg ) - ensure_parsed - @_for = arg - end - - def date - ensure_parsed - @date - end - - def date=( arg ) - ensure_parsed - @date = arg - end - - private - - def init - @from = @by = @via = @with = @id = @_for = nil - @with = [] - @date = nil - end - - def set( args ) - @from, @by, @via, @with, @id, @_for, @date = *args - end - - def isempty? - @with.empty? and not (@from or @by or @via or @id or @_for or @date) - end - - def do_accept( strategy ) - list = [] - list.push 'from ' + @from if @from - list.push 'by ' + @by if @by - list.push 'via ' + @via if @via - @with.each do |i| - list.push 'with ' + i - end - list.push 'id ' + @id if @id - list.push 'for <' + @_for + '>' if @_for - - first = true - list.each do |i| - strategy.space unless first - strategy.meta i - first = false - end - if @date - strategy.meta ';' - strategy.space - strategy.meta time2str(@date) - end - end - - end - - - class KeywordsHeader < StructuredHeader - - PARSE_TYPE = :KEYWORDS - - def keys - ensure_parsed - @keys - end - - private - - def init - @keys = [] - end - - def set( a ) - @keys = a - end - - def isempty? - @keys.empty? - end - - def do_accept( strategy ) - first = true - @keys.each do |i| - if first - first = false - else - strategy.meta ',' - end - strategy.meta i - end - end - - end - - - class EncryptedHeader < StructuredHeader - - PARSE_TYPE = :ENCRYPTED - - def encrypter - ensure_parsed - @encrypter - end - - def encrypter=( arg ) - ensure_parsed - @encrypter = arg - end - - def keyword - ensure_parsed - @keyword - end - - def keyword=( arg ) - ensure_parsed - @keyword = arg - end - - private - - def init - @encrypter = nil - @keyword = nil - end - - def set( args ) - @encrypter, @keyword = args - end - - def isempty? - not (@encrypter or @keyword) - end - - def do_accept( strategy ) - if @key - strategy.meta @encrypter + ',' - strategy.space - strategy.meta @keyword - else - strategy.meta @encrypter - end - end - - end - - - class MimeVersionHeader < StructuredHeader - - PARSE_TYPE = :MIMEVERSION - - def major - ensure_parsed - @major - end - - def major=( arg ) - ensure_parsed - @major = arg - end - - def minor - ensure_parsed - @minor - end - - def minor=( arg ) - ensure_parsed - @minor = arg - end - - def version - sprintf('%d.%d', major, minor) - end - - private - - def init - @major = nil - @minor = nil - end - - def set( args ) - @major, @minor = *args - end - - def isempty? - not (@major or @minor) - end - - def do_accept( strategy ) - strategy.meta sprintf('%d.%d', @major, @minor) - end - - end - - - class ContentTypeHeader < StructuredHeader - - PARSE_TYPE = :CTYPE - - def main_type - ensure_parsed - @main - end - - def main_type=( arg ) - ensure_parsed - @main = arg.downcase - end - - def sub_type - ensure_parsed - @sub - end - - def sub_type=( arg ) - ensure_parsed - @sub = arg.downcase - end - - def content_type - ensure_parsed - @sub ? sprintf('%s/%s', @main, @sub) : @main - end - - def params - ensure_parsed - @params - end - - def []( key ) - ensure_parsed - @params and @params[key] - end - - def []=( key, val ) - ensure_parsed - (@params ||= {})[key] = val - end - - private - - def init - @main = @sub = @params = nil - end - - def set( args ) - @main, @sub, @params = *args - end - - def isempty? - not (@main or @sub) - end - - def do_accept( strategy ) - if @sub - strategy.meta sprintf('%s/%s', @main, @sub) - else - strategy.meta @main - end - @params.each do |k,v| - if v - strategy.meta ';' - strategy.space - strategy.kv_pair k, v - end - end - end - - end - - - class ContentTransferEncodingHeader < StructuredHeader - - PARSE_TYPE = :CENCODING - - def encoding - ensure_parsed - @encoding - end - - def encoding=( arg ) - ensure_parsed - @encoding = arg - end - - private - - def init - @encoding = nil - end - - def set( s ) - @encoding = s - end - - def isempty? - not @encoding - end - - def do_accept( strategy ) - strategy.meta @encoding.capitalize - end - - end - - - class ContentDispositionHeader < StructuredHeader - - PARSE_TYPE = :CDISPOSITION - - def disposition - ensure_parsed - @disposition - end - - def disposition=( str ) - ensure_parsed - @disposition = str.downcase - end - - def params - ensure_parsed - @params - end - - def []( key ) - ensure_parsed - @params and @params[key] - end - - def []=( key, val ) - ensure_parsed - (@params ||= {})[key] = val - end - - private - - def init - @disposition = @params = nil - end - - def set( args ) - @disposition, @params = *args - end - - def isempty? - not @disposition and (not @params or @params.empty?) - end - - def do_accept( strategy ) - strategy.meta @disposition - @params.each do |k,v| - strategy.meta ';' - strategy.space - strategy.kv_pair k, v - end - end - - end - - - class HeaderField # redefine - - FNAME_TO_CLASS = { - 'date' => DateTimeHeader, - 'resent-date' => DateTimeHeader, - 'to' => AddressHeader, - 'cc' => AddressHeader, - 'bcc' => AddressHeader, - 'from' => AddressHeader, - 'reply-to' => AddressHeader, - 'resent-to' => AddressHeader, - 'resent-cc' => AddressHeader, - 'resent-bcc' => AddressHeader, - 'resent-from' => AddressHeader, - 'resent-reply-to' => AddressHeader, - 'sender' => SingleAddressHeader, - 'resent-sender' => SingleAddressHeader, - 'return-path' => ReturnPathHeader, - 'message-id' => MessageIdHeader, - 'resent-message-id' => MessageIdHeader, - 'in-reply-to' => ReferencesHeader, - 'received' => ReceivedHeader, - 'references' => ReferencesHeader, - 'keywords' => KeywordsHeader, - 'encrypted' => EncryptedHeader, - 'mime-version' => MimeVersionHeader, - 'content-type' => ContentTypeHeader, - 'content-transfer-encoding' => ContentTransferEncodingHeader, - 'content-disposition' => ContentDispositionHeader, - 'content-id' => MessageIdHeader, - 'subject' => UnstructuredHeader, - 'comments' => UnstructuredHeader, - 'content-description' => UnstructuredHeader - } - - end - -end # module TMail diff --git a/tracks/vendor/rails/actionmailer/lib/action_mailer/vendor/tmail/info.rb b/tracks/vendor/rails/actionmailer/lib/action_mailer/vendor/tmail/info.rb deleted file mode 100644 index 5c115d58..00000000 --- a/tracks/vendor/rails/actionmailer/lib/action_mailer/vendor/tmail/info.rb +++ /dev/null @@ -1,35 +0,0 @@ -# -# info.rb -# -#-- -# Copyright (c) 1998-2003 Minero Aoki -# -# 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. -# -# Note: Originally licensed under LGPL v2+. Using MIT license for Rails -# with permission of Minero Aoki. -#++ - -module TMail - - Version = '0.10.7' - Copyright = 'Copyright (c) 1998-2002 Minero Aoki' - -end diff --git a/tracks/vendor/rails/actionmailer/lib/action_mailer/vendor/tmail/loader.rb b/tracks/vendor/rails/actionmailer/lib/action_mailer/vendor/tmail/loader.rb deleted file mode 100644 index 79073154..00000000 --- a/tracks/vendor/rails/actionmailer/lib/action_mailer/vendor/tmail/loader.rb +++ /dev/null @@ -1 +0,0 @@ -require 'tmail/mailbox' diff --git a/tracks/vendor/rails/actionmailer/lib/action_mailer/vendor/tmail/mail.rb b/tracks/vendor/rails/actionmailer/lib/action_mailer/vendor/tmail/mail.rb deleted file mode 100644 index e11fa0f0..00000000 --- a/tracks/vendor/rails/actionmailer/lib/action_mailer/vendor/tmail/mail.rb +++ /dev/null @@ -1,447 +0,0 @@ -# -# mail.rb -# -#-- -# Copyright (c) 1998-2003 Minero Aoki -# -# 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. -# -# Note: Originally licensed under LGPL v2+. Using MIT license for Rails -# with permission of Minero Aoki. -#++ - -require 'tmail/facade' -require 'tmail/encode' -require 'tmail/header' -require 'tmail/port' -require 'tmail/config' -require 'tmail/utils' -require 'tmail/attachments' -require 'tmail/quoting' -require 'socket' - - -module TMail - - class Mail - - class << self - def load( fname ) - new(FilePort.new(fname)) - end - - alias load_from load - alias loadfrom load - - def parse( str ) - new(StringPort.new(str)) - end - end - - def initialize( port = nil, conf = DEFAULT_CONFIG ) - @port = port || StringPort.new - @config = Config.to_config(conf) - - @header = {} - @body_port = nil - @body_parsed = false - @epilogue = '' - @parts = [] - - @port.ropen {|f| - parse_header f - parse_body f unless @port.reproducible? - } - end - - attr_reader :port - - def inspect - "\#<#{self.class} port=#{@port.inspect} bodyport=#{@body_port.inspect}>" - end - - # - # to_s interfaces - # - - public - - include StrategyInterface - - def write_back( eol = "\n", charset = 'e' ) - parse_body - @port.wopen {|stream| encoded eol, charset, stream } - end - - def accept( strategy ) - with_multipart_encoding(strategy) { - ordered_each do |name, field| - next if field.empty? - strategy.header_name canonical(name) - field.accept strategy - strategy.puts - end - strategy.puts - body_port().ropen {|r| - strategy.write r.read - } - } - end - - private - - def canonical( name ) - name.split(/-/).map {|s| s.capitalize }.join('-') - end - - def with_multipart_encoding( strategy ) - if parts().empty? # DO NOT USE @parts - yield - - else - bound = ::TMail.new_boundary - if @header.key? 'content-type' - @header['content-type'].params['boundary'] = bound - else - store 'Content-Type', % - end - - yield - - parts().each do |tm| - strategy.puts - strategy.puts '--' + bound - tm.accept strategy - end - strategy.puts - strategy.puts '--' + bound + '--' - strategy.write epilogue() - end - end - - ### - ### header - ### - - public - - ALLOW_MULTIPLE = { - 'received' => true, - 'resent-date' => true, - 'resent-from' => true, - 'resent-sender' => true, - 'resent-to' => true, - 'resent-cc' => true, - 'resent-bcc' => true, - 'resent-message-id' => true, - 'comments' => true, - 'keywords' => true - } - USE_ARRAY = ALLOW_MULTIPLE - - def header - @header.dup - end - - def []( key ) - @header[key.downcase] - end - - def sub_header(key, param) - (hdr = self[key]) ? hdr[param] : nil - end - - alias fetch [] - - def []=( key, val ) - dkey = key.downcase - - if val.nil? - @header.delete dkey - return nil - end - - case val - when String - header = new_hf(key, val) - when HeaderField - ; - when Array - ALLOW_MULTIPLE.include? dkey or - raise ArgumentError, "#{key}: Header must not be multiple" - @header[dkey] = val - return val - else - header = new_hf(key, val.to_s) - end - if ALLOW_MULTIPLE.include? dkey - (@header[dkey] ||= []).push header - else - @header[dkey] = header - end - - val - end - - alias store []= - - def each_header - @header.each do |key, val| - [val].flatten.each {|v| yield key, v } - end - end - - alias each_pair each_header - - def each_header_name( &block ) - @header.each_key(&block) - end - - alias each_key each_header_name - - def each_field( &block ) - @header.values.flatten.each(&block) - end - - alias each_value each_field - - FIELD_ORDER = %w( - return-path received - resent-date resent-from resent-sender resent-to - resent-cc resent-bcc resent-message-id - date from sender reply-to to cc bcc - message-id in-reply-to references - subject comments keywords - mime-version content-type content-transfer-encoding - content-disposition content-description - ) - - def ordered_each - list = @header.keys - FIELD_ORDER.each do |name| - if list.delete(name) - [@header[name]].flatten.each {|v| yield name, v } - end - end - list.each do |name| - [@header[name]].flatten.each {|v| yield name, v } - end - end - - def clear - @header.clear - end - - def delete( key ) - @header.delete key.downcase - end - - def delete_if - @header.delete_if do |key,val| - if Array === val - val.delete_if {|v| yield key, v } - val.empty? - else - yield key, val - end - end - end - - def keys - @header.keys - end - - def key?( key ) - @header.key? key.downcase - end - - def values_at( *args ) - args.map {|k| @header[k.downcase] }.flatten - end - - alias indexes values_at - alias indices values_at - - private - - def parse_header( f ) - name = field = nil - unixfrom = nil - - while line = f.gets - case line - when /\A[ \t]/ # continue from prev line - raise SyntaxError, 'mail is began by space' unless field - field << ' ' << line.strip - - when /\A([^\: \t]+):\s*/ # new header line - add_hf name, field if field - name = $1 - field = $' #.strip - - when /\A\-*\s*\z/ # end of header - add_hf name, field if field - name = field = nil - break - - when /\AFrom (\S+)/ - unixfrom = $1 - - when /^charset=.*/ - - else - raise SyntaxError, "wrong mail header: '#{line.inspect}'" - end - end - add_hf name, field if name - - if unixfrom - add_hf 'Return-Path', "<#{unixfrom}>" unless @header['return-path'] - end - end - - def add_hf( name, field ) - key = name.downcase - field = new_hf(name, field) - - if ALLOW_MULTIPLE.include? key - (@header[key] ||= []).push field - else - @header[key] = field - end - end - - def new_hf( name, field ) - HeaderField.new(name, field, @config) - end - - ### - ### body - ### - - public - - def body_port - parse_body - @body_port - end - - def each( &block ) - body_port().ropen {|f| f.each(&block) } - end - - def quoted_body - parse_body - @body_port.ropen {|f| - return f.read - } - end - - def body=( str ) - parse_body - @body_port.wopen {|f| f.write str } - str - end - - alias preamble body - alias preamble= body= - - def epilogue - parse_body - @epilogue.dup - end - - def epilogue=( str ) - parse_body - @epilogue = str - str - end - - def parts - parse_body - @parts - end - - def each_part( &block ) - parts().each(&block) - end - - private - - def parse_body( f = nil ) - return if @body_parsed - if f - parse_body_0 f - else - @port.ropen {|f| - skip_header f - parse_body_0 f - } - end - @body_parsed = true - end - - def skip_header( f ) - while line = f.gets - return if /\A[\r\n]*\z/ === line - end - end - - def parse_body_0( f ) - if multipart? - read_multipart f - else - @body_port = @config.new_body_port(self) - @body_port.wopen {|w| - w.write f.read - } - end - end - - def read_multipart( src ) - bound = @header['content-type'].params['boundary'] - is_sep = /\A--#{Regexp.quote bound}(?:--)?[ \t]*(?:\n|\r\n|\r)/ - lastbound = "--#{bound}--" - - ports = [ @config.new_preamble_port(self) ] - begin - f = ports.last.wopen - while line = src.gets - if is_sep === line - f.close - break if line.strip == lastbound - ports.push @config.new_part_port(self) - f = ports.last.wopen - else - f << line - end - end - @epilogue = (src.read || '') - ensure - f.close if f and not f.closed? - end - - @body_port = ports.shift - @parts = ports.map {|p| self.class.new(p, @config) } - end - - end # class Mail - -end # module TMail diff --git a/tracks/vendor/rails/actionmailer/lib/action_mailer/vendor/tmail/mailbox.rb b/tracks/vendor/rails/actionmailer/lib/action_mailer/vendor/tmail/mailbox.rb deleted file mode 100644 index d85915ed..00000000 --- a/tracks/vendor/rails/actionmailer/lib/action_mailer/vendor/tmail/mailbox.rb +++ /dev/null @@ -1,433 +0,0 @@ -# -# mailbox.rb -# -#-- -# Copyright (c) 1998-2003 Minero Aoki -# -# 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. -# -# Note: Originally licensed under LGPL v2+. Using MIT license for Rails -# with permission of Minero Aoki. -#++ - -require 'tmail/port' -require 'socket' -require 'mutex_m' - - -unless [].respond_to?(:sort_by) -module Enumerable#:nodoc: - def sort_by - map {|i| [yield(i), i] }.sort {|a,b| a.first <=> b.first }.map {|i| i[1] } - end -end -end - - -module TMail - - class MhMailbox - - PORT_CLASS = MhPort - - def initialize( dir ) - edir = File.expand_path(dir) - raise ArgumentError, "not directory: #{dir}"\ - unless FileTest.directory? edir - @dirname = edir - @last_file = nil - @last_atime = nil - end - - def directory - @dirname - end - - alias dirname directory - - attr_accessor :last_atime - - def inspect - "#<#{self.class} #{@dirname}>" - end - - def close - end - - def new_port - PORT_CLASS.new(next_file_name()) - end - - def each_port - mail_files().each do |path| - yield PORT_CLASS.new(path) - end - @last_atime = Time.now - end - - alias each each_port - - def reverse_each_port - mail_files().reverse_each do |path| - yield PORT_CLASS.new(path) - end - @last_atime = Time.now - end - - alias reverse_each reverse_each_port - - # old #each_mail returns Port - #def each_mail - # each_port do |port| - # yield Mail.new(port) - # end - #end - - def each_new_port( mtime = nil, &block ) - mtime ||= @last_atime - return each_port(&block) unless mtime - return unless File.mtime(@dirname) >= mtime - - mail_files().each do |path| - yield PORT_CLASS.new(path) if File.mtime(path) > mtime - end - @last_atime = Time.now - end - - private - - def mail_files - Dir.entries(@dirname)\ - .select {|s| /\A\d+\z/ === s }\ - .map {|s| s.to_i }\ - .sort\ - .map {|i| "#{@dirname}/#{i}" }\ - .select {|path| FileTest.file? path } - end - - def next_file_name - unless n = @last_file - n = 0 - Dir.entries(@dirname)\ - .select {|s| /\A\d+\z/ === s }\ - .map {|s| s.to_i }.sort\ - .each do |i| - next unless FileTest.file? "#{@dirname}/#{i}" - n = i - end - end - begin - n += 1 - end while FileTest.exist? "#{@dirname}/#{n}" - @last_file = n - - "#{@dirname}/#{n}" - end - - end # MhMailbox - - MhLoader = MhMailbox - - - class UNIXMbox - - def UNIXMbox.lock( fname ) - begin - f = File.open(fname) - f.flock File::LOCK_EX - yield f - ensure - f.flock File::LOCK_UN - f.close if f and not f.closed? - end - end - - class << self - alias newobj new - end - - def UNIXMbox.new( fname, tmpdir = nil, readonly = false ) - tmpdir = ENV['TEMP'] || ENV['TMP'] || '/tmp' - newobj(fname, "#{tmpdir}/ruby_tmail_#{$$}_#{rand()}", readonly, false) - end - - def UNIXMbox.static_new( fname, dir, readonly = false ) - newobj(fname, dir, readonly, true) - end - - def initialize( fname, mhdir, readonly, static ) - @filename = fname - @readonly = readonly - @closed = false - - Dir.mkdir mhdir - @real = MhMailbox.new(mhdir) - @finalizer = UNIXMbox.mkfinal(@real, @filename, !@readonly, !static) - ObjectSpace.define_finalizer self, @finalizer - end - - def UNIXMbox.mkfinal( mh, mboxfile, writeback_p, cleanup_p ) - lambda { - if writeback_p - lock(mboxfile) {|f| - mh.each_port do |port| - f.puts create_from_line(port) - port.ropen {|r| - f.puts r.read - } - end - } - end - if cleanup_p - Dir.foreach(mh.dirname) do |fname| - next if /\A\.\.?\z/ === fname - File.unlink "#{mh.dirname}/#{fname}" - end - Dir.rmdir mh.dirname - end - } - end - - # make _From line - def UNIXMbox.create_from_line( port ) - sprintf 'From %s %s', - fromaddr(), TextUtils.time2str(File.mtime(port.filename)) - end - - def UNIXMbox.fromaddr - h = HeaderField.new_from_port(port, 'Return-Path') || - HeaderField.new_from_port(port, 'From') or return 'nobody' - a = h.addrs[0] or return 'nobody' - a.spec - end - private_class_method :fromaddr - - def close - return if @closed - - ObjectSpace.undefine_finalizer self - @finalizer.call - @finalizer = nil - @real = nil - @closed = true - @updated = nil - end - - def each_port( &block ) - close_check - update - @real.each_port(&block) - end - - alias each each_port - - def reverse_each_port( &block ) - close_check - update - @real.reverse_each_port(&block) - end - - alias reverse_each reverse_each_port - - # old #each_mail returns Port - #def each_mail( &block ) - # each_port do |port| - # yield Mail.new(port) - # end - #end - - def each_new_port( mtime = nil ) - close_check - update - @real.each_new_port(mtime) {|p| yield p } - end - - def new_port - close_check - @real.new_port - end - - private - - def close_check - @closed and raise ArgumentError, 'accessing already closed mbox' - end - - def update - return if FileTest.zero?(@filename) - return if @updated and File.mtime(@filename) < @updated - w = nil - port = nil - time = nil - UNIXMbox.lock(@filename) {|f| - begin - f.each do |line| - if /\AFrom / === line - w.close if w - File.utime time, time, port.filename if time - - port = @real.new_port - w = port.wopen - time = fromline2time(line) - else - w.print line if w - end - end - ensure - if w and not w.closed? - w.close - File.utime time, time, port.filename if time - end - end - f.truncate(0) unless @readonly - @updated = Time.now - } - end - - def fromline2time( line ) - m = /\AFrom \S+ \w+ (\w+) (\d+) (\d+):(\d+):(\d+) (\d+)/.match(line) \ - or return nil - Time.local(m[6].to_i, m[1], m[2].to_i, m[3].to_i, m[4].to_i, m[5].to_i) - end - - end # UNIXMbox - - MboxLoader = UNIXMbox - - - class Maildir - - extend Mutex_m - - PORT_CLASS = MaildirPort - - @seq = 0 - def Maildir.unique_number - synchronize { - @seq += 1 - return @seq - } - end - - def initialize( dir = nil ) - @dirname = dir || ENV['MAILDIR'] - raise ArgumentError, "not directory: #{@dirname}"\ - unless FileTest.directory? @dirname - @new = "#{@dirname}/new" - @tmp = "#{@dirname}/tmp" - @cur = "#{@dirname}/cur" - end - - def directory - @dirname - end - - def inspect - "#<#{self.class} #{@dirname}>" - end - - def close - end - - def each_port - mail_files(@cur).each do |path| - yield PORT_CLASS.new(path) - end - end - - alias each each_port - - def reverse_each_port - mail_files(@cur).reverse_each do |path| - yield PORT_CLASS.new(path) - end - end - - alias reverse_each reverse_each_port - - def new_port - fname = nil - tmpfname = nil - newfname = nil - - begin - fname = "#{Time.now.to_i}.#{$$}_#{Maildir.unique_number}.#{Socket.gethostname}" - - tmpfname = "#{@tmp}/#{fname}" - newfname = "#{@new}/#{fname}" - end while FileTest.exist? tmpfname - - if block_given? - File.open(tmpfname, 'w') {|f| yield f } - File.rename tmpfname, newfname - PORT_CLASS.new(newfname) - else - File.open(tmpfname, 'w') {|f| f.write "\n\n" } - PORT_CLASS.new(tmpfname) - end - end - - def each_new_port - mail_files(@new).each do |path| - dest = @cur + '/' + File.basename(path) - File.rename path, dest - yield PORT_CLASS.new(dest) - end - - check_tmp - end - - TOO_OLD = 60 * 60 * 36 # 36 hour - - def check_tmp - old = Time.now.to_i - TOO_OLD - - each_filename(@tmp) do |full, fname| - if FileTest.file? full and - File.stat(full).mtime.to_i < old - File.unlink full - end - end - end - - private - - def mail_files( dir ) - Dir.entries(dir)\ - .select {|s| s[0] != ?. }\ - .sort_by {|s| s.slice(/\A\d+/).to_i }\ - .map {|s| "#{dir}/#{s}" }\ - .select {|path| FileTest.file? path } - end - - def each_filename( dir ) - Dir.foreach(dir) do |fname| - path = "#{dir}/#{fname}" - if fname[0] != ?. and FileTest.file? path - yield path, fname - end - end - end - - end # Maildir - - MaildirLoader = Maildir - -end # module TMail diff --git a/tracks/vendor/rails/actionmailer/lib/action_mailer/vendor/tmail/mbox.rb b/tracks/vendor/rails/actionmailer/lib/action_mailer/vendor/tmail/mbox.rb deleted file mode 100644 index 79073154..00000000 --- a/tracks/vendor/rails/actionmailer/lib/action_mailer/vendor/tmail/mbox.rb +++ /dev/null @@ -1 +0,0 @@ -require 'tmail/mailbox' diff --git a/tracks/vendor/rails/actionmailer/lib/action_mailer/vendor/tmail/net.rb b/tracks/vendor/rails/actionmailer/lib/action_mailer/vendor/tmail/net.rb deleted file mode 100644 index f96cf64c..00000000 --- a/tracks/vendor/rails/actionmailer/lib/action_mailer/vendor/tmail/net.rb +++ /dev/null @@ -1,280 +0,0 @@ -# -# net.rb -# -#-- -# Copyright (c) 1998-2003 Minero Aoki -# -# 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. -# -# Note: Originally licensed under LGPL v2+. Using MIT license for Rails -# with permission of Minero Aoki. -#++ - -require 'nkf' - - -module TMail - - class Mail - - def send_to( smtp ) - do_send_to(smtp) do - ready_to_send - end - end - - def send_text_to( smtp ) - do_send_to(smtp) do - ready_to_send - mime_encode - end - end - - def do_send_to( smtp ) - from = from_address or raise ArgumentError, 'no from address' - (dests = destinations).empty? and raise ArgumentError, 'no receipient' - yield - send_to_0 smtp, from, dests - end - private :do_send_to - - def send_to_0( smtp, from, to ) - smtp.ready(from, to) do |f| - encoded "\r\n", 'j', f, '' - end - end - - def ready_to_send - delete_no_send_fields - add_message_id - add_date - end - - NOSEND_FIELDS = %w( - received - bcc - ) - - def delete_no_send_fields - NOSEND_FIELDS.each do |nm| - delete nm - end - delete_if {|n,v| v.empty? } - end - - def add_message_id( fqdn = nil ) - self.message_id = ::TMail::new_message_id(fqdn) - end - - def add_date - self.date = Time.now - end - - def mime_encode - if parts.empty? - mime_encode_singlepart - else - mime_encode_multipart true - end - end - - def mime_encode_singlepart - self.mime_version = '1.0' - b = body - if NKF.guess(b) != NKF::BINARY - mime_encode_text b - else - mime_encode_binary b - end - end - - def mime_encode_text( body ) - self.body = NKF.nkf('-j -m0', body) - self.set_content_type 'text', 'plain', {'charset' => 'iso-2022-jp'} - self.encoding = '7bit' - end - - def mime_encode_binary( body ) - self.body = [body].pack('m') - self.set_content_type 'application', 'octet-stream' - self.encoding = 'Base64' - end - - def mime_encode_multipart( top = true ) - self.mime_version = '1.0' if top - self.set_content_type 'multipart', 'mixed' - e = encoding(nil) - if e and not /\A(?:7bit|8bit|binary)\z/i === e - raise ArgumentError, - 'using C.T.Encoding with multipart mail is not permitted' - end - end - - def create_empty_mail - self.class.new(StringPort.new(''), @config) - end - - def create_reply - setup_reply create_empty_mail() - end - - def setup_reply( m ) - if tmp = reply_addresses(nil) - m.to_addrs = tmp - end - - mid = message_id(nil) - tmp = references(nil) || [] - tmp.push mid if mid - m.in_reply_to = [mid] if mid - m.references = tmp unless tmp.empty? - m.subject = 'Re: ' + subject('').sub(/\A(?:\s*re:)+/i, '') - - m - end - - def create_forward - setup_forward create_empty_mail() - end - - def setup_forward( mail ) - m = Mail.new(StringPort.new('')) - m.body = decoded - m.set_content_type 'message', 'rfc822' - m.encoding = encoding('7bit') - mail.parts.push m - end - - end - - - class DeleteFields - - NOSEND_FIELDS = %w( - received - bcc - ) - - def initialize( nosend = nil, delempty = true ) - @no_send_fields = nosend || NOSEND_FIELDS.dup - @delete_empty_fields = delempty - end - - attr :no_send_fields - attr :delete_empty_fields, true - - def exec( mail ) - @no_send_fields.each do |nm| - delete nm - end - delete_if {|n,v| v.empty? } if @delete_empty_fields - end - - end - - - class AddMessageId - - def initialize( fqdn = nil ) - @fqdn = fqdn - end - - attr :fqdn, true - - def exec( mail ) - mail.message_id = ::TMail::new_msgid(@fqdn) - end - - end - - - class AddDate - - def exec( mail ) - mail.date = Time.now - end - - end - - - class MimeEncodeAuto - - def initialize( s = nil, m = nil ) - @singlepart_composer = s || MimeEncodeSingle.new - @multipart_composer = m || MimeEncodeMulti.new - end - - attr :singlepart_composer - attr :multipart_composer - - def exec( mail ) - if mail._builtin_multipart? - then @multipart_composer - else @singlepart_composer end.exec mail - end - - end - - - class MimeEncodeSingle - - def exec( mail ) - mail.mime_version = '1.0' - b = mail.body - if NKF.guess(b) != NKF::BINARY - on_text b - else - on_binary b - end - end - - def on_text( body ) - mail.body = NKF.nkf('-j -m0', body) - mail.set_content_type 'text', 'plain', {'charset' => 'iso-2022-jp'} - mail.encoding = '7bit' - end - - def on_binary( body ) - mail.body = [body].pack('m') - mail.set_content_type 'application', 'octet-stream' - mail.encoding = 'Base64' - end - - end - - - class MimeEncodeMulti - - def exec( mail, top = true ) - mail.mime_version = '1.0' if top - mail.set_content_type 'multipart', 'mixed' - e = encoding(nil) - if e and not /\A(?:7bit|8bit|binary)\z/i === e - raise ArgumentError, - 'using C.T.Encoding with multipart mail is not permitted' - end - mail.parts.each do |m| - exec m, false if m._builtin_multipart? - end - end - - end - -end # module TMail diff --git a/tracks/vendor/rails/actionmailer/lib/action_mailer/vendor/tmail/obsolete.rb b/tracks/vendor/rails/actionmailer/lib/action_mailer/vendor/tmail/obsolete.rb deleted file mode 100644 index f98be747..00000000 --- a/tracks/vendor/rails/actionmailer/lib/action_mailer/vendor/tmail/obsolete.rb +++ /dev/null @@ -1,135 +0,0 @@ -# -# obsolete.rb -# -#-- -# Copyright (c) 1998-2003 Minero Aoki -# -# 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. -# -# Note: Originally licensed under LGPL v2+. Using MIT license for Rails -# with permission of Minero Aoki. -#++ - -module TMail - - # mail.rb - class Mail - alias include? key? - alias has_key? key? - - def values - ret = [] - each_field {|v| ret.push v } - ret - end - - def value?( val ) - HeaderField === val or return false - - [ @header[val.name.downcase] ].flatten.include? val - end - - alias has_value? value? - end - - - # facade.rb - class Mail - def from_addr( default = nil ) - addr, = from_addrs(nil) - addr || default - end - - def from_address( default = nil ) - if a = from_addr(nil) - a.spec - else - default - end - end - - alias from_address= from_addrs= - - def from_phrase( default = nil ) - if a = from_addr(nil) - a.phrase - else - default - end - end - - alias msgid message_id - alias msgid= message_id= - - alias each_dest each_destination - end - - - # address.rb - class Address - alias route routes - alias addr spec - - def spec=( str ) - @local, @domain = str.split(/@/,2).map {|s| s.split(/\./) } - end - - alias addr= spec= - alias address= spec= - end - - - # mbox.rb - class MhMailbox - alias new_mail new_port - alias each_mail each_port - alias each_newmail each_new_port - end - class UNIXMbox - alias new_mail new_port - alias each_mail each_port - alias each_newmail each_new_port - end - class Maildir - alias new_mail new_port - alias each_mail each_port - alias each_newmail each_new_port - end - - - # utils.rb - extend TextUtils - - class << self - alias msgid? message_id? - alias boundary new_boundary - alias msgid new_message_id - alias new_msgid new_message_id - end - - def Mail.boundary - ::TMail.new_boundary - end - - def Mail.msgid - ::TMail.new_message_id - end - -end # module TMail diff --git a/tracks/vendor/rails/actionmailer/lib/action_mailer/vendor/tmail/parser.rb b/tracks/vendor/rails/actionmailer/lib/action_mailer/vendor/tmail/parser.rb deleted file mode 100644 index 825eca92..00000000 --- a/tracks/vendor/rails/actionmailer/lib/action_mailer/vendor/tmail/parser.rb +++ /dev/null @@ -1,1522 +0,0 @@ -# -# DO NOT MODIFY!!!! -# This file is automatically generated by racc 1.4.3 -# from racc grammer file "parser.y". -# -# -# parser.rb: generated by racc (runtime embedded) -# - -###### racc/parser.rb - -unless $".index 'racc/parser.rb' -$".push 'racc/parser.rb' - -self.class.module_eval <<'..end /home/aamine/lib/ruby/racc/parser.rb modeval..idb76f2e220d', '/home/aamine/lib/ruby/racc/parser.rb', 1 -# -# parser.rb -# -# Copyright (c) 1999-2003 Minero Aoki -# -# This program is free software. -# You can distribute/modify this program under the same terms of ruby. -# -# As a special exception, when this code is copied by Racc -# into a Racc output file, you may use that output file -# without restriction. -# -# $Id: parser.rb,v 1.1.1.1 2004/10/14 11:59:58 webster132 Exp $ -# - -unless defined? NotImplementedError - NotImplementedError = NotImplementError -end - - -module Racc - class ParseError < StandardError; end -end -unless defined?(::ParseError) - ParseError = Racc::ParseError -end - - -module Racc - - unless defined? Racc_No_Extentions - Racc_No_Extentions = false - end - - class Parser - - Racc_Runtime_Version = '1.4.3' - Racc_Runtime_Revision = '$Revision: 1.1.1.1 $'.split(/\s+/)[1] - - Racc_Runtime_Core_Version_R = '1.4.3' - Racc_Runtime_Core_Revision_R = '$Revision: 1.1.1.1 $'.split(/\s+/)[1] - begin - require 'racc/cparse' - # Racc_Runtime_Core_Version_C = (defined in extention) - Racc_Runtime_Core_Revision_C = Racc_Runtime_Core_Id_C.split(/\s+/)[2] - unless new.respond_to?(:_racc_do_parse_c, true) - raise LoadError, 'old cparse.so' - end - if Racc_No_Extentions - raise LoadError, 'selecting ruby version of racc runtime core' - end - - Racc_Main_Parsing_Routine = :_racc_do_parse_c - Racc_YY_Parse_Method = :_racc_yyparse_c - Racc_Runtime_Core_Version = Racc_Runtime_Core_Version_C - Racc_Runtime_Core_Revision = Racc_Runtime_Core_Revision_C - Racc_Runtime_Type = 'c' - rescue LoadError - Racc_Main_Parsing_Routine = :_racc_do_parse_rb - Racc_YY_Parse_Method = :_racc_yyparse_rb - Racc_Runtime_Core_Version = Racc_Runtime_Core_Version_R - Racc_Runtime_Core_Revision = Racc_Runtime_Core_Revision_R - Racc_Runtime_Type = 'ruby' - end - - def self.racc_runtime_type - Racc_Runtime_Type - end - - private - - def _racc_setup - @yydebug = false unless self.class::Racc_debug_parser - @yydebug = false unless defined? @yydebug - if @yydebug - @racc_debug_out = $stderr unless defined? @racc_debug_out - @racc_debug_out ||= $stderr - end - arg = self.class::Racc_arg - arg[13] = true if arg.size < 14 - arg - end - - def _racc_init_sysvars - @racc_state = [0] - @racc_tstack = [] - @racc_vstack = [] - - @racc_t = nil - @racc_val = nil - - @racc_read_next = true - - @racc_user_yyerror = false - @racc_error_status = 0 - end - - - ### - ### do_parse - ### - - def do_parse - __send__ Racc_Main_Parsing_Routine, _racc_setup(), false - end - - def next_token - raise NotImplementedError, "#{self.class}\#next_token is not defined" - end - - def _racc_do_parse_rb( arg, in_debug ) - action_table, action_check, action_default, action_pointer, - goto_table, goto_check, goto_default, goto_pointer, - nt_base, reduce_table, token_table, shift_n, - reduce_n, use_result, * = arg - - _racc_init_sysvars - tok = act = i = nil - nerr = 0 - - catch(:racc_end_parse) { - while true - if i = action_pointer[@racc_state[-1]] - if @racc_read_next - if @racc_t != 0 # not EOF - tok, @racc_val = next_token() - unless tok # EOF - @racc_t = 0 - else - @racc_t = (token_table[tok] or 1) # error token - end - racc_read_token(@racc_t, tok, @racc_val) if @yydebug - @racc_read_next = false - end - end - i += @racc_t - if i >= 0 and - act = action_table[i] and - action_check[i] == @racc_state[-1] - ; - else - act = action_default[@racc_state[-1]] - end - else - act = action_default[@racc_state[-1]] - end - while act = _racc_evalact(act, arg) - end - end - } - end - - - ### - ### yyparse - ### - - def yyparse( recv, mid ) - __send__ Racc_YY_Parse_Method, recv, mid, _racc_setup(), true - end - - def _racc_yyparse_rb( recv, mid, arg, c_debug ) - action_table, action_check, action_default, action_pointer, - goto_table, goto_check, goto_default, goto_pointer, - nt_base, reduce_table, token_table, shift_n, - reduce_n, use_result, * = arg - - _racc_init_sysvars - tok = nil - act = nil - i = nil - nerr = 0 - - - catch(:racc_end_parse) { - until i = action_pointer[@racc_state[-1]] - while act = _racc_evalact(action_default[@racc_state[-1]], arg) - end - end - - recv.__send__(mid) do |tok, val| -# $stderr.puts "rd: tok=#{tok}, val=#{val}" - unless tok - @racc_t = 0 - else - @racc_t = (token_table[tok] or 1) # error token - end - @racc_val = val - @racc_read_next = false - - i += @racc_t - if i >= 0 and - act = action_table[i] and - action_check[i] == @racc_state[-1] - ; -# $stderr.puts "01: act=#{act}" - else - act = action_default[@racc_state[-1]] -# $stderr.puts "02: act=#{act}" -# $stderr.puts "curstate=#{@racc_state[-1]}" - end - - while act = _racc_evalact(act, arg) - end - - while not (i = action_pointer[@racc_state[-1]]) or - not @racc_read_next or - @racc_t == 0 # $ - if i and i += @racc_t and - i >= 0 and - act = action_table[i] and - action_check[i] == @racc_state[-1] - ; -# $stderr.puts "03: act=#{act}" - else -# $stderr.puts "04: act=#{act}" - act = action_default[@racc_state[-1]] - end - - while act = _racc_evalact(act, arg) - end - end - end - } - end - - - ### - ### common - ### - - def _racc_evalact( act, arg ) -# $stderr.puts "ea: act=#{act}" - action_table, action_check, action_default, action_pointer, - goto_table, goto_check, goto_default, goto_pointer, - nt_base, reduce_table, token_table, shift_n, - reduce_n, use_result, * = arg -nerr = 0 # tmp - - if act > 0 and act < shift_n - # - # shift - # - - if @racc_error_status > 0 - @racc_error_status -= 1 unless @racc_t == 1 # error token - end - - @racc_vstack.push @racc_val - @racc_state.push act - @racc_read_next = true - - if @yydebug - @racc_tstack.push @racc_t - racc_shift @racc_t, @racc_tstack, @racc_vstack - end - - elsif act < 0 and act > -reduce_n - # - # reduce - # - - code = catch(:racc_jump) { - @racc_state.push _racc_do_reduce(arg, act) - false - } - if code - case code - when 1 # yyerror - @racc_user_yyerror = true # user_yyerror - return -reduce_n - when 2 # yyaccept - return shift_n - else - raise RuntimeError, '[Racc Bug] unknown jump code' - end - end - - elsif act == shift_n - # - # accept - # - - racc_accept if @yydebug - throw :racc_end_parse, @racc_vstack[0] - - elsif act == -reduce_n - # - # error - # - - case @racc_error_status - when 0 - unless arg[21] # user_yyerror - nerr += 1 - on_error @racc_t, @racc_val, @racc_vstack - end - when 3 - if @racc_t == 0 # is $ - throw :racc_end_parse, nil - end - @racc_read_next = true - end - @racc_user_yyerror = false - @racc_error_status = 3 - - while true - if i = action_pointer[@racc_state[-1]] - i += 1 # error token - if i >= 0 and - (act = action_table[i]) and - action_check[i] == @racc_state[-1] - break - end - end - - throw :racc_end_parse, nil if @racc_state.size < 2 - @racc_state.pop - @racc_vstack.pop - if @yydebug - @racc_tstack.pop - racc_e_pop @racc_state, @racc_tstack, @racc_vstack - end - end - - return act - - else - raise RuntimeError, "[Racc Bug] unknown action #{act.inspect}" - end - - racc_next_state(@racc_state[-1], @racc_state) if @yydebug - - nil - end - - def _racc_do_reduce( arg, act ) - action_table, action_check, action_default, action_pointer, - goto_table, goto_check, goto_default, goto_pointer, - nt_base, reduce_table, token_table, shift_n, - reduce_n, use_result, * = arg - state = @racc_state - vstack = @racc_vstack - tstack = @racc_tstack - - i = act * -3 - len = reduce_table[i] - reduce_to = reduce_table[i+1] - method_id = reduce_table[i+2] - void_array = [] - - tmp_t = tstack[-len, len] if @yydebug - tmp_v = vstack[-len, len] - tstack[-len, len] = void_array if @yydebug - vstack[-len, len] = void_array - state[-len, len] = void_array - - # tstack must be updated AFTER method call - if use_result - vstack.push __send__(method_id, tmp_v, vstack, tmp_v[0]) - else - vstack.push __send__(method_id, tmp_v, vstack) - end - tstack.push reduce_to - - racc_reduce(tmp_t, reduce_to, tstack, vstack) if @yydebug - - k1 = reduce_to - nt_base - if i = goto_pointer[k1] - i += state[-1] - if i >= 0 and (curstate = goto_table[i]) and goto_check[i] == k1 - return curstate - end - end - goto_default[k1] - end - - def on_error( t, val, vstack ) - raise ParseError, sprintf("\nparse error on value %s (%s)", - val.inspect, token_to_str(t) || '?') - end - - def yyerror - throw :racc_jump, 1 - end - - def yyaccept - throw :racc_jump, 2 - end - - def yyerrok - @racc_error_status = 0 - end - - - # for debugging output - - def racc_read_token( t, tok, val ) - @racc_debug_out.print 'read ' - @racc_debug_out.print tok.inspect, '(', racc_token2str(t), ') ' - @racc_debug_out.puts val.inspect - @racc_debug_out.puts - end - - def racc_shift( tok, tstack, vstack ) - @racc_debug_out.puts "shift #{racc_token2str tok}" - racc_print_stacks tstack, vstack - @racc_debug_out.puts - end - - def racc_reduce( toks, sim, tstack, vstack ) - out = @racc_debug_out - out.print 'reduce ' - if toks.empty? - out.print ' ' - else - toks.each {|t| out.print ' ', racc_token2str(t) } - end - out.puts " --> #{racc_token2str(sim)}" - - racc_print_stacks tstack, vstack - @racc_debug_out.puts - end - - def racc_accept - @racc_debug_out.puts 'accept' - @racc_debug_out.puts - end - - def racc_e_pop( state, tstack, vstack ) - @racc_debug_out.puts 'error recovering mode: pop token' - racc_print_states state - racc_print_stacks tstack, vstack - @racc_debug_out.puts - end - - def racc_next_state( curstate, state ) - @racc_debug_out.puts "goto #{curstate}" - racc_print_states state - @racc_debug_out.puts - end - - def racc_print_stacks( t, v ) - out = @racc_debug_out - out.print ' [' - t.each_index do |i| - out.print ' (', racc_token2str(t[i]), ' ', v[i].inspect, ')' - end - out.puts ' ]' - end - - def racc_print_states( s ) - out = @racc_debug_out - out.print ' [' - s.each {|st| out.print ' ', st } - out.puts ' ]' - end - - def racc_token2str( tok ) - self.class::Racc_token_to_s_table[tok] or - raise RuntimeError, "[Racc Bug] can't convert token #{tok} to string" - end - - def token_to_str( t ) - self.class::Racc_token_to_s_table[t] - end - - end - -end -..end /home/aamine/lib/ruby/racc/parser.rb modeval..idb76f2e220d -end # end of racc/parser.rb - - -# -# parser.rb -# -#-- -# Copyright (c) 1998-2003 Minero Aoki -# -# 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. -# -# Note: Originally licensed under LGPL v2+. Using MIT license for Rails -# with permission of Minero Aoki. -#++ - -require 'tmail/scanner' -require 'tmail/utils' - - -module TMail - - class Parser < Racc::Parser - -module_eval <<'..end parser.y modeval..id43721faf1c', 'parser.y', 331 - - include TextUtils - - def self.parse( ident, str, cmt = nil ) - new.parse(ident, str, cmt) - end - - MAILP_DEBUG = false - - def initialize - self.debug = MAILP_DEBUG - end - - def debug=( flag ) - @yydebug = flag && Racc_debug_parser - @scanner_debug = flag - end - - def debug - @yydebug - end - - def parse( ident, str, comments = nil ) - @scanner = Scanner.new(str, ident, comments) - @scanner.debug = @scanner_debug - @first = [ident, ident] - result = yyparse(self, :parse_in) - comments.map! {|c| to_kcode(c) } if comments - result - end - - private - - def parse_in( &block ) - yield @first - @scanner.scan(&block) - end - - def on_error( t, val, vstack ) - raise SyntaxError, "parse error on token #{racc_token2str t}" - end - -..end parser.y modeval..id43721faf1c - -##### racc 1.4.3 generates ### - -racc_reduce_table = [ - 0, 0, :racc_error, - 2, 35, :_reduce_1, - 2, 35, :_reduce_2, - 2, 35, :_reduce_3, - 2, 35, :_reduce_4, - 2, 35, :_reduce_5, - 2, 35, :_reduce_6, - 2, 35, :_reduce_7, - 2, 35, :_reduce_8, - 2, 35, :_reduce_9, - 2, 35, :_reduce_10, - 2, 35, :_reduce_11, - 2, 35, :_reduce_12, - 6, 36, :_reduce_13, - 0, 48, :_reduce_none, - 2, 48, :_reduce_none, - 3, 49, :_reduce_16, - 5, 49, :_reduce_17, - 1, 50, :_reduce_18, - 7, 37, :_reduce_19, - 0, 51, :_reduce_none, - 2, 51, :_reduce_21, - 0, 52, :_reduce_none, - 2, 52, :_reduce_23, - 1, 58, :_reduce_24, - 3, 58, :_reduce_25, - 2, 58, :_reduce_26, - 0, 53, :_reduce_none, - 2, 53, :_reduce_28, - 0, 54, :_reduce_29, - 3, 54, :_reduce_30, - 0, 55, :_reduce_none, - 2, 55, :_reduce_32, - 2, 55, :_reduce_33, - 0, 56, :_reduce_none, - 2, 56, :_reduce_35, - 1, 61, :_reduce_36, - 1, 61, :_reduce_37, - 0, 57, :_reduce_none, - 2, 57, :_reduce_39, - 1, 38, :_reduce_none, - 1, 38, :_reduce_none, - 3, 38, :_reduce_none, - 1, 46, :_reduce_none, - 1, 46, :_reduce_none, - 1, 46, :_reduce_none, - 1, 39, :_reduce_none, - 2, 39, :_reduce_47, - 1, 64, :_reduce_48, - 3, 64, :_reduce_49, - 1, 68, :_reduce_none, - 1, 68, :_reduce_none, - 1, 69, :_reduce_52, - 3, 69, :_reduce_53, - 1, 47, :_reduce_none, - 1, 47, :_reduce_none, - 2, 47, :_reduce_56, - 2, 67, :_reduce_none, - 3, 65, :_reduce_58, - 2, 65, :_reduce_59, - 1, 70, :_reduce_60, - 2, 70, :_reduce_61, - 4, 62, :_reduce_62, - 3, 62, :_reduce_63, - 2, 72, :_reduce_none, - 2, 73, :_reduce_65, - 4, 73, :_reduce_66, - 3, 63, :_reduce_67, - 1, 63, :_reduce_68, - 1, 74, :_reduce_none, - 2, 74, :_reduce_70, - 1, 71, :_reduce_71, - 3, 71, :_reduce_72, - 1, 59, :_reduce_73, - 3, 59, :_reduce_74, - 1, 76, :_reduce_75, - 2, 76, :_reduce_76, - 1, 75, :_reduce_none, - 1, 75, :_reduce_none, - 1, 75, :_reduce_none, - 1, 77, :_reduce_none, - 1, 77, :_reduce_none, - 1, 77, :_reduce_none, - 1, 66, :_reduce_none, - 2, 66, :_reduce_none, - 3, 60, :_reduce_85, - 1, 40, :_reduce_86, - 3, 40, :_reduce_87, - 1, 79, :_reduce_none, - 2, 79, :_reduce_89, - 1, 41, :_reduce_90, - 2, 41, :_reduce_91, - 3, 42, :_reduce_92, - 5, 43, :_reduce_93, - 3, 43, :_reduce_94, - 0, 80, :_reduce_95, - 5, 80, :_reduce_96, - 1, 82, :_reduce_none, - 1, 82, :_reduce_none, - 1, 44, :_reduce_99, - 3, 45, :_reduce_100, - 0, 81, :_reduce_none, - 1, 81, :_reduce_none, - 1, 78, :_reduce_none, - 1, 78, :_reduce_none, - 1, 78, :_reduce_none, - 1, 78, :_reduce_none, - 1, 78, :_reduce_none, - 1, 78, :_reduce_none, - 1, 78, :_reduce_none ] - -racc_reduce_n = 110 - -racc_shift_n = 168 - -racc_action_table = [ - -70, -69, 23, 25, 146, 147, 29, 31, 105, 106, - 16, 17, 20, 22, 136, 27, -70, -69, 32, 101, - -70, -69, 154, 100, 113, 115, -70, -69, -70, 109, - 75, 23, 25, 101, 155, 29, 31, 142, 143, 16, - 17, 20, 22, 107, 27, 23, 25, 32, 98, 29, - 31, 96, 94, 16, 17, 20, 22, 78, 27, 23, - 25, 32, 112, 29, 31, 74, 91, 16, 17, 20, - 22, 88, 117, 92, 81, 32, 23, 25, 80, 123, - 29, 31, 100, 125, 16, 17, 20, 22, 126, 23, - 25, 109, 32, 29, 31, 91, 128, 16, 17, 20, - 22, 129, 27, 23, 25, 32, 101, 29, 31, 101, - 130, 16, 17, 20, 22, 79, 52, 23, 25, 32, - 78, 29, 31, 133, 78, 16, 17, 20, 22, 77, - 23, 25, 75, 32, 29, 31, 65, 62, 16, 17, - 20, 22, 139, 23, 25, 101, 32, 29, 31, 60, - 100, 16, 17, 20, 22, 44, 27, 101, 148, 32, - 23, 25, 120, 149, 29, 31, 152, 153, 16, 17, - 20, 22, 42, 27, 157, 159, 32, 23, 25, 120, - 40, 29, 31, 15, 164, 16, 17, 20, 22, 40, - 27, 23, 25, 32, 68, 29, 31, 166, 167, 16, - 17, 20, 22, nil, 27, 23, 25, 32, nil, 29, - 31, 74, nil, 16, 17, 20, 22, nil, 23, 25, - nil, 32, 29, 31, nil, nil, 16, 17, 20, 22, - nil, 23, 25, nil, 32, 29, 31, nil, nil, 16, - 17, 20, 22, nil, 23, 25, nil, 32, 29, 31, - nil, nil, 16, 17, 20, 22, nil, 23, 25, nil, - 32, 29, 31, nil, nil, 16, 17, 20, 22, nil, - 27, 23, 25, 32, nil, 29, 31, nil, nil, 16, - 17, 20, 22, nil, 23, 25, nil, 32, 29, 31, - nil, nil, 16, 17, 20, 22, nil, 23, 25, nil, - 32, 29, 31, nil, nil, 16, 17, 20, 22, nil, - 84, 25, nil, 32, 29, 31, nil, 87, 16, 17, - 20, 22, 4, 6, 7, 8, 9, 10, 11, 12, - 13, 1, 2, 3, 84, 25, nil, nil, 29, 31, - nil, 87, 16, 17, 20, 22, 84, 25, nil, nil, - 29, 31, nil, 87, 16, 17, 20, 22, 84, 25, - nil, nil, 29, 31, nil, 87, 16, 17, 20, 22, - 84, 25, nil, nil, 29, 31, nil, 87, 16, 17, - 20, 22, 84, 25, nil, nil, 29, 31, nil, 87, - 16, 17, 20, 22, 84, 25, nil, nil, 29, 31, - nil, 87, 16, 17, 20, 22 ] - -racc_action_check = [ - 75, 28, 68, 68, 136, 136, 68, 68, 72, 72, - 68, 68, 68, 68, 126, 68, 75, 28, 68, 67, - 75, 28, 143, 66, 86, 86, 75, 28, 75, 75, - 28, 3, 3, 86, 143, 3, 3, 134, 134, 3, - 3, 3, 3, 73, 3, 152, 152, 3, 62, 152, - 152, 60, 56, 152, 152, 152, 152, 51, 152, 52, - 52, 152, 80, 52, 52, 52, 50, 52, 52, 52, - 52, 45, 89, 52, 42, 52, 71, 71, 41, 96, - 71, 71, 97, 98, 71, 71, 71, 71, 100, 7, - 7, 101, 71, 7, 7, 102, 104, 7, 7, 7, - 7, 105, 7, 8, 8, 7, 108, 8, 8, 111, - 112, 8, 8, 8, 8, 40, 8, 9, 9, 8, - 36, 9, 9, 117, 121, 9, 9, 9, 9, 33, - 10, 10, 70, 9, 10, 10, 13, 12, 10, 10, - 10, 10, 130, 2, 2, 131, 10, 2, 2, 11, - 135, 2, 2, 2, 2, 6, 2, 138, 139, 2, - 90, 90, 90, 140, 90, 90, 141, 142, 90, 90, - 90, 90, 5, 90, 148, 151, 90, 127, 127, 127, - 4, 127, 127, 1, 157, 127, 127, 127, 127, 159, - 127, 26, 26, 127, 26, 26, 26, 163, 164, 26, - 26, 26, 26, nil, 26, 27, 27, 26, nil, 27, - 27, 27, nil, 27, 27, 27, 27, nil, 155, 155, - nil, 27, 155, 155, nil, nil, 155, 155, 155, 155, - nil, 122, 122, nil, 155, 122, 122, nil, nil, 122, - 122, 122, 122, nil, 76, 76, nil, 122, 76, 76, - nil, nil, 76, 76, 76, 76, nil, 38, 38, nil, - 76, 38, 38, nil, nil, 38, 38, 38, 38, nil, - 38, 55, 55, 38, nil, 55, 55, nil, nil, 55, - 55, 55, 55, nil, 94, 94, nil, 55, 94, 94, - nil, nil, 94, 94, 94, 94, nil, 59, 59, nil, - 94, 59, 59, nil, nil, 59, 59, 59, 59, nil, - 114, 114, nil, 59, 114, 114, nil, 114, 114, 114, - 114, 114, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 77, 77, nil, nil, 77, 77, - nil, 77, 77, 77, 77, 77, 44, 44, nil, nil, - 44, 44, nil, 44, 44, 44, 44, 44, 113, 113, - nil, nil, 113, 113, nil, 113, 113, 113, 113, 113, - 88, 88, nil, nil, 88, 88, nil, 88, 88, 88, - 88, 88, 74, 74, nil, nil, 74, 74, nil, 74, - 74, 74, 74, 74, 129, 129, nil, nil, 129, 129, - nil, 129, 129, 129, 129, 129 ] - -racc_action_pointer = [ - 320, 152, 129, 17, 165, 172, 137, 75, 89, 103, - 116, 135, 106, 105, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, nil, nil, 177, 191, 1, nil, - nil, nil, nil, 109, nil, nil, 94, nil, 243, nil, - 99, 64, 74, nil, 332, 52, nil, nil, nil, nil, - 50, 31, 45, nil, nil, 257, 36, nil, nil, 283, - 22, nil, 16, nil, nil, nil, -3, -10, -12, nil, - 103, 62, -8, 15, 368, 0, 230, 320, nil, nil, - 47, nil, nil, nil, nil, nil, 4, nil, 356, 50, - 146, nil, nil, nil, 270, nil, 65, 56, 52, nil, - 57, 62, 79, nil, 68, 81, nil, nil, 77, nil, - nil, 80, 96, 344, 296, nil, nil, 108, nil, nil, - nil, 98, 217, nil, nil, nil, -19, 163, nil, 380, - 128, 116, nil, nil, 14, 124, -26, nil, 128, 141, - 148, 141, 152, 7, nil, nil, nil, nil, 160, nil, - nil, 149, 31, nil, nil, 204, nil, 167, nil, 174, - nil, nil, nil, 169, 184, nil, nil, nil ] - -racc_action_default = [ - -110, -110, -110, -110, -14, -110, -20, -110, -110, -110, - -110, -110, -110, -110, -10, -95, -106, -107, -77, -44, - -108, -11, -109, -79, -43, -103, -110, -110, -60, -104, - -55, -105, -78, -68, -54, -71, -45, -12, -110, -1, - -110, -110, -110, -2, -110, -22, -51, -48, -50, -3, - -40, -41, -110, -46, -4, -86, -5, -88, -6, -90, - -110, -7, -95, -8, -9, -99, -101, -61, -59, -56, - -69, -110, -110, -110, -110, -75, -110, -110, -57, -15, - -110, 168, -73, -80, -82, -21, -24, -81, -110, -27, - -110, -83, -47, -89, -110, -91, -110, -101, -110, -100, - -102, -75, -58, -52, -110, -110, -64, -63, -65, -76, - -72, -67, -110, -110, -110, -26, -23, -110, -29, -49, - -84, -42, -87, -92, -94, -95, -110, -110, -62, -110, - -110, -25, -74, -28, -31, -101, -110, -53, -66, -110, - -110, -34, -110, -110, -93, -96, -98, -97, -110, -18, - -13, -38, -110, -30, -33, -110, -32, -16, -19, -14, - -35, -36, -37, -110, -110, -39, -85, -17 ] - -racc_goto_table = [ - 39, 67, 70, 73, 24, 37, 69, 66, 36, 38, - 57, 59, 55, 67, 108, 83, 90, 111, 69, 99, - 85, 49, 53, 76, 158, 134, 141, 70, 73, 151, - 118, 89, 45, 156, 160, 150, 140, 21, 14, 19, - 119, 102, 64, 63, 61, 83, 70, 104, 83, 58, - 124, 132, 56, 131, 97, 54, 93, 43, 5, 83, - 95, 145, 76, nil, 116, 76, nil, nil, 127, 138, - 103, nil, nil, nil, 38, nil, nil, 110, nil, nil, - nil, nil, nil, nil, 83, 83, nil, nil, 144, nil, - nil, nil, nil, nil, nil, 57, 121, 122, nil, nil, - 83, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, nil, nil, nil, 135, nil, nil, - nil, nil, nil, 93, nil, nil, nil, 70, 162, 137, - 70, 163, 161, 38, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, nil, 165 ] - -racc_goto_check = [ - 2, 37, 37, 29, 13, 13, 28, 46, 31, 36, - 41, 41, 45, 37, 25, 44, 32, 25, 28, 47, - 24, 4, 4, 42, 23, 20, 21, 37, 29, 22, - 19, 18, 17, 26, 27, 16, 15, 12, 11, 33, - 34, 35, 10, 9, 8, 44, 37, 29, 44, 7, - 47, 43, 6, 25, 46, 5, 41, 3, 1, 44, - 41, 48, 42, nil, 24, 42, nil, nil, 32, 25, - 13, nil, nil, nil, 36, nil, nil, 41, nil, nil, - nil, nil, nil, nil, 44, 44, nil, nil, 47, nil, - nil, nil, nil, nil, nil, 41, 31, 45, nil, nil, - 44, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, nil, nil, nil, 46, nil, nil, - nil, nil, nil, 41, nil, nil, nil, 37, 29, 13, - 37, 29, 28, 36, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, nil, 2 ] - -racc_goto_pointer = [ - nil, 58, -4, 51, 14, 47, 43, 39, 33, 31, - 29, 37, 35, 2, nil, -94, -105, 26, -14, -59, - -93, -108, -112, -127, -24, -60, -110, -118, -20, -24, - nil, 6, -34, 37, -50, -27, 6, -25, nil, nil, - nil, 1, -5, -63, -29, 3, -8, -47, -75 ] - -racc_goto_default = [ - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, nil, 48, 41, nil, nil, nil, nil, nil, - nil, nil, nil, nil, nil, 86, nil, nil, 30, 34, - 50, 51, nil, 46, 47, nil, 26, 28, 71, 72, - 33, 35, 114, 82, 18, nil, nil, nil, nil ] - -racc_token_table = { - false => 0, - Object.new => 1, - :DATETIME => 2, - :RECEIVED => 3, - :MADDRESS => 4, - :RETPATH => 5, - :KEYWORDS => 6, - :ENCRYPTED => 7, - :MIMEVERSION => 8, - :CTYPE => 9, - :CENCODING => 10, - :CDISPOSITION => 11, - :ADDRESS => 12, - :MAILBOX => 13, - :DIGIT => 14, - :ATOM => 15, - "," => 16, - ":" => 17, - :FROM => 18, - :BY => 19, - "@" => 20, - :DOMLIT => 21, - :VIA => 22, - :WITH => 23, - :ID => 24, - :FOR => 25, - ";" => 26, - "<" => 27, - ">" => 28, - "." => 29, - :QUOTED => 30, - :TOKEN => 31, - "/" => 32, - "=" => 33 } - -racc_use_result_var = false - -racc_nt_base = 34 - -Racc_arg = [ - racc_action_table, - racc_action_check, - racc_action_default, - racc_action_pointer, - racc_goto_table, - racc_goto_check, - racc_goto_default, - racc_goto_pointer, - racc_nt_base, - racc_reduce_table, - racc_token_table, - racc_shift_n, - racc_reduce_n, - racc_use_result_var ] - -Racc_token_to_s_table = [ -'$end', -'error', -'DATETIME', -'RECEIVED', -'MADDRESS', -'RETPATH', -'KEYWORDS', -'ENCRYPTED', -'MIMEVERSION', -'CTYPE', -'CENCODING', -'CDISPOSITION', -'ADDRESS', -'MAILBOX', -'DIGIT', -'ATOM', -'","', -'":"', -'FROM', -'BY', -'"@"', -'DOMLIT', -'VIA', -'WITH', -'ID', -'FOR', -'";"', -'"<"', -'">"', -'"."', -'QUOTED', -'TOKEN', -'"/"', -'"="', -'$start', -'content', -'datetime', -'received', -'addrs_TOP', -'retpath', -'keys', -'enc', -'version', -'ctype', -'cencode', -'cdisp', -'addr_TOP', -'mbox', -'day', -'hour', -'zone', -'from', -'by', -'via', -'with', -'id', -'for', -'received_datetime', -'received_domain', -'domain', -'msgid', -'received_addrspec', -'routeaddr', -'spec', -'addrs', -'group_bare', -'commas', -'group', -'addr', -'mboxes', -'addr_phrase', -'local_head', -'routes', -'at_domains', -'local', -'word', -'dots', -'domword', -'atom', -'phrase', -'params', -'opt_semicolon', -'value'] - -Racc_debug_parser = false - -##### racc system variables end ##### - - # reduce 0 omitted - -module_eval <<'.,.,', 'parser.y', 16 - def _reduce_1( val, _values) - val[1] - end -.,., - -module_eval <<'.,.,', 'parser.y', 17 - def _reduce_2( val, _values) - val[1] - end -.,., - -module_eval <<'.,.,', 'parser.y', 18 - def _reduce_3( val, _values) - val[1] - end -.,., - -module_eval <<'.,.,', 'parser.y', 19 - def _reduce_4( val, _values) - val[1] - end -.,., - -module_eval <<'.,.,', 'parser.y', 20 - def _reduce_5( val, _values) - val[1] - end -.,., - -module_eval <<'.,.,', 'parser.y', 21 - def _reduce_6( val, _values) - val[1] - end -.,., - -module_eval <<'.,.,', 'parser.y', 22 - def _reduce_7( val, _values) - val[1] - end -.,., - -module_eval <<'.,.,', 'parser.y', 23 - def _reduce_8( val, _values) - val[1] - end -.,., - -module_eval <<'.,.,', 'parser.y', 24 - def _reduce_9( val, _values) - val[1] - end -.,., - -module_eval <<'.,.,', 'parser.y', 25 - def _reduce_10( val, _values) - val[1] - end -.,., - -module_eval <<'.,.,', 'parser.y', 26 - def _reduce_11( val, _values) - val[1] - end -.,., - -module_eval <<'.,.,', 'parser.y', 27 - def _reduce_12( val, _values) - val[1] - end -.,., - -module_eval <<'.,.,', 'parser.y', 33 - def _reduce_13( val, _values) - t = Time.gm(val[3].to_i, val[2], val[1].to_i, 0, 0, 0) - (t + val[4] - val[5]).localtime - end -.,., - - # reduce 14 omitted - - # reduce 15 omitted - -module_eval <<'.,.,', 'parser.y', 42 - def _reduce_16( val, _values) - (val[0].to_i * 60 * 60) + - (val[2].to_i * 60) - end -.,., - -module_eval <<'.,.,', 'parser.y', 47 - def _reduce_17( val, _values) - (val[0].to_i * 60 * 60) + - (val[2].to_i * 60) + - (val[4].to_i) - end -.,., - -module_eval <<'.,.,', 'parser.y', 54 - def _reduce_18( val, _values) - timezone_string_to_unixtime(val[0]) - end -.,., - -module_eval <<'.,.,', 'parser.y', 59 - def _reduce_19( val, _values) - val - end -.,., - - # reduce 20 omitted - -module_eval <<'.,.,', 'parser.y', 65 - def _reduce_21( val, _values) - val[1] - end -.,., - - # reduce 22 omitted - -module_eval <<'.,.,', 'parser.y', 71 - def _reduce_23( val, _values) - val[1] - end -.,., - -module_eval <<'.,.,', 'parser.y', 77 - def _reduce_24( val, _values) - join_domain(val[0]) - end -.,., - -module_eval <<'.,.,', 'parser.y', 81 - def _reduce_25( val, _values) - join_domain(val[2]) - end -.,., - -module_eval <<'.,.,', 'parser.y', 85 - def _reduce_26( val, _values) - join_domain(val[0]) - end -.,., - - # reduce 27 omitted - -module_eval <<'.,.,', 'parser.y', 91 - def _reduce_28( val, _values) - val[1] - end -.,., - -module_eval <<'.,.,', 'parser.y', 96 - def _reduce_29( val, _values) - [] - end -.,., - -module_eval <<'.,.,', 'parser.y', 100 - def _reduce_30( val, _values) - val[0].push val[2] - val[0] - end -.,., - - # reduce 31 omitted - -module_eval <<'.,.,', 'parser.y', 107 - def _reduce_32( val, _values) - val[1] - end -.,., - -module_eval <<'.,.,', 'parser.y', 111 - def _reduce_33( val, _values) - val[1] - end -.,., - - # reduce 34 omitted - -module_eval <<'.,.,', 'parser.y', 117 - def _reduce_35( val, _values) - val[1] - end -.,., - -module_eval <<'.,.,', 'parser.y', 123 - def _reduce_36( val, _values) - val[0].spec - end -.,., - -module_eval <<'.,.,', 'parser.y', 127 - def _reduce_37( val, _values) - val[0].spec - end -.,., - - # reduce 38 omitted - -module_eval <<'.,.,', 'parser.y', 134 - def _reduce_39( val, _values) - val[1] - end -.,., - - # reduce 40 omitted - - # reduce 41 omitted - - # reduce 42 omitted - - # reduce 43 omitted - - # reduce 44 omitted - - # reduce 45 omitted - - # reduce 46 omitted - -module_eval <<'.,.,', 'parser.y', 146 - def _reduce_47( val, _values) - [ Address.new(nil, nil) ] - end -.,., - -module_eval <<'.,.,', 'parser.y', 148 - def _reduce_48( val, _values) - val - end -.,., - -module_eval <<'.,.,', 'parser.y', 149 - def _reduce_49( val, _values) - val[0].push val[2]; val[0] - end -.,., - - # reduce 50 omitted - - # reduce 51 omitted - -module_eval <<'.,.,', 'parser.y', 156 - def _reduce_52( val, _values) - val - end -.,., - -module_eval <<'.,.,', 'parser.y', 160 - def _reduce_53( val, _values) - val[0].push val[2] - val[0] - end -.,., - - # reduce 54 omitted - - # reduce 55 omitted - -module_eval <<'.,.,', 'parser.y', 168 - def _reduce_56( val, _values) - val[1].phrase = Decoder.decode(val[0]) - val[1] - end -.,., - - # reduce 57 omitted - -module_eval <<'.,.,', 'parser.y', 176 - def _reduce_58( val, _values) - AddressGroup.new(val[0], val[2]) - end -.,., - -module_eval <<'.,.,', 'parser.y', 178 - def _reduce_59( val, _values) - AddressGroup.new(val[0], []) - end -.,., - -module_eval <<'.,.,', 'parser.y', 181 - def _reduce_60( val, _values) - val[0].join('.') - end -.,., - -module_eval <<'.,.,', 'parser.y', 182 - def _reduce_61( val, _values) - val[0] << ' ' << val[1].join('.') - end -.,., - -module_eval <<'.,.,', 'parser.y', 186 - def _reduce_62( val, _values) - val[2].routes.replace val[1] - val[2] - end -.,., - -module_eval <<'.,.,', 'parser.y', 191 - def _reduce_63( val, _values) - val[1] - end -.,., - - # reduce 64 omitted - -module_eval <<'.,.,', 'parser.y', 196 - def _reduce_65( val, _values) - [ val[1].join('.') ] - end -.,., - -module_eval <<'.,.,', 'parser.y', 197 - def _reduce_66( val, _values) - val[0].push val[3].join('.'); val[0] - end -.,., - -module_eval <<'.,.,', 'parser.y', 199 - def _reduce_67( val, _values) - Address.new( val[0], val[2] ) - end -.,., - -module_eval <<'.,.,', 'parser.y', 200 - def _reduce_68( val, _values) - Address.new( val[0], nil ) - end -.,., - - # reduce 69 omitted - -module_eval <<'.,.,', 'parser.y', 203 - def _reduce_70( val, _values) - val[0].push ''; val[0] - end -.,., - -module_eval <<'.,.,', 'parser.y', 206 - def _reduce_71( val, _values) - val - end -.,., - -module_eval <<'.,.,', 'parser.y', 209 - def _reduce_72( val, _values) - val[1].times do - val[0].push '' - end - val[0].push val[2] - val[0] - end -.,., - -module_eval <<'.,.,', 'parser.y', 217 - def _reduce_73( val, _values) - val - end -.,., - -module_eval <<'.,.,', 'parser.y', 220 - def _reduce_74( val, _values) - val[1].times do - val[0].push '' - end - val[0].push val[2] - val[0] - end -.,., - -module_eval <<'.,.,', 'parser.y', 227 - def _reduce_75( val, _values) - 0 - end -.,., - -module_eval <<'.,.,', 'parser.y', 228 - def _reduce_76( val, _values) - 1 - end -.,., - - # reduce 77 omitted - - # reduce 78 omitted - - # reduce 79 omitted - - # reduce 80 omitted - - # reduce 81 omitted - - # reduce 82 omitted - - # reduce 83 omitted - - # reduce 84 omitted - -module_eval <<'.,.,', 'parser.y', 243 - def _reduce_85( val, _values) - val[1] = val[1].spec - val.join('') - end -.,., - -module_eval <<'.,.,', 'parser.y', 247 - def _reduce_86( val, _values) - val - end -.,., - -module_eval <<'.,.,', 'parser.y', 248 - def _reduce_87( val, _values) - val[0].push val[2]; val[0] - end -.,., - - # reduce 88 omitted - -module_eval <<'.,.,', 'parser.y', 251 - def _reduce_89( val, _values) - val[0] << ' ' << val[1] - end -.,., - -module_eval <<'.,.,', 'parser.y', 255 - def _reduce_90( val, _values) - val.push nil - val - end -.,., - -module_eval <<'.,.,', 'parser.y', 260 - def _reduce_91( val, _values) - val - end -.,., - -module_eval <<'.,.,', 'parser.y', 265 - def _reduce_92( val, _values) - [ val[0].to_i, val[2].to_i ] - end -.,., - -module_eval <<'.,.,', 'parser.y', 270 - def _reduce_93( val, _values) - [ val[0].downcase, val[2].downcase, decode_params(val[3]) ] - end -.,., - -module_eval <<'.,.,', 'parser.y', 274 - def _reduce_94( val, _values) - [ val[0].downcase, nil, decode_params(val[1]) ] - end -.,., - -module_eval <<'.,.,', 'parser.y', 279 - def _reduce_95( val, _values) - {} - end -.,., - -module_eval <<'.,.,', 'parser.y', 283 - def _reduce_96( val, _values) - val[0][ val[2].downcase ] = val[4] - val[0] - end -.,., - - # reduce 97 omitted - - # reduce 98 omitted - -module_eval <<'.,.,', 'parser.y', 292 - def _reduce_99( val, _values) - val[0].downcase - end -.,., - -module_eval <<'.,.,', 'parser.y', 297 - def _reduce_100( val, _values) - [ val[0].downcase, decode_params(val[1]) ] - end -.,., - - # reduce 101 omitted - - # reduce 102 omitted - - # reduce 103 omitted - - # reduce 104 omitted - - # reduce 105 omitted - - # reduce 106 omitted - - # reduce 107 omitted - - # reduce 108 omitted - - # reduce 109 omitted - - def _reduce_none( val, _values) - val[0] - end - - end # class Parser - -end # module TMail diff --git a/tracks/vendor/rails/actionmailer/lib/action_mailer/vendor/tmail/port.rb b/tracks/vendor/rails/actionmailer/lib/action_mailer/vendor/tmail/port.rb deleted file mode 100644 index f973c05b..00000000 --- a/tracks/vendor/rails/actionmailer/lib/action_mailer/vendor/tmail/port.rb +++ /dev/null @@ -1,377 +0,0 @@ -# -# port.rb -# -#-- -# Copyright (c) 1998-2003 Minero Aoki -# -# 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. -# -# Note: Originally licensed under LGPL v2+. Using MIT license for Rails -# with permission of Minero Aoki. -#++ - -require 'tmail/stringio' - - -module TMail - - class Port - def reproducible? - false - end - end - - - ### - ### FilePort - ### - - class FilePort < Port - - def initialize( fname ) - @filename = File.expand_path(fname) - super() - end - - attr_reader :filename - - alias ident filename - - def ==( other ) - other.respond_to?(:filename) and @filename == other.filename - end - - alias eql? == - - def hash - @filename.hash - end - - def inspect - "#<#{self.class}:#{@filename}>" - end - - def reproducible? - true - end - - def size - File.size @filename - end - - - def ropen( &block ) - File.open(@filename, &block) - end - - def wopen( &block ) - File.open(@filename, 'w', &block) - end - - def aopen( &block ) - File.open(@filename, 'a', &block) - end - - - def read_all - ropen {|f| - return f.read - } - end - - - def remove - File.unlink @filename - end - - def move_to( port ) - begin - File.link @filename, port.filename - rescue Errno::EXDEV - copy_to port - end - File.unlink @filename - end - - alias mv move_to - - def copy_to( port ) - if FilePort === port - copy_file @filename, port.filename - else - File.open(@filename) {|r| - port.wopen {|w| - while s = r.sysread(4096) - w.write << s - end - } } - end - end - - alias cp copy_to - - private - - # from fileutils.rb - def copy_file( src, dest ) - st = r = w = nil - - File.open(src, 'rb') {|r| - File.open(dest, 'wb') {|w| - st = r.stat - begin - while true - w.write r.sysread(st.blksize) - end - rescue EOFError - end - } } - end - - end - - - module MailFlags - - def seen=( b ) - set_status 'S', b - end - - def seen? - get_status 'S' - end - - def replied=( b ) - set_status 'R', b - end - - def replied? - get_status 'R' - end - - def flagged=( b ) - set_status 'F', b - end - - def flagged? - get_status 'F' - end - - private - - def procinfostr( str, tag, true_p ) - a = str.upcase.split(//) - a.push true_p ? tag : nil - a.delete tag unless true_p - a.compact.sort.join('').squeeze - end - - end - - - class MhPort < FilePort - - include MailFlags - - private - - def set_status( tag, flag ) - begin - tmpfile = @filename + '.tmailtmp.' + $$.to_s - File.open(tmpfile, 'w') {|f| - write_status f, tag, flag - } - File.unlink @filename - File.link tmpfile, @filename - ensure - File.unlink tmpfile - end - end - - def write_status( f, tag, flag ) - stat = '' - File.open(@filename) {|r| - while line = r.gets - if line.strip.empty? - break - elsif m = /\AX-TMail-Status:/i.match(line) - stat = m.post_match.strip - else - f.print line - end - end - - s = procinfostr(stat, tag, flag) - f.puts 'X-TMail-Status: ' + s unless s.empty? - f.puts - - while s = r.read(2048) - f.write s - end - } - end - - def get_status( tag ) - File.foreach(@filename) {|line| - return false if line.strip.empty? - if m = /\AX-TMail-Status:/i.match(line) - return m.post_match.strip.include?(tag[0]) - end - } - false - end - - end - - - class MaildirPort < FilePort - - def move_to_new - new = replace_dir(@filename, 'new') - File.rename @filename, new - @filename = new - end - - def move_to_cur - new = replace_dir(@filename, 'cur') - File.rename @filename, new - @filename = new - end - - def replace_dir( path, dir ) - "#{File.dirname File.dirname(path)}/#{dir}/#{File.basename path}" - end - private :replace_dir - - - include MailFlags - - private - - MAIL_FILE = /\A(\d+\.[\d_]+\.[^:]+)(?:\:(\d),(\w+)?)?\z/ - - def set_status( tag, flag ) - if m = MAIL_FILE.match(File.basename(@filename)) - s, uniq, type, info, = m.to_a - return if type and type != '2' # do not change anything - newname = File.dirname(@filename) + '/' + - uniq + ':2,' + procinfostr(info.to_s, tag, flag) - else - newname = @filename + ':2,' + tag - end - - File.link @filename, newname - File.unlink @filename - @filename = newname - end - - def get_status( tag ) - m = MAIL_FILE.match(File.basename(@filename)) or return false - m[2] == '2' and m[3].to_s.include?(tag[0]) - end - - end - - - ### - ### StringPort - ### - - class StringPort < Port - - def initialize( str = '' ) - @buffer = str - super() - end - - def string - @buffer - end - - def to_s - @buffer.dup - end - - alias read_all to_s - - def size - @buffer.size - end - - def ==( other ) - StringPort === other and @buffer.equal? other.string - end - - alias eql? == - - def hash - @buffer.object_id.hash - end - - def inspect - "#<#{self.class}:id=#{sprintf '0x%x', @buffer.object_id}>" - end - - def reproducible? - true - end - - def ropen( &block ) - @buffer or raise Errno::ENOENT, "#{inspect} is already removed" - StringInput.open(@buffer, &block) - end - - def wopen( &block ) - @buffer = '' - StringOutput.new(@buffer, &block) - end - - def aopen( &block ) - @buffer ||= '' - StringOutput.new(@buffer, &block) - end - - def remove - @buffer = nil - end - - alias rm remove - - def copy_to( port ) - port.wopen {|f| - f.write @buffer - } - end - - alias cp copy_to - - def move_to( port ) - if StringPort === port - str = @buffer - port.instance_eval { @buffer = str } - else - copy_to port - end - remove - end - - end - -end # module TMail diff --git a/tracks/vendor/rails/actionmailer/lib/action_mailer/vendor/tmail/quoting.rb b/tracks/vendor/rails/actionmailer/lib/action_mailer/vendor/tmail/quoting.rb deleted file mode 100644 index 36bf03f0..00000000 --- a/tracks/vendor/rails/actionmailer/lib/action_mailer/vendor/tmail/quoting.rb +++ /dev/null @@ -1,125 +0,0 @@ -module TMail - class Mail - def subject(to_charset = 'utf-8') - Unquoter.unquote_and_convert_to(quoted_subject, to_charset) - end - - def unquoted_body(to_charset = 'utf-8') - from_charset = sub_header("content-type", "charset") - case (content_transfer_encoding || "7bit").downcase - when "quoted-printable" - Unquoter.unquote_quoted_printable_and_convert_to(quoted_body, - to_charset, from_charset, true) - when "base64" - Unquoter.unquote_base64_and_convert_to(quoted_body, to_charset, - from_charset) - when "7bit", "8bit" - Unquoter.convert_to(quoted_body, to_charset, from_charset) - when "binary" - quoted_body - else - quoted_body - end - end - - def body(to_charset = 'utf-8', &block) - attachment_presenter = block || Proc.new { |file_name| "Attachment: #{file_name}\n" } - - if multipart? - parts.collect { |part| - header = part["content-type"] - - if part.multipart? - part.body(to_charset, &attachment_presenter) - elsif header.nil? - "" - elsif header.main_type == "text" - part.unquoted_body(to_charset) - else - attachment_presenter.call(header["name"] || "(unnamed)") - end - }.join - else - unquoted_body(to_charset) - end - end - end - - class Unquoter - class << self - def unquote_and_convert_to(text, to_charset, from_charset = "iso-8859-1", preserve_underscores=false) - return "" if text.nil? - if text =~ /^=\?(.*?)\?(.)\?(.*)\?=$/ - from_charset = $1 - quoting_method = $2 - text = $3 - case quoting_method.upcase - when "Q" then - unquote_quoted_printable_and_convert_to(text, to_charset, from_charset, preserve_underscores) - when "B" then - unquote_base64_and_convert_to(text, to_charset, from_charset) - else - raise "unknown quoting method #{quoting_method.inspect}" - end - else - convert_to(text, to_charset, from_charset) - end - end - - def unquote_quoted_printable_and_convert_to(text, to, from, preserve_underscores=false) - text = text.gsub(/_/, " ") unless preserve_underscores - convert_to(text.unpack("M*").first, to, from) - end - - def unquote_base64_and_convert_to(text, to, from) - convert_to(Base64.decode(text).first, to, from) - end - - begin - require 'iconv' - def convert_to(text, to, from) - return text unless to && from - text ? Iconv.iconv(to, from, text).first : "" - rescue Iconv::IllegalSequence, Errno::EINVAL - # the 'from' parameter specifies a charset other than what the text - # actually is...not much we can do in this case but just return the - # unconverted text. - # - # Ditto if either parameter represents an unknown charset, like - # X-UNKNOWN. - text - end - rescue LoadError - # Not providing quoting support - def convert_to(text, to, from) - warn "Action Mailer: iconv not loaded; ignoring conversion from #{from} to #{to} (#{__FILE__}:#{__LINE__})" - text - end - end - end - end -end - -if __FILE__ == $0 - require 'test/unit' - - class TC_Unquoter < Test::Unit::TestCase - def test_unquote_quoted_printable - a ="=?ISO-8859-1?Q?[166417]_Bekr=E6ftelse_fra_Rejsefeber?=" - b = TMail::Unquoter.unquote_and_convert_to(a, 'utf-8') - assert_equal "[166417] Bekr\303\246ftelse fra Rejsefeber", b - end - - def test_unquote_base64 - a ="=?ISO-8859-1?B?WzE2NjQxN10gQmVrcuZmdGVsc2UgZnJhIFJlanNlZmViZXI=?=" - b = TMail::Unquoter.unquote_and_convert_to(a, 'utf-8') - assert_equal "[166417] Bekr\303\246ftelse fra Rejsefeber", b - end - - def test_unquote_without_charset - a ="[166417]_Bekr=E6ftelse_fra_Rejsefeber" - b = TMail::Unquoter.unquote_and_convert_to(a, 'utf-8') - assert_equal "[166417]_Bekr=E6ftelse_fra_Rejsefeber", b - end - end -end diff --git a/tracks/vendor/rails/actionmailer/lib/action_mailer/vendor/tmail/scanner.rb b/tracks/vendor/rails/actionmailer/lib/action_mailer/vendor/tmail/scanner.rb deleted file mode 100644 index 839dd793..00000000 --- a/tracks/vendor/rails/actionmailer/lib/action_mailer/vendor/tmail/scanner.rb +++ /dev/null @@ -1,41 +0,0 @@ -# -# scanner.rb -# -#-- -# Copyright (c) 1998-2003 Minero Aoki -# -# 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. -# -# Note: Originally licensed under LGPL v2+. Using MIT license for Rails -# with permission of Minero Aoki. -#++ - -require 'tmail/utils' - -module TMail - require 'tmail/scanner_r.rb' - begin - raise LoadError, 'Turn off Ruby extention by user choice' if ENV['NORUBYEXT'] - require 'tmail/scanner_c.so' - Scanner = Scanner_C - rescue LoadError - Scanner = Scanner_R - end -end diff --git a/tracks/vendor/rails/actionmailer/lib/action_mailer/vendor/tmail/scanner_r.rb b/tracks/vendor/rails/actionmailer/lib/action_mailer/vendor/tmail/scanner_r.rb deleted file mode 100644 index ccf576c2..00000000 --- a/tracks/vendor/rails/actionmailer/lib/action_mailer/vendor/tmail/scanner_r.rb +++ /dev/null @@ -1,263 +0,0 @@ -# -# scanner_r.rb -# -#-- -# Copyright (c) 1998-2003 Minero Aoki -# -# 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. -# -# Note: Originally licensed under LGPL v2+. Using MIT license for Rails -# with permission of Minero Aoki. -#++ - -require 'tmail/config' - - -module TMail - - class Scanner_R - - Version = '0.10.7' - Version.freeze - - MIME_HEADERS = { - :CTYPE => true, - :CENCODING => true, - :CDISPOSITION => true - } - - alnum = 'a-zA-Z0-9' - atomsyms = %q[ _#!$%&`'*+-{|}~^@/=? ].strip - tokensyms = %q[ _#!$%&`'*+-{|}~^@. ].strip - - atomchars = alnum + Regexp.quote(atomsyms) - tokenchars = alnum + Regexp.quote(tokensyms) - iso2022str = '\e(?!\(B)..(?:[^\e]+|\e(?!\(B)..)*\e\(B' - - eucstr = '(?:[\xa1-\xfe][\xa1-\xfe])+' - sjisstr = '(?:[\x81-\x9f\xe0-\xef][\x40-\x7e\x80-\xfc])+' - utf8str = '(?:[\xc0-\xdf][\x80-\xbf]|[\xe0-\xef][\x80-\xbf][\x80-\xbf])+' - - quoted_with_iso2022 = /\A(?:[^\\\e"]+|#{iso2022str})+/n - domlit_with_iso2022 = /\A(?:[^\\\e\]]+|#{iso2022str})+/n - comment_with_iso2022 = /\A(?:[^\\\e()]+|#{iso2022str})+/n - - quoted_without_iso2022 = /\A[^\\"]+/n - domlit_without_iso2022 = /\A[^\\\]]+/n - comment_without_iso2022 = /\A[^\\()]+/n - - PATTERN_TABLE = {} - PATTERN_TABLE['EUC'] = - [ - /\A(?:[#{atomchars}]+|#{iso2022str}|#{eucstr})+/n, - /\A(?:[#{tokenchars}]+|#{iso2022str}|#{eucstr})+/n, - quoted_with_iso2022, - domlit_with_iso2022, - comment_with_iso2022 - ] - PATTERN_TABLE['SJIS'] = - [ - /\A(?:[#{atomchars}]+|#{iso2022str}|#{sjisstr})+/n, - /\A(?:[#{tokenchars}]+|#{iso2022str}|#{sjisstr})+/n, - quoted_with_iso2022, - domlit_with_iso2022, - comment_with_iso2022 - ] - PATTERN_TABLE['UTF8'] = - [ - /\A(?:[#{atomchars}]+|#{utf8str})+/n, - /\A(?:[#{tokenchars}]+|#{utf8str})+/n, - quoted_without_iso2022, - domlit_without_iso2022, - comment_without_iso2022 - ] - PATTERN_TABLE['NONE'] = - [ - /\A[#{atomchars}]+/n, - /\A[#{tokenchars}]+/n, - quoted_without_iso2022, - domlit_without_iso2022, - comment_without_iso2022 - ] - - - def initialize( str, scantype, comments ) - init_scanner str - @comments = comments || [] - @debug = false - - # fix scanner mode - @received = (scantype == :RECEIVED) - @is_mime_header = MIME_HEADERS[scantype] - - atom, token, @quoted_re, @domlit_re, @comment_re = PATTERN_TABLE[$KCODE] - @word_re = (MIME_HEADERS[scantype] ? token : atom) - end - - attr_accessor :debug - - def scan( &block ) - if @debug - scan_main do |arr| - s, v = arr - printf "%7d %-10s %s\n", - rest_size(), - s.respond_to?(:id2name) ? s.id2name : s.inspect, - v.inspect - yield arr - end - else - scan_main(&block) - end - end - - private - - RECV_TOKEN = { - 'from' => :FROM, - 'by' => :BY, - 'via' => :VIA, - 'with' => :WITH, - 'id' => :ID, - 'for' => :FOR - } - - def scan_main - until eof? - if skip(/\A[\n\r\t ]+/n) # LWSP - break if eof? - end - - if s = readstr(@word_re) - if @is_mime_header - yield :TOKEN, s - else - # atom - if /\A\d+\z/ === s - yield :DIGIT, s - elsif @received - yield RECV_TOKEN[s.downcase] || :ATOM, s - else - yield :ATOM, s - end - end - - elsif skip(/\A"/) - yield :QUOTED, scan_quoted_word() - - elsif skip(/\A\[/) - yield :DOMLIT, scan_domain_literal() - - elsif skip(/\A\(/) - @comments.push scan_comment() - - else - c = readchar() - yield c, c - end - end - - yield false, '$' - end - - def scan_quoted_word - scan_qstr(@quoted_re, /\A"/, 'quoted-word') - end - - def scan_domain_literal - '[' + scan_qstr(@domlit_re, /\A\]/, 'domain-literal') + ']' - end - - def scan_qstr( pattern, terminal, type ) - result = '' - until eof? - if s = readstr(pattern) then result << s - elsif skip(terminal) then return result - elsif skip(/\A\\/) then result << readchar() - else - raise "TMail FATAL: not match in #{type}" - end - end - scan_error! "found unterminated #{type}" - end - - def scan_comment - result = '' - nest = 1 - content = @comment_re - - until eof? - if s = readstr(content) then result << s - elsif skip(/\A\)/) then nest -= 1 - return result if nest == 0 - result << ')' - elsif skip(/\A\(/) then nest += 1 - result << '(' - elsif skip(/\A\\/) then result << readchar() - else - raise 'TMail FATAL: not match in comment' - end - end - scan_error! 'found unterminated comment' - end - - # string scanner - - def init_scanner( str ) - @src = str - end - - def eof? - @src.empty? - end - - def rest_size - @src.size - end - - def readstr( re ) - if m = re.match(@src) - @src = m.post_match - m[0] - else - nil - end - end - - def readchar - readstr(/\A./) - end - - def skip( re ) - if m = re.match(@src) - @src = m.post_match - true - else - false - end - end - - def scan_error!( msg ) - raise SyntaxError, msg - end - - end - -end # module TMail diff --git a/tracks/vendor/rails/actionmailer/lib/action_mailer/vendor/tmail/stringio.rb b/tracks/vendor/rails/actionmailer/lib/action_mailer/vendor/tmail/stringio.rb deleted file mode 100644 index 532be3db..00000000 --- a/tracks/vendor/rails/actionmailer/lib/action_mailer/vendor/tmail/stringio.rb +++ /dev/null @@ -1,277 +0,0 @@ -# -# stringio.rb -# -#-- -# Copyright (c) 1998-2003 Minero Aoki -# -# 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. -# -# Note: Originally licensed under LGPL v2+. Using MIT license for Rails -# with permission of Minero Aoki. -#++ - -class StringInput#:nodoc: - - include Enumerable - - class << self - - def new( str ) - if block_given? - begin - f = super - yield f - ensure - f.close if f - end - else - super - end - end - - alias open new - - end - - def initialize( str ) - @src = str - @pos = 0 - @closed = false - @lineno = 0 - end - - attr_reader :lineno - - def string - @src - end - - def inspect - "#<#{self.class}:#{@closed ? 'closed' : 'open'},src=#{@src[0,30].inspect}>" - end - - def close - stream_check! - @pos = nil - @closed = true - end - - def closed? - @closed - end - - def pos - stream_check! - [@pos, @src.size].min - end - - alias tell pos - - def seek( offset, whence = IO::SEEK_SET ) - stream_check! - case whence - when IO::SEEK_SET - @pos = offset - when IO::SEEK_CUR - @pos += offset - when IO::SEEK_END - @pos = @src.size - offset - else - raise ArgumentError, "unknown seek flag: #{whence}" - end - @pos = 0 if @pos < 0 - @pos = [@pos, @src.size + 1].min - offset - end - - def rewind - stream_check! - @pos = 0 - end - - def eof? - stream_check! - @pos > @src.size - end - - def each( &block ) - stream_check! - begin - @src.each(&block) - ensure - @pos = 0 - end - end - - def gets - stream_check! - if idx = @src.index(?\n, @pos) - idx += 1 # "\n".size - line = @src[ @pos ... idx ] - @pos = idx - @pos += 1 if @pos == @src.size - else - line = @src[ @pos .. -1 ] - @pos = @src.size + 1 - end - @lineno += 1 - - line - end - - def getc - stream_check! - ch = @src[@pos] - @pos += 1 - @pos += 1 if @pos == @src.size - ch - end - - def read( len = nil ) - stream_check! - return read_all unless len - str = @src[@pos, len] - @pos += len - @pos += 1 if @pos == @src.size - str - end - - alias sysread read - - def read_all - stream_check! - return nil if eof? - rest = @src[@pos ... @src.size] - @pos = @src.size + 1 - rest - end - - def stream_check! - @closed and raise IOError, 'closed stream' - end - -end - - -class StringOutput#:nodoc: - - class << self - - def new( str = '' ) - if block_given? - begin - f = super - yield f - ensure - f.close if f - end - else - super - end - end - - alias open new - - end - - def initialize( str = '' ) - @dest = str - @closed = false - end - - def close - @closed = true - end - - def closed? - @closed - end - - def string - @dest - end - - alias value string - alias to_str string - - def size - @dest.size - end - - alias pos size - - def inspect - "#<#{self.class}:#{@dest ? 'open' : 'closed'},#{id}>" - end - - def print( *args ) - stream_check! - raise ArgumentError, 'wrong # of argument (0 for >1)' if args.empty? - args.each do |s| - raise ArgumentError, 'nil not allowed' if s.nil? - @dest << s.to_s - end - nil - end - - def puts( *args ) - stream_check! - args.each do |str| - @dest << (s = str.to_s) - @dest << "\n" unless s[-1] == ?\n - end - @dest << "\n" if args.empty? - nil - end - - def putc( ch ) - stream_check! - @dest << ch.chr - nil - end - - def printf( *args ) - stream_check! - @dest << sprintf(*args) - nil - end - - def write( str ) - stream_check! - s = str.to_s - @dest << s - s.size - end - - alias syswrite write - - def <<( str ) - stream_check! - @dest << str.to_s - self - end - - private - - def stream_check! - @closed and raise IOError, 'closed stream' - end - -end diff --git a/tracks/vendor/rails/actionmailer/lib/action_mailer/vendor/tmail/tmail.rb b/tracks/vendor/rails/actionmailer/lib/action_mailer/vendor/tmail/tmail.rb deleted file mode 100644 index 57ed3cc5..00000000 --- a/tracks/vendor/rails/actionmailer/lib/action_mailer/vendor/tmail/tmail.rb +++ /dev/null @@ -1 +0,0 @@ -require 'tmail' diff --git a/tracks/vendor/rails/actionmailer/lib/action_mailer/vendor/tmail/utils.rb b/tracks/vendor/rails/actionmailer/lib/action_mailer/vendor/tmail/utils.rb deleted file mode 100644 index 852acd75..00000000 --- a/tracks/vendor/rails/actionmailer/lib/action_mailer/vendor/tmail/utils.rb +++ /dev/null @@ -1,238 +0,0 @@ -# -# utils.rb -# -#-- -# Copyright (c) 1998-2003 Minero Aoki -# -# 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. -# -# Note: Originally licensed under LGPL v2+. Using MIT license for Rails -# with permission of Minero Aoki. -#++ - -module TMail - - class SyntaxError < StandardError; end - - - def TMail.new_boundary - 'mimepart_' + random_tag - end - - def TMail.new_message_id( fqdn = nil ) - fqdn ||= ::Socket.gethostname - "<#{random_tag()}@#{fqdn}.tmail>" - end - - def TMail.random_tag - @uniq += 1 - t = Time.now - sprintf('%x%x_%x%x%d%x', - t.to_i, t.tv_usec, - $$, Thread.current.object_id, @uniq, rand(255)) - end - private_class_method :random_tag - - @uniq = 0 - - - module TextUtils - - aspecial = '()<>[]:;.\\,"' - tspecial = '()<>[];:\\,"/?=' - lwsp = " \t\r\n" - control = '\x00-\x1f\x7f-\xff' - - ATOM_UNSAFE = /[#{Regexp.quote aspecial}#{control}#{lwsp}]/n - PHRASE_UNSAFE = /[#{Regexp.quote aspecial}#{control}]/n - TOKEN_UNSAFE = /[#{Regexp.quote tspecial}#{control}#{lwsp}]/n - CONTROL_CHAR = /[#{control}]/n - - def atom_safe?( str ) - not ATOM_UNSAFE === str - end - - def quote_atom( str ) - (ATOM_UNSAFE === str) ? dquote(str) : str - end - - def quote_phrase( str ) - (PHRASE_UNSAFE === str) ? dquote(str) : str - end - - def token_safe?( str ) - not TOKEN_UNSAFE === str - end - - def quote_token( str ) - (TOKEN_UNSAFE === str) ? dquote(str) : str - end - - def dquote( str ) - '"' + str.gsub(/["\\]/n) {|s| '\\' + s } + '"' - end - private :dquote - - - def join_domain( arr ) - arr.map {|i| - if /\A\[.*\]\z/ === i - i - else - quote_atom(i) - end - }.join('.') - end - - - ZONESTR_TABLE = { - 'jst' => 9 * 60, - 'eet' => 2 * 60, - 'bst' => 1 * 60, - 'met' => 1 * 60, - 'gmt' => 0, - 'utc' => 0, - 'ut' => 0, - 'nst' => -(3 * 60 + 30), - 'ast' => -4 * 60, - 'edt' => -4 * 60, - 'est' => -5 * 60, - 'cdt' => -5 * 60, - 'cst' => -6 * 60, - 'mdt' => -6 * 60, - 'mst' => -7 * 60, - 'pdt' => -7 * 60, - 'pst' => -8 * 60, - 'a' => -1 * 60, - 'b' => -2 * 60, - 'c' => -3 * 60, - 'd' => -4 * 60, - 'e' => -5 * 60, - 'f' => -6 * 60, - 'g' => -7 * 60, - 'h' => -8 * 60, - 'i' => -9 * 60, - # j not use - 'k' => -10 * 60, - 'l' => -11 * 60, - 'm' => -12 * 60, - 'n' => 1 * 60, - 'o' => 2 * 60, - 'p' => 3 * 60, - 'q' => 4 * 60, - 'r' => 5 * 60, - 's' => 6 * 60, - 't' => 7 * 60, - 'u' => 8 * 60, - 'v' => 9 * 60, - 'w' => 10 * 60, - 'x' => 11 * 60, - 'y' => 12 * 60, - 'z' => 0 * 60 - } - - def timezone_string_to_unixtime( str ) - if m = /([\+\-])(\d\d?)(\d\d)/.match(str) - sec = (m[2].to_i * 60 + m[3].to_i) * 60 - m[1] == '-' ? -sec : sec - else - min = ZONESTR_TABLE[str.downcase] or - raise SyntaxError, "wrong timezone format '#{str}'" - min * 60 - end - end - - - WDAY = %w( Sun Mon Tue Wed Thu Fri Sat TMailBUG ) - MONTH = %w( TMailBUG Jan Feb Mar Apr May Jun - Jul Aug Sep Oct Nov Dec TMailBUG ) - - def time2str( tm ) - # [ruby-list:7928] - gmt = Time.at(tm.to_i) - gmt.gmtime - offset = tm.to_i - Time.local(*gmt.to_a[0,6].reverse).to_i - - # DO NOT USE strftime: setlocale() breaks it - sprintf '%s, %s %s %d %02d:%02d:%02d %+.2d%.2d', - WDAY[tm.wday], tm.mday, MONTH[tm.month], - tm.year, tm.hour, tm.min, tm.sec, - *(offset / 60).divmod(60) - end - - - MESSAGE_ID = /<[^\@>]+\@[^>\@]+>/ - - def message_id?( str ) - MESSAGE_ID === str - end - - - MIME_ENCODED = /=\?[^\s?=]+\?[QB]\?[^\s?=]+\?=/i - - def mime_encoded?( str ) - MIME_ENCODED === str - end - - - def decode_params( hash ) - new = Hash.new - encoded = nil - hash.each do |key, value| - if m = /\*(?:(\d+)\*)?\z/.match(key) - ((encoded ||= {})[m.pre_match] ||= [])[(m[1] || 0).to_i] = value - else - new[key] = to_kcode(value) - end - end - if encoded - encoded.each do |key, strings| - new[key] = decode_RFC2231(strings.join('')) - end - end - - new - end - - NKF_FLAGS = { - 'EUC' => '-e -m', - 'SJIS' => '-s -m' - } - - def to_kcode( str ) - flag = NKF_FLAGS[$KCODE] or return str - NKF.nkf(flag, str) - end - - RFC2231_ENCODED = /\A(?:iso-2022-jp|euc-jp|shift_jis|us-ascii)?'[a-z]*'/in - - def decode_RFC2231( str ) - m = RFC2231_ENCODED.match(str) or return str - begin - NKF.nkf(NKF_FLAGS[$KCODE], - m.post_match.gsub(/%[\da-f]{2}/in) {|s| s[1,2].hex.chr }) - rescue - m.post_match.gsub(/%[\da-f]{2}/in, "") - end - end - - end - -end diff --git a/tracks/vendor/rails/actionmailer/lib/action_mailer/version.rb b/tracks/vendor/rails/actionmailer/lib/action_mailer/version.rb deleted file mode 100644 index 02c6d83e..00000000 --- a/tracks/vendor/rails/actionmailer/lib/action_mailer/version.rb +++ /dev/null @@ -1,9 +0,0 @@ -module ActionMailer - module VERSION #:nodoc: - MAJOR = 1 - MINOR = 1 - TINY = 5 - - STRING = [MAJOR, MINOR, TINY].join('.') - end -end diff --git a/tracks/vendor/rails/actionmailer/rakefile b/tracks/vendor/rails/actionmailer/rakefile deleted file mode 100644 index 5ac7d616..00000000 --- a/tracks/vendor/rails/actionmailer/rakefile +++ /dev/null @@ -1,198 +0,0 @@ -require 'rubygems' -require 'rake' -require 'rake/testtask' -require 'rake/rdoctask' -require 'rake/packagetask' -require 'rake/gempackagetask' -require 'rake/contrib/rubyforgepublisher' -require File.join(File.dirname(__FILE__), 'lib', 'action_mailer', 'version') - -PKG_BUILD = ENV['PKG_BUILD'] ? '.' + ENV['PKG_BUILD'] : '' -PKG_NAME = 'actionmailer' -PKG_VERSION = ActionMailer::VERSION::STRING + PKG_BUILD -PKG_FILE_NAME = "#{PKG_NAME}-#{PKG_VERSION}" - -RELEASE_NAME = "REL #{PKG_VERSION}" - -RUBY_FORGE_PROJECT = "actionmailer" -RUBY_FORGE_USER = "webster132" - -desc "Default Task" -task :default => [ :test ] - -# Run the unit tests -Rake::TestTask.new { |t| - t.libs << "test" - t.pattern = 'test/*_test.rb' - t.verbose = true -} - - -# Genereate the RDoc documentation -Rake::RDocTask.new { |rdoc| - rdoc.rdoc_dir = 'doc' - rdoc.title = "Action Mailer -- Easy email delivery and testing" - rdoc.options << '--line-numbers --inline-source --main README --accessor adv_attr_accessor=M' - rdoc.template = "#{ENV['template']}.rb" if ENV['template'] - rdoc.rdoc_files.include('README', 'CHANGELOG') - rdoc.rdoc_files.include('lib/action_mailer.rb') - rdoc.rdoc_files.include('lib/action_mailer/*.rb') -} - - -# Create compressed packages -spec = Gem::Specification.new do |s| - s.platform = Gem::Platform::RUBY - s.name = PKG_NAME - s.summary = "Service layer for easy email delivery and testing." - s.description = %q{Makes it trivial to test and deliver emails sent from a single service layer.} - s.version = PKG_VERSION - - s.author = "David Heinemeier Hansson" - s.email = "david@loudthinking.com" - s.rubyforge_project = "actionmailer" - s.homepage = "http://www.rubyonrails.org" - - s.add_dependency('actionpack', '= 1.11.2' + PKG_BUILD) - - s.has_rdoc = true - s.requirements << 'none' - s.require_path = 'lib' - s.autorequire = 'action_mailer' - - s.files = [ "rakefile", "install.rb", "README", "CHANGELOG", "MIT-LICENSE" ] - s.files = s.files + Dir.glob( "lib/**/*" ).delete_if { |item| item.include?( "\.svn" ) } - s.files = s.files + Dir.glob( "test/**/*" ).delete_if { |item| item.include?( "\.svn" ) } -end - -Rake::GemPackageTask.new(spec) do |p| - p.gem_spec = spec - p.need_tar = true - p.need_zip = true -end - - -desc "Publish the API documentation" -task :pgem => [:package] do - Rake::SshFilePublisher.new("davidhh@wrath.rubyonrails.org", "public_html/gems/gems", "pkg", "#{PKG_FILE_NAME}.gem").upload -end - -desc "Publish the API documentation" -task :pdoc => [:rdoc] do - Rake::SshDirPublisher.new("davidhh@wrath.rubyonrails.org", "public_html/am", "doc").upload -end - -desc "Publish the release files to RubyForge." -task :release => [:package] do - files = ["gem", "tgz", "zip"].map { |ext| "pkg/#{PKG_FILE_NAME}.#{ext}" } - - if RUBY_FORGE_PROJECT then - require 'net/http' - require 'open-uri' - - project_uri = "http://rubyforge.org/projects/#{RUBY_FORGE_PROJECT}/" - project_data = open(project_uri) { |data| data.read } - group_id = project_data[/[?&]group_id=(\d+)/, 1] - raise "Couldn't get group id" unless group_id - - # This echos password to shell which is a bit sucky - if ENV["RUBY_FORGE_PASSWORD"] - password = ENV["RUBY_FORGE_PASSWORD"] - else - print "#{RUBY_FORGE_USER}@rubyforge.org's password: " - password = STDIN.gets.chomp - end - - login_response = Net::HTTP.start("rubyforge.org", 80) do |http| - data = [ - "login=1", - "form_loginname=#{RUBY_FORGE_USER}", - "form_pw=#{password}" - ].join("&") - http.post("/account/login.php", data) - end - - cookie = login_response["set-cookie"] - raise "Login failed" unless cookie - headers = { "Cookie" => cookie } - - release_uri = "http://rubyforge.org/frs/admin/?group_id=#{group_id}" - release_data = open(release_uri, headers) { |data| data.read } - package_id = release_data[/[?&]package_id=(\d+)/, 1] - raise "Couldn't get package id" unless package_id - - first_file = true - release_id = "" - - files.each do |filename| - basename = File.basename(filename) - file_ext = File.extname(filename) - file_data = File.open(filename, "rb") { |file| file.read } - - puts "Releasing #{basename}..." - - release_response = Net::HTTP.start("rubyforge.org", 80) do |http| - release_date = Time.now.strftime("%Y-%m-%d %H:%M") - type_map = { - ".zip" => "3000", - ".tgz" => "3110", - ".gz" => "3110", - ".gem" => "1400" - }; type_map.default = "9999" - type = type_map[file_ext] - boundary = "rubyqMY6QN9bp6e4kS21H4y0zxcvoor" - - query_hash = if first_file then - { - "group_id" => group_id, - "package_id" => package_id, - "release_name" => RELEASE_NAME, - "release_date" => release_date, - "type_id" => type, - "processor_id" => "8000", # Any - "release_notes" => "", - "release_changes" => "", - "preformatted" => "1", - "submit" => "1" - } - else - { - "group_id" => group_id, - "release_id" => release_id, - "package_id" => package_id, - "step2" => "1", - "type_id" => type, - "processor_id" => "8000", # Any - "submit" => "Add This File" - } - end - - query = "?" + query_hash.map do |(name, value)| - [name, URI.encode(value)].join("=") - end.join("&") - - data = [ - "--" + boundary, - "Content-Disposition: form-data; name=\"userfile\"; filename=\"#{basename}\"", - "Content-Type: application/octet-stream", - "Content-Transfer-Encoding: binary", - "", file_data, "" - ].join("\x0D\x0A") - - release_headers = headers.merge( - "Content-Type" => "multipart/form-data; boundary=#{boundary}" - ) - - target = first_file ? "/frs/admin/qrs.php" : "/frs/admin/editrelease.php" - http.post(target + query, data, release_headers) - end - - if first_file then - release_id = release_response.body[/release_id=(\d+)/, 1] - raise("Couldn't get release id") unless release_id - end - - first_file = false - end - end -end diff --git a/tracks/vendor/rails/actionmailer/test/fixtures/helper_mailer/use_helper.rhtml b/tracks/vendor/rails/actionmailer/test/fixtures/helper_mailer/use_helper.rhtml deleted file mode 100644 index 378777f8..00000000 --- a/tracks/vendor/rails/actionmailer/test/fixtures/helper_mailer/use_helper.rhtml +++ /dev/null @@ -1 +0,0 @@ -Hello, <%= person_name %>. Thanks for registering! diff --git a/tracks/vendor/rails/actionmailer/test/fixtures/helper_mailer/use_helper_method.rhtml b/tracks/vendor/rails/actionmailer/test/fixtures/helper_mailer/use_helper_method.rhtml deleted file mode 100644 index d5b8b285..00000000 --- a/tracks/vendor/rails/actionmailer/test/fixtures/helper_mailer/use_helper_method.rhtml +++ /dev/null @@ -1 +0,0 @@ -This message brought to you by <%= name_of_the_mailer_class %>. diff --git a/tracks/vendor/rails/actionmailer/test/fixtures/helper_mailer/use_mail_helper.rhtml b/tracks/vendor/rails/actionmailer/test/fixtures/helper_mailer/use_mail_helper.rhtml deleted file mode 100644 index 96ec49d1..00000000 --- a/tracks/vendor/rails/actionmailer/test/fixtures/helper_mailer/use_mail_helper.rhtml +++ /dev/null @@ -1,5 +0,0 @@ -From "Romeo and Juliet": - -<%= block_format @text %> - -Good ol' Shakespeare. diff --git a/tracks/vendor/rails/actionmailer/test/fixtures/helper_mailer/use_test_helper.rhtml b/tracks/vendor/rails/actionmailer/test/fixtures/helper_mailer/use_test_helper.rhtml deleted file mode 100644 index 52ea9aa4..00000000 --- a/tracks/vendor/rails/actionmailer/test/fixtures/helper_mailer/use_test_helper.rhtml +++ /dev/null @@ -1 +0,0 @@ -So, <%= test_format(@text) %> diff --git a/tracks/vendor/rails/actionmailer/test/fixtures/helpers/test_helper.rb b/tracks/vendor/rails/actionmailer/test/fixtures/helpers/test_helper.rb deleted file mode 100644 index f479820c..00000000 --- a/tracks/vendor/rails/actionmailer/test/fixtures/helpers/test_helper.rb +++ /dev/null @@ -1,5 +0,0 @@ -module TestHelper - def test_format(text) - "#{text}" - end -end diff --git a/tracks/vendor/rails/actionmailer/test/fixtures/raw_email b/tracks/vendor/rails/actionmailer/test/fixtures/raw_email deleted file mode 100644 index 43f7a59c..00000000 --- a/tracks/vendor/rails/actionmailer/test/fixtures/raw_email +++ /dev/null @@ -1,14 +0,0 @@ -From jamis_buck@byu.edu Mon May 2 16:07:05 2005 -Mime-Version: 1.0 (Apple Message framework v622) -Content-Transfer-Encoding: base64 -Message-Id: -Content-Type: text/plain; - charset=EUC-KR; - format=flowed -To: willard15georgina@jamis.backpackit.com -From: Jamis Buck -Subject: =?EUC-KR?Q?NOTE:_=C7=D1=B1=B9=B8=BB=B7=CE_=C7=CF=B4=C2_=B0=CD?= -Date: Mon, 2 May 2005 16:07:05 -0600 - -tOu6zrrQwMcguLbC+bChwfa3ziwgv+y4rrTCIMfPs6q01MC7ILnPvcC0z7TZLg0KDQrBpiDAzLin -wLogSmFtaXPA1LTPtNku diff --git a/tracks/vendor/rails/actionmailer/test/fixtures/raw_email10 b/tracks/vendor/rails/actionmailer/test/fixtures/raw_email10 deleted file mode 100644 index b1fc2b26..00000000 --- a/tracks/vendor/rails/actionmailer/test/fixtures/raw_email10 +++ /dev/null @@ -1,20 +0,0 @@ -Return-Path: -Received: from xxx.xxxx.xxx by xxx.xxxx.xxx with ESMTP id C1B953B4CB6 for ; Tue, 10 May 2005 15:27:05 -0500 -Received: from SMS-GTYxxx.xxxx.xxx by xxx.xxxx.xxx with ESMTP id ca for ; Tue, 10 May 2005 15:27:04 -0500 -Received: from xxx.xxxx.xxx by SMS-GTYxxx.xxxx.xxx with ESMTP id j4AKR3r23323 for ; Tue, 10 May 2005 15:27:03 -0500 -Date: Tue, 10 May 2005 15:27:03 -0500 -From: xxx@xxxx.xxx -Sender: xxx@xxxx.xxx -To: xxxxxxxxxxx@xxxx.xxxx.xxx -Message-Id: -X-Original-To: xxxxxxxxxxx@xxxx.xxxx.xxx -Delivered-To: xxx@xxxx.xxx -Importance: normal -Content-Type: text/plain; charset=X-UNKNOWN - -Test test. Hi. Waving. m - ----------------------------------------------------------------- -Sent via Bell Mobility's Text Messaging service. -Envoyé par le service de messagerie texte de Bell Mobilité. ----------------------------------------------------------------- diff --git a/tracks/vendor/rails/actionmailer/test/fixtures/raw_email11 b/tracks/vendor/rails/actionmailer/test/fixtures/raw_email11 deleted file mode 100644 index 8af74b87..00000000 --- a/tracks/vendor/rails/actionmailer/test/fixtures/raw_email11 +++ /dev/null @@ -1,34 +0,0 @@ -From xxx@xxxx.com Wed Apr 27 14:15:31 2005 -Mime-Version: 1.0 (Apple Message framework v619.2) -To: xxxxx@xxxxx -Message-Id: <416eaebec6d333ec6939eaf8a7d80724@xxxxx> -Content-Type: multipart/alternative; - boundary=Apple-Mail-5-1037861608 -From: xxxxx@xxxxx -Subject: worse when you use them. -Date: Wed, 27 Apr 2005 14:15:31 -0700 - - - - ---Apple-Mail-5-1037861608 -Content-Transfer-Encoding: 7bit -Content-Type: text/plain; - charset=US-ASCII; - format=flowed - - -XXXXX Xxxxx - ---Apple-Mail-5-1037861608 -Content-Transfer-Encoding: 7bit -Content-Type: text/enriched; - charset=US-ASCII - - - -XXXXX Xxxxx - - ---Apple-Mail-5-1037861608-- - diff --git a/tracks/vendor/rails/actionmailer/test/fixtures/raw_email12 b/tracks/vendor/rails/actionmailer/test/fixtures/raw_email12 deleted file mode 100644 index 2cd31720..00000000 --- a/tracks/vendor/rails/actionmailer/test/fixtures/raw_email12 +++ /dev/null @@ -1,32 +0,0 @@ -Mime-Version: 1.0 (Apple Message framework v730) -Content-Type: multipart/mixed; boundary=Apple-Mail-13-196941151 -Message-Id: <9169D984-4E0B-45EF-82D4-8F5E53AD7012@example.com> -From: foo@example.com -Subject: testing -Date: Mon, 6 Jun 2005 22:21:22 +0200 -To: blah@example.com - - ---Apple-Mail-13-196941151 -Content-Transfer-Encoding: quoted-printable -Content-Type: text/plain; - charset=ISO-8859-1; - delsp=yes; - format=flowed - -This is the first part. - ---Apple-Mail-13-196941151 -Content-Type: image/jpeg -Content-Transfer-Encoding: base64 -Content-Location: Photo25.jpg -Content-ID: -Content-Disposition: inline - -jamisSqGSIb3DQEHAqCAMIjamisxCzAJBgUrDgMCGgUAMIAGCSqGSjamisEHAQAAoIIFSjCCBUYw -ggQujamisQICBD++ukQwDQYJKojamisNAQEFBQAwMTELMAkGA1UEBhMCRjamisAKBgNVBAoTA1RE -QzEUMBIGjamisxMLVERDIE9DRVMgQ0jamisNMDQwMjI5MTE1OTAxWhcNMDYwMjamisIyOTAxWjCB -gDELMAkGA1UEjamisEsxKTAnBgNVBAoTIEjamisuIG9yZ2FuaXNhdG9yaXNrIHRpbjamisRuaW5= - ---Apple-Mail-13-196941151-- - diff --git a/tracks/vendor/rails/actionmailer/test/fixtures/raw_email2 b/tracks/vendor/rails/actionmailer/test/fixtures/raw_email2 deleted file mode 100644 index 3999fcc8..00000000 --- a/tracks/vendor/rails/actionmailer/test/fixtures/raw_email2 +++ /dev/null @@ -1,114 +0,0 @@ -From xxxxxxxxx.xxxxxxx@gmail.com Sun May 8 19:07:09 2005 -Return-Path: -X-Original-To: xxxxx@xxxxx.xxxxxxxxx.com -Delivered-To: xxxxx@xxxxx.xxxxxxxxx.com -Received: from localhost (localhost [127.0.0.1]) - by xxxxx.xxxxxxxxx.com (Postfix) with ESMTP id 06C9DA98D - for ; Sun, 8 May 2005 19:09:13 +0000 (GMT) -Received: from xxxxx.xxxxxxxxx.com ([127.0.0.1]) - by localhost (xxxxx.xxxxxxxxx.com [127.0.0.1]) (amavisd-new, port 10024) - with LMTP id 88783-08 for ; - Sun, 8 May 2005 19:09:12 +0000 (GMT) -Received: from xxxxxxx.xxxxxxxxx.com (xxxxxxx.xxxxxxxxx.com [69.36.39.150]) - by xxxxx.xxxxxxxxx.com (Postfix) with ESMTP id 10D8BA960 - for ; Sun, 8 May 2005 19:09:12 +0000 (GMT) -Received: from zproxy.gmail.com (zproxy.gmail.com [64.233.162.199]) - by xxxxxxx.xxxxxxxxx.com (Postfix) with ESMTP id 9EBC4148EAB - for ; Sun, 8 May 2005 14:09:11 -0500 (CDT) -Received: by zproxy.gmail.com with SMTP id 13so1233405nzp - for ; Sun, 08 May 2005 12:09:11 -0700 (PDT) -DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; - s=beta; d=gmail.com; - h=received:message-id:date:from:reply-to:to:subject:in-reply-to:mime-version:content-type:references; - b=cid1mzGEFa3gtRa06oSrrEYfKca2CTKu9sLMkWxjbvCsWMtp9RGEILjUz0L5RySdH5iO661LyNUoHRFQIa57bylAbXM3g2DTEIIKmuASDG3x3rIQ4sHAKpNxP7Pul+mgTaOKBv+spcH7af++QEJ36gHFXD2O/kx9RePs3JNf/K8= -Received: by 10.36.10.16 with SMTP id 16mr1012493nzj; - Sun, 08 May 2005 12:09:11 -0700 (PDT) -Received: by 10.36.5.10 with HTTP; Sun, 8 May 2005 12:09:11 -0700 (PDT) -Message-ID: -Date: Sun, 8 May 2005 14:09:11 -0500 -From: xxxxxxxxx xxxxxxx -Reply-To: xxxxxxxxx xxxxxxx -To: xxxxx xxxx -Subject: Fwd: Signed email causes file attachments -In-Reply-To: -Mime-Version: 1.0 -Content-Type: multipart/mixed; - boundary="----=_Part_5028_7368284.1115579351471" -References: - -------=_Part_5028_7368284.1115579351471 -Content-Type: text/plain; charset=ISO-8859-1 -Content-Transfer-Encoding: quoted-printable -Content-Disposition: inline - -We should not include these files or vcards as attachments. - ----------- Forwarded message ---------- -From: xxxxx xxxxxx -Date: May 8, 2005 1:17 PM -Subject: Signed email causes file attachments -To: xxxxxxx@xxxxxxxxxx.com - - -Hi, - -Just started to use my xxxxxxxx account (to set-up a GTD system, -natch) and noticed that when I send content via email the signature/ -certificate from my email account gets added as a file (e.g. -"smime.p7s"). - -Obviously I can uncheck the signature option in the Mail compose -window but how often will I remember to do that? - -Is there any way these kind of files could be ignored, e.g. via some -sort of exclusions list? - -------=_Part_5028_7368284.1115579351471 -Content-Type: application/pkcs7-signature; name=smime.p7s -Content-Transfer-Encoding: base64 -Content-Disposition: attachment; filename="smime.p7s" - -MIAGCSqGSIb3DQEHAqCAMIACAQExCzAJBgUrDgMCGgUAMIAGCSqGSIb3DQEHAQAAoIIGFDCCAs0w -ggI2oAMCAQICAw5c+TANBgkqhkiG9w0BAQQFADBiMQswCQYDVQQGEwJaQTElMCMGA1UEChMcVGhh -d3RlIENvbnN1bHRpbmcgKFB0eSkgTHRkLjEsMCoGA1UEAxMjVGhhd3RlIFBlcnNvbmFsIEZyZWVt -YWlsIElzc3VpbmcgQ0EwHhcNMDUwMzI5MDkzOTEwWhcNMDYwMzI5MDkzOTEwWjBCMR8wHQYDVQQD -ExZUaGF3dGUgRnJlZW1haWwgTWVtYmVyMR8wHQYJKoZIhvcNAQkBFhBzbWhhdW5jaEBtYWMuY29t -MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAn90dPsYS3LjfMY211OSYrDQLzwNYPlAL -7+/0XA+kdy8/rRnyEHFGwhNCDmg0B6pxC7z3xxJD/8GfCd+IYUUNUQV5m9MkxfP9pTVXZVIYLaBw -o8xS3A0a1LXealcmlEbJibmKkEaoXci3MhryLgpaa+Kk/sH02SNatDO1vS28bPsibZpcc6deFrla -hSYnL+PW54mDTGHIcCN2fbx/Y6qspzqmtKaXrv75NBtuy9cB6KzU4j2xXbTkAwz3pRSghJJaAwdp -+yIivAD3vr0kJE3p+Ez34HMh33EXEpFoWcN+MCEQZD9WnmFViMrvfvMXLGVFQfAAcC060eGFSRJ1 -ZQ9UVQIDAQABoy0wKzAbBgNVHREEFDASgRBzbWhhdW5jaEBtYWMuY29tMAwGA1UdEwEB/wQCMAAw -DQYJKoZIhvcNAQEEBQADgYEAQMrg1n2pXVWteP7BBj+Pk3UfYtbuHb42uHcLJjfjnRlH7AxnSwrd -L3HED205w3Cq8T7tzVxIjRRLO/ljq0GedSCFBky7eYo1PrXhztGHCTSBhsiWdiyLWxKlOxGAwJc/ -lMMnwqLOdrQcoF/YgbjeaUFOQbUh94w9VDNpWZYCZwcwggM/MIICqKADAgECAgENMA0GCSqGSIb3 -DQEBBQUAMIHRMQswCQYDVQQGEwJaQTEVMBMGA1UECBMMV2VzdGVybiBDYXBlMRIwEAYDVQQHEwlD -YXBlIFRvd24xGjAYBgNVBAoTEVRoYXd0ZSBDb25zdWx0aW5nMSgwJgYDVQQLEx9DZXJ0aWZpY2F0 -aW9uIFNlcnZpY2VzIERpdmlzaW9uMSQwIgYDVQQDExtUaGF3dGUgUGVyc29uYWwgRnJlZW1haWwg -Q0ExKzApBgkqhkiG9w0BCQEWHHBlcnNvbmFsLWZyZWVtYWlsQHRoYXd0ZS5jb20wHhcNMDMwNzE3 -MDAwMDAwWhcNMTMwNzE2MjM1OTU5WjBiMQswCQYDVQQGEwJaQTElMCMGA1UEChMcVGhhd3RlIENv -bnN1bHRpbmcgKFB0eSkgTHRkLjEsMCoGA1UEAxMjVGhhd3RlIFBlcnNvbmFsIEZyZWVtYWlsIElz -c3VpbmcgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMSmPFVzVftOucqZWh5owHUEcJ3f -6f+jHuy9zfVb8hp2vX8MOmHyv1HOAdTlUAow1wJjWiyJFXCO3cnwK4Vaqj9xVsuvPAsH5/EfkTYk -KhPPK9Xzgnc9A74r/rsYPge/QIACZNenprufZdHFKlSFD0gEf6e20TxhBEAeZBlyYLf7AgMBAAGj -gZQwgZEwEgYDVR0TAQH/BAgwBgEB/wIBADBDBgNVHR8EPDA6MDigNqA0hjJodHRwOi8vY3JsLnRo -YXd0ZS5jb20vVGhhd3RlUGVyc29uYWxGcmVlbWFpbENBLmNybDALBgNVHQ8EBAMCAQYwKQYDVR0R -BCIwIKQeMBwxGjAYBgNVBAMTEVByaXZhdGVMYWJlbDItMTM4MA0GCSqGSIb3DQEBBQUAA4GBAEiM -0VCD6gsuzA2jZqxnD3+vrL7CF6FDlpSdf0whuPg2H6otnzYvwPQcUCCTcDz9reFhYsPZOhl+hLGZ -GwDFGguCdJ4lUJRix9sncVcljd2pnDmOjCBPZV+V2vf3h9bGCE6u9uo05RAaWzVNd+NWIXiC3CEZ -Nd4ksdMdRv9dX2VPMYIC5zCCAuMCAQEwaTBiMQswCQYDVQQGEwJaQTElMCMGA1UEChMcVGhhd3Rl -IENvbnN1bHRpbmcgKFB0eSkgTHRkLjEsMCoGA1UEAxMjVGhhd3RlIFBlcnNvbmFsIEZyZWVtYWls -IElzc3VpbmcgQ0ECAw5c+TAJBgUrDgMCGgUAoIIBUzAYBgkqhkiG9w0BCQMxCwYJKoZIhvcNAQcB -MBwGCSqGSIb3DQEJBTEPFw0wNTA1MDgxODE3NDZaMCMGCSqGSIb3DQEJBDEWBBQSkG9j6+hB0pKp -fV9tCi/iP59sNTB4BgkrBgEEAYI3EAQxazBpMGIxCzAJBgNVBAYTAlpBMSUwIwYDVQQKExxUaGF3 -dGUgQ29uc3VsdGluZyAoUHR5KSBMdGQuMSwwKgYDVQQDEyNUaGF3dGUgUGVyc29uYWwgRnJlZW1h -aWwgSXNzdWluZyBDQQIDDlz5MHoGCyqGSIb3DQEJEAILMWugaTBiMQswCQYDVQQGEwJaQTElMCMG -A1UEChMcVGhhd3RlIENvbnN1bHRpbmcgKFB0eSkgTHRkLjEsMCoGA1UEAxMjVGhhd3RlIFBlcnNv -bmFsIEZyZWVtYWlsIElzc3VpbmcgQ0ECAw5c+TANBgkqhkiG9w0BAQEFAASCAQAm1GeF7dWfMvrW -8yMPjkhE+R8D1DsiCoWSCp+5gAQm7lcK7V3KrZh5howfpI3TmCZUbbaMxOH+7aKRKpFemxoBY5Q8 -rnCkbpg/++/+MI01T69hF/rgMmrGcrv2fIYy8EaARLG0xUVFSZHSP+NQSYz0TTmh4cAESHMzY3JA -nHOoUkuPyl8RXrimY1zn0lceMXlweZRouiPGuPNl1hQKw8P+GhOC5oLlM71UtStnrlk3P9gqX5v7 -Tj7Hx057oVfY8FMevjxGwU3EK5TczHezHbWWgTyum9l2ZQbUQsDJxSniD3BM46C1VcbDLPaotAZ0 -fTYLZizQfm5hcWEbfYVzkSzLAAAAAAAA -------=_Part_5028_7368284.1115579351471-- - diff --git a/tracks/vendor/rails/actionmailer/test/fixtures/raw_email3 b/tracks/vendor/rails/actionmailer/test/fixtures/raw_email3 deleted file mode 100644 index 771a9635..00000000 --- a/tracks/vendor/rails/actionmailer/test/fixtures/raw_email3 +++ /dev/null @@ -1,70 +0,0 @@ -From xxxx@xxxx.com Tue May 10 11:28:07 2005 -Return-Path: -X-Original-To: xxxx@xxxx.com -Delivered-To: xxxx@xxxx.com -Received: from localhost (localhost [127.0.0.1]) - by xxx.xxxxx.com (Postfix) with ESMTP id 50FD3A96F - for ; Tue, 10 May 2005 17:26:50 +0000 (GMT) -Received: from xxx.xxxxx.com ([127.0.0.1]) - by localhost (xxx.xxxxx.com [127.0.0.1]) (amavisd-new, port 10024) - with LMTP id 70060-03 for ; - Tue, 10 May 2005 17:26:49 +0000 (GMT) -Received: from xxx.xxxxx.com (xxx.xxxxx.com [69.36.39.150]) - by xxx.xxxxx.com (Postfix) with ESMTP id 8B957A94B - for ; Tue, 10 May 2005 17:26:48 +0000 (GMT) -Received: from xxx.xxxxx.com (xxx.xxxxx.com [64.233.184.203]) - by xxx.xxxxx.com (Postfix) with ESMTP id 9972514824C - for ; Tue, 10 May 2005 12:26:40 -0500 (CDT) -Received: by xxx.xxxxx.com with SMTP id 68so1694448wri - for ; Tue, 10 May 2005 10:26:40 -0700 (PDT) -DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; - s=beta; d=xxxxx.com; - h=received:message-id:date:from:reply-to:to:subject:mime-version:content-type; - b=g8ZO5ttS6GPEMAz9WxrRk9+9IXBUfQIYsZLL6T88+ECbsXqGIgfGtzJJFn6o9CE3/HMrrIGkN5AisxVFTGXWxWci5YA/7PTVWwPOhJff5BRYQDVNgRKqMl/SMttNrrRElsGJjnD1UyQ/5kQmcBxq2PuZI5Zc47u6CILcuoBcM+A= -Received: by 10.54.96.19 with SMTP id t19mr621017wrb; - Tue, 10 May 2005 10:26:39 -0700 (PDT) -Received: by 10.54.110.5 with HTTP; Tue, 10 May 2005 10:26:39 -0700 (PDT) -Message-ID: -Date: Tue, 10 May 2005 11:26:39 -0600 -From: Test Tester -Reply-To: Test Tester -To: xxxx@xxxx.com, xxxx@xxxx.com -Subject: Another PDF -Mime-Version: 1.0 -Content-Type: multipart/mixed; - boundary="----=_Part_2192_32400445.1115745999735" -X-Virus-Scanned: amavisd-new at textdrive.com - -------=_Part_2192_32400445.1115745999735 -Content-Type: text/plain; charset=ISO-8859-1 -Content-Transfer-Encoding: quoted-printable -Content-Disposition: inline - -Just attaching another PDF, here, to see what the message looks like, -and to see if I can figure out what is going wrong here. - -------=_Part_2192_32400445.1115745999735 -Content-Type: application/pdf; name="broken.pdf" -Content-Transfer-Encoding: base64 -Content-Disposition: attachment; filename="broken.pdf" - -JVBERi0xLjQNCiXk9tzfDQoxIDAgb2JqDQo8PCAvTGVuZ3RoIDIgMCBSDQogICAvRmlsdGVyIC9G -bGF0ZURlY29kZQ0KPj4NCnN0cmVhbQ0KeJy9Wt2KJbkNvm/od6jrhZxYln9hWEh2p+8HBvICySaE -ycLuTV4/1ifJ9qnq09NpSBimu76yLUuy/qzqcPz7+em3Ixx/CDc6CsXxs3b5+fvfjr/8cPz6/BRu -rbfAx/n3739/fuJylJ5u5fjX81OuDr4deK4Bz3z/aDP+8fz0yw8g0Ofq7ktr1Mn+u28rvhy/jVeD -QSa+9YNKHP/pxjvDNfVAx/m3MFz54FhvTbaseaxiDoN2LeMVMw+yA7RbHSCDzxZuaYB2E1Yay7QU -x89vz0+tyFDKMlAHK5yqLmnjF+c4RjEiQIUeKwblXMe+AsZjN1J5yGQL5DHpDHksurM81rF6PKab -gK6zAarIDzIiUY23rJsN9iorAE816aIu6lsgAdQFsuhhkHOUFgVjp2GjMqSewITXNQ27jrMeamkg -1rPI3iLWG2CIaSBB+V1245YVRICGbbpYKHc2USFDl6M09acQVQYhlwIrkBNLISvXhGlF1wi5FHCw -wxZkoGNJlVeJCEsqKA+3YAV5AMb6KkeaqEJQmFKKQU8T1pRi2ihE1Y4CDrqoYFFXYjJJOatsyzuI -8SIlykuxKTMibWK8H1PgEvqYgs4GmQSrEjJAalgGirIhik+p4ZQN9E3ETFPAHE1b8pp1l/0Rc1gl -fQs0ABWvyoZZzU8VnPXwVVcO9BEsyjEJaO6eBoZRyKGlrKoYoOygA8BGIzgwN3RQ15ouigG5idZQ -fx2U4Db2CqiLO0WHAZoylGiCAqhniNQjFjQPSkmjwfNTgQ6M1Ih+eWo36wFmjIxDJZiGUBiWsAyR -xX3EekGOizkGI96Ol9zVZTAivikURhRsHh2E3JhWMpSTZCnnonrLhMCodgrNcgo4uyJUJc6qnVss -nrGd1Ptr0YwisCOYyIbUwVjV4xBUNLbguSO2YHujonAMJkMdSI7bIw91Akq2AUlMUWGFTMAOamjU -OvZQCxIkY2pCpMFo/IwLdVLHs6nddwTRrgoVbvLU9eB0G4EMndV0TNoxHbt3JBWwK6hhv3iHfDtF -yokB302IpEBTnWICde4uYc/1khDbSIkQopO6lcqamGBu1OSE3N5IPSsZX00CkSHRiiyx6HQIShsS -HSVNswdVsaOUSAWq9aYhDtGDaoG5a3lBGkYt/lFlBFt1UqrYnzVtUpUQnLiZeouKgf1KhRBViRRk -ExepJCzTwEmFDalIRbLEGtw0gfpESOpIAF/NnpPzcVCG86s0g2DuSyd41uhNGbEgaSrWEXORErbw -------=_Part_2192_32400445.1115745999735-- - diff --git a/tracks/vendor/rails/actionmailer/test/fixtures/raw_email4 b/tracks/vendor/rails/actionmailer/test/fixtures/raw_email4 deleted file mode 100644 index 639ad40e..00000000 --- a/tracks/vendor/rails/actionmailer/test/fixtures/raw_email4 +++ /dev/null @@ -1,59 +0,0 @@ -Return-Path: -Received: from xxx.xxxx.xxx by xxx.xxxx.xxx with ESMTP id 6AAEE3B4D23 for ; Sun, 8 May 2005 12:30:23 -0500 -Received: from xxx.xxxx.xxx by xxx.xxxx.xxx with ESMTP id j48HUC213279 for ; Sun, 8 May 2005 12:30:13 -0500 -Received: from conversion-xxx.xxxx.xxx.net by xxx.xxxx.xxx id <0IG600901LQ64I@xxx.xxxx.xxx> for ; Sun, 8 May 2005 12:30:12 -0500 -Received: from agw1 by xxx.xxxx.xxx with ESMTP id <0IG600JFYLYCAxxx@xxxx.xxx> for ; Sun, 8 May 2005 12:30:12 -0500 -Date: Sun, 8 May 2005 12:30:08 -0500 -From: xxx@xxxx.xxx -To: xxx@xxxx.xxx -Message-Id: <7864245.1115573412626.JavaMxxx@xxxx.xxx> -Subject: Filth -Mime-Version: 1.0 -Content-Type: multipart/mixed; boundary=mimepart_427e4cb4ca329_133ae40413c81ef -X-Mms-Priority: 1 -X-Mms-Transaction-Id: 3198421808-0 -X-Mms-Message-Type: 0 -X-Mms-Sender-Visibility: 1 -X-Mms-Read-Reply: 1 -X-Original-To: xxx@xxxx.xxx -X-Mms-Message-Class: 0 -X-Mms-Delivery-Report: 0 -X-Mms-Mms-Version: 16 -Delivered-To: xxx@xxxx.xxx -X-Nokia-Ag-Version: 2.0 - -This is a multi-part message in MIME format. - ---mimepart_427e4cb4ca329_133ae40413c81ef -Content-Type: multipart/mixed; boundary=mimepart_427e4cb4cbd97_133ae40413c8217 - - - ---mimepart_427e4cb4cbd97_133ae40413c8217 -Content-Type: text/plain; charset=utf-8 -Content-Transfer-Encoding: 7bit -Content-Disposition: inline -Content-Location: text.txt - -Some text - ---mimepart_427e4cb4cbd97_133ae40413c8217-- - ---mimepart_427e4cb4ca329_133ae40413c81ef -Content-Type: text/plain; charset=us-ascii -Content-Transfer-Encoding: 7bit - - --- -This Orange Multi Media Message was sent wirefree from an Orange -MMS phone. If you would like to reply, please text or phone the -sender directly by using the phone number listed in the sender's -address. To learn more about Orange's Multi Media Messaging -Service, find us on the Web at xxx.xxxx.xxx.uk/mms - - ---mimepart_427e4cb4ca329_133ae40413c81ef - - ---mimepart_427e4cb4ca329_133ae40413c81ef- - diff --git a/tracks/vendor/rails/actionmailer/test/fixtures/raw_email5 b/tracks/vendor/rails/actionmailer/test/fixtures/raw_email5 deleted file mode 100644 index 151c6314..00000000 --- a/tracks/vendor/rails/actionmailer/test/fixtures/raw_email5 +++ /dev/null @@ -1,19 +0,0 @@ -Return-Path: -Received: from xxx.xxxx.xxx by xxx.xxxx.xxx with ESMTP id C1B953B4CB6 for ; Tue, 10 May 2005 15:27:05 -0500 -Received: from SMS-GTYxxx.xxxx.xxx by xxx.xxxx.xxx with ESMTP id ca for ; Tue, 10 May 2005 15:27:04 -0500 -Received: from xxx.xxxx.xxx by SMS-GTYxxx.xxxx.xxx with ESMTP id j4AKR3r23323 for ; Tue, 10 May 2005 15:27:03 -0500 -Date: Tue, 10 May 2005 15:27:03 -0500 -From: xxx@xxxx.xxx -Sender: xxx@xxxx.xxx -To: xxxxxxxxxxx@xxxx.xxxx.xxx -Message-Id: -X-Original-To: xxxxxxxxxxx@xxxx.xxxx.xxx -Delivered-To: xxx@xxxx.xxx -Importance: normal - -Test test. Hi. Waving. m - ----------------------------------------------------------------- -Sent via Bell Mobility's Text Messaging service. -Envoyé par le service de messagerie texte de Bell Mobilité. ----------------------------------------------------------------- diff --git a/tracks/vendor/rails/actionmailer/test/fixtures/raw_email6 b/tracks/vendor/rails/actionmailer/test/fixtures/raw_email6 deleted file mode 100644 index 93289c4f..00000000 --- a/tracks/vendor/rails/actionmailer/test/fixtures/raw_email6 +++ /dev/null @@ -1,20 +0,0 @@ -Return-Path: -Received: from xxx.xxxx.xxx by xxx.xxxx.xxx with ESMTP id C1B953B4CB6 for ; Tue, 10 May 2005 15:27:05 -0500 -Received: from SMS-GTYxxx.xxxx.xxx by xxx.xxxx.xxx with ESMTP id ca for ; Tue, 10 May 2005 15:27:04 -0500 -Received: from xxx.xxxx.xxx by SMS-GTYxxx.xxxx.xxx with ESMTP id j4AKR3r23323 for ; Tue, 10 May 2005 15:27:03 -0500 -Date: Tue, 10 May 2005 15:27:03 -0500 -From: xxx@xxxx.xxx -Sender: xxx@xxxx.xxx -To: xxxxxxxxxxx@xxxx.xxxx.xxx -Message-Id: -X-Original-To: xxxxxxxxxxx@xxxx.xxxx.xxx -Delivered-To: xxx@xxxx.xxx -Importance: normal -Content-Type: text/plain; charset=us-ascii - -Test test. Hi. Waving. m - ----------------------------------------------------------------- -Sent via Bell Mobility's Text Messaging service. -Envoyé par le service de messagerie texte de Bell Mobilité. ----------------------------------------------------------------- diff --git a/tracks/vendor/rails/actionmailer/test/fixtures/raw_email7 b/tracks/vendor/rails/actionmailer/test/fixtures/raw_email7 deleted file mode 100644 index 251172a7..00000000 --- a/tracks/vendor/rails/actionmailer/test/fixtures/raw_email7 +++ /dev/null @@ -1,56 +0,0 @@ -Mime-Version: 1.0 (Apple Message framework v730) -Content-Type: multipart/mixed; boundary=Apple-Mail-13-196941151 -Message-Id: <9169D984-4E0B-45EF-82D4-8F5E53AD7012@example.com> -From: foo@example.com -Subject: testing -Date: Mon, 6 Jun 2005 22:21:22 +0200 -To: blah@example.com - - ---Apple-Mail-13-196941151 -Content-Type: multipart/mixed; - boundary=Apple-Mail-12-196940926 - - ---Apple-Mail-12-196940926 -Content-Transfer-Encoding: quoted-printable -Content-Type: text/plain; - charset=ISO-8859-1; - delsp=yes; - format=flowed - -This is the first part. - ---Apple-Mail-12-196940926 -Content-Transfer-Encoding: base64 -Content-Type: application/pdf; - x-unix-mode=0666; - name="test.pdf" -Content-Disposition: inline; - filename=test.pdf - -YmxhaCBibGFoIGJsYWg= - ---Apple-Mail-12-196940926 -Content-Transfer-Encoding: 7bit -Content-Type: text/plain; - charset=US-ASCII; - format=flowed - - - ---Apple-Mail-12-196940926-- - ---Apple-Mail-13-196941151 -Content-Transfer-Encoding: base64 -Content-Type: application/pkcs7-signature; - name=smime.p7s -Content-Disposition: attachment; - filename=smime.p7s - -jamisSqGSIb3DQEHAqCAMIjamisxCzAJBgUrDgMCGgUAMIAGCSqGSjamisEHAQAAoIIFSjCCBUYw -ggQujamisQICBD++ukQwDQYJKojamisNAQEFBQAwMTELMAkGA1UEBhMCRjamisAKBgNVBAoTA1RE -QzEUMBIGjamisxMLVERDIE9DRVMgQ0jamisNMDQwMjI5MTE1OTAxWhcNMDYwMjamisIyOTAxWjCB -gDELMAkGA1UEjamisEsxKTAnBgNVBAoTIEjamisuIG9yZ2FuaXNhdG9yaXNrIHRpbjamisRuaW5= - ---Apple-Mail-13-196941151-- diff --git a/tracks/vendor/rails/actionmailer/test/fixtures/raw_email8 b/tracks/vendor/rails/actionmailer/test/fixtures/raw_email8 deleted file mode 100644 index 2382dfdf..00000000 --- a/tracks/vendor/rails/actionmailer/test/fixtures/raw_email8 +++ /dev/null @@ -1,47 +0,0 @@ -From xxxxxxxxx.xxxxxxx@gmail.com Sun May 8 19:07:09 2005 -Return-Path: -Message-ID: -Date: Sun, 8 May 2005 14:09:11 -0500 -From: xxxxxxxxx xxxxxxx -Reply-To: xxxxxxxxx xxxxxxx -To: xxxxx xxxx -Subject: Fwd: Signed email causes file attachments -In-Reply-To: -Mime-Version: 1.0 -Content-Type: multipart/mixed; - boundary="----=_Part_5028_7368284.1115579351471" -References: - -------=_Part_5028_7368284.1115579351471 -Content-Type: text/plain; charset=ISO-8859-1 -Content-Transfer-Encoding: quoted-printable -Content-Disposition: inline - -We should not include these files or vcards as attachments. - ----------- Forwarded message ---------- -From: xxxxx xxxxxx -Date: May 8, 2005 1:17 PM -Subject: Signed email causes file attachments -To: xxxxxxx@xxxxxxxxxx.com - - -Hi, - -Test attachments oddly encoded with japanese charset. - - -------=_Part_5028_7368284.1115579351471 -Content-Type: application/octet-stream; name*=iso-2022-jp'ja'01%20Quien%20Te%20Dij%8aat.%20Pitbull.mp3 -Content-Transfer-Encoding: base64 -Content-Disposition: attachment - -MIAGCSqGSIb3DQEHAqCAMIACAQExCzAJBgUrDgMCGgUAMIAGCSqGSIb3DQEHAQAAoIIGFDCCAs0w -ggI2oAMCAQICAw5c+TANBgkqhkiG9w0BAQQFADBiMQswCQYDVQQGEwJaQTElMCMGA1UEChMcVGhh -d3RlIENvbnN1bHRpbmcgKFB0eSkgTHRkLjEsMCoGA1UEAxMjVGhhd3RlIFBlcnNvbmFsIEZyZWVt -YWlsIElzc3VpbmcgQ0EwHhcNMDUwMzI5MDkzOTEwWhcNMDYwMzI5MDkzOTEwWjBCMR8wHQYDVQQD -ExZUaGF3dGUgRnJlZW1haWwgTWVtYmVyMR8wHQYJKoZIhvcNAQkBFhBzbWhhdW5jaEBtYWMuY29t -MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAn90dPsYS3LjfMY211OSYrDQLzwNYPlAL -7+/0XA+kdy8/rRnyEHFGwhNCDmg0B6pxC7z3xxJD/8GfCd+IYUUNUQV5m9MkxfP9pTVXZVIYLaBw -------=_Part_5028_7368284.1115579351471-- - diff --git a/tracks/vendor/rails/actionmailer/test/fixtures/raw_email9 b/tracks/vendor/rails/actionmailer/test/fixtures/raw_email9 deleted file mode 100644 index 8b9b1eaa..00000000 --- a/tracks/vendor/rails/actionmailer/test/fixtures/raw_email9 +++ /dev/null @@ -1,28 +0,0 @@ -Received: from xxx.xxx.xxx ([xxx.xxx.xxx.xxx] verified) - by xxx.com (CommuniGate Pro SMTP 4.2.8) - with SMTP id 2532598 for xxx@xxx.com; Wed, 23 Feb 2005 17:51:49 -0500 -Received-SPF: softfail - receiver=xxx.com; client-ip=xxx.xxx.xxx.xxx; envelope-from=xxx@xxx.xxx -quite Delivered-To: xxx@xxx.xxx -Received: by xxx.xxx.xxx (Wostfix, from userid xxx) - id 0F87F333; Wed, 23 Feb 2005 16:16:17 -0600 -Date: Wed, 23 Feb 2005 18:20:17 -0400 -From: "xxx xxx" -Message-ID: <4D6AA7EB.6490534@xxx.xxx> -To: xxx@xxx.com -Subject: Stop adware/spyware once and for all. -X-Scanned-By: MIMEDefang 2.11 (www dot roaringpenguin dot com slash mimedefang) - -You are infected with: -Ad Ware and Spy Ware - -Get your free scan and removal download now, -before it gets any worse. - -http://xxx.xxx.info?aid=3D13&?stat=3D4327kdzt - - - - -no more? (you will still be infected) -http://xxx.xxx.info/discon/?xxx@xxx.com diff --git a/tracks/vendor/rails/actionmailer/test/fixtures/templates/signed_up.rhtml b/tracks/vendor/rails/actionmailer/test/fixtures/templates/signed_up.rhtml deleted file mode 100644 index a85d5fa4..00000000 --- a/tracks/vendor/rails/actionmailer/test/fixtures/templates/signed_up.rhtml +++ /dev/null @@ -1,3 +0,0 @@ -Hello there, - -Mr. <%= @recipient %> \ No newline at end of file diff --git a/tracks/vendor/rails/actionmailer/test/fixtures/test_mailer/implicitly_multipart_example.text.html.rhtml b/tracks/vendor/rails/actionmailer/test/fixtures/test_mailer/implicitly_multipart_example.text.html.rhtml deleted file mode 100644 index 946d99ed..00000000 --- a/tracks/vendor/rails/actionmailer/test/fixtures/test_mailer/implicitly_multipart_example.text.html.rhtml +++ /dev/null @@ -1,10 +0,0 @@ - - - HTML formatted message to <%= @recipient %>. - - - - - HTML formatted message to <%= @recipient %>. - - diff --git a/tracks/vendor/rails/actionmailer/test/fixtures/test_mailer/implicitly_multipart_example.text.plain.rhtml b/tracks/vendor/rails/actionmailer/test/fixtures/test_mailer/implicitly_multipart_example.text.plain.rhtml deleted file mode 100644 index a6c8d54c..00000000 --- a/tracks/vendor/rails/actionmailer/test/fixtures/test_mailer/implicitly_multipart_example.text.plain.rhtml +++ /dev/null @@ -1,2 +0,0 @@ -Plain text to <%= @recipient %>. -Plain text to <%= @recipient %>. diff --git a/tracks/vendor/rails/actionmailer/test/fixtures/test_mailer/implicitly_multipart_example.text.yaml.rhtml b/tracks/vendor/rails/actionmailer/test/fixtures/test_mailer/implicitly_multipart_example.text.yaml.rhtml deleted file mode 100644 index c14348c7..00000000 --- a/tracks/vendor/rails/actionmailer/test/fixtures/test_mailer/implicitly_multipart_example.text.yaml.rhtml +++ /dev/null @@ -1 +0,0 @@ -yaml to: <%= @recipient %> \ No newline at end of file diff --git a/tracks/vendor/rails/actionmailer/test/fixtures/test_mailer/signed_up.rhtml b/tracks/vendor/rails/actionmailer/test/fixtures/test_mailer/signed_up.rhtml deleted file mode 100644 index a85d5fa4..00000000 --- a/tracks/vendor/rails/actionmailer/test/fixtures/test_mailer/signed_up.rhtml +++ /dev/null @@ -1,3 +0,0 @@ -Hello there, - -Mr. <%= @recipient %> \ No newline at end of file diff --git a/tracks/vendor/rails/actionmailer/test/mail_helper_test.rb b/tracks/vendor/rails/actionmailer/test/mail_helper_test.rb deleted file mode 100644 index bf5bf7f3..00000000 --- a/tracks/vendor/rails/actionmailer/test/mail_helper_test.rb +++ /dev/null @@ -1,97 +0,0 @@ -$:.unshift(File.dirname(__FILE__) + "/../lib/") -$:.unshift File.dirname(__FILE__) + "/fixtures/helpers" - -require 'test/unit' -require 'action_mailer' - -module MailerHelper - def person_name - "Mr. Joe Person" - end -end - -class HelperMailer < ActionMailer::Base - helper MailerHelper - helper :test - - def use_helper(recipient) - recipients recipient - subject "using helpers" - from "tester@example.com" - end - - def use_test_helper(recipient) - recipients recipient - subject "using helpers" - from "tester@example.com" - self.body = { :text => "emphasize me!" } - end - - def use_mail_helper(recipient) - recipients recipient - subject "using mailing helpers" - from "tester@example.com" - self.body = { :text => - "But soft! What light through yonder window breaks? It is the east, " + - "and Juliet is the sun. Arise, fair sun, and kill the envious moon, " + - "which is sick and pale with grief that thou, her maid, art far more " + - "fair than she. Be not her maid, for she is envious! Her vestal " + - "livery is but sick and green, and none but fools do wear it. Cast " + - "it off!" - } - end - - def use_helper_method(recipient) - recipients recipient - subject "using helpers" - from "tester@example.com" - self.body = { :text => "emphasize me!" } - end - - private - - def name_of_the_mailer_class - self.class.name - end - helper_method :name_of_the_mailer_class -end - -HelperMailer.template_root = File.dirname(__FILE__) + "/fixtures" - -class MailerHelperTest < Test::Unit::TestCase - def new_mail( charset="utf-8" ) - mail = TMail::Mail.new - mail.set_content_type "text", "plain", { "charset" => charset } if charset - mail - end - - def setup - ActionMailer::Base.delivery_method = :test - ActionMailer::Base.perform_deliveries = true - ActionMailer::Base.deliveries = [] - - @recipient = 'test@localhost' - end - - def test_use_helper - mail = HelperMailer.create_use_helper(@recipient) - assert_match %r{Mr. Joe Person}, mail.encoded - end - - def test_use_test_helper - mail = HelperMailer.create_use_test_helper(@recipient) - assert_match %r{emphasize me!}, mail.encoded - end - - def test_use_helper_method - mail = HelperMailer.create_use_helper_method(@recipient) - assert_match %r{HelperMailer}, mail.encoded - end - - def test_use_mail_helper - mail = HelperMailer.create_use_mail_helper(@recipient) - assert_match %r{ But soft!}, mail.encoded - assert_match %r{east, and\n Juliet}, mail.encoded - end -end - diff --git a/tracks/vendor/rails/actionmailer/test/mail_render_test.rb b/tracks/vendor/rails/actionmailer/test/mail_render_test.rb deleted file mode 100644 index d5819652..00000000 --- a/tracks/vendor/rails/actionmailer/test/mail_render_test.rb +++ /dev/null @@ -1,48 +0,0 @@ -$:.unshift(File.dirname(__FILE__) + "/../lib/") - -require 'test/unit' -require 'action_mailer' - -class RenderMailer < ActionMailer::Base - def inline_template(recipient) - recipients recipient - subject "using helpers" - from "tester@example.com" - body render(:inline => "Hello, <%= @world %>", :body => { :world => "Earth" }) - end - - def file_template(recipient) - recipients recipient - subject "using helpers" - from "tester@example.com" - body render(:file => "signed_up", :body => { :recipient => recipient }) - end - - def initialize_defaults(method_name) - super - mailer_name "test_mailer" - end -end - -RenderMailer.template_root = File.dirname(__FILE__) + "/fixtures" - -class RenderHelperTest < Test::Unit::TestCase - def setup - ActionMailer::Base.delivery_method = :test - ActionMailer::Base.perform_deliveries = true - ActionMailer::Base.deliveries = [] - - @recipient = 'test@localhost' - end - - def test_inline_template - mail = RenderMailer.create_inline_template(@recipient) - assert_equal "Hello, Earth", mail.body.strip - end - - def test_file_template - mail = RenderMailer.create_file_template(@recipient) - assert_equal "Hello there, \n\nMr. test@localhost", mail.body.strip - end -end - diff --git a/tracks/vendor/rails/actionmailer/test/mail_service_test.rb b/tracks/vendor/rails/actionmailer/test/mail_service_test.rb deleted file mode 100644 index c5b2cdec..00000000 --- a/tracks/vendor/rails/actionmailer/test/mail_service_test.rb +++ /dev/null @@ -1,749 +0,0 @@ -$:.unshift(File.dirname(__FILE__) + "/../lib/") - -require 'test/unit' -require 'action_mailer' - -class MockSMTP - def self.deliveries - @@deliveries - end - - def initialize - @@deliveries = [] - end - - def sendmail(mail, from, to) - @@deliveries << [mail, from, to] - end -end - -class Net::SMTP - def self.start(*args) - yield MockSMTP.new - end -end - -class TestMailer < ActionMailer::Base - - def signed_up(recipient) - @recipients = recipient - @subject = "[Signed up] Welcome #{recipient}" - @from = "system@loudthinking.com" - @sent_on = Time.local(2004, 12, 12) - @body["recipient"] = recipient - end - - def cancelled_account(recipient) - self.recipients = recipient - self.subject = "[Cancelled] Goodbye #{recipient}" - self.from = "system@loudthinking.com" - self.sent_on = Time.local(2004, 12, 12) - self.body = "Goodbye, Mr. #{recipient}" - end - - def cc_bcc(recipient) - recipients recipient - subject "testing bcc/cc" - from "system@loudthinking.com" - sent_on Time.local(2004, 12, 12) - cc "nobody@loudthinking.com" - bcc "root@loudthinking.com" - body "Nothing to see here." - end - - def iso_charset(recipient) - @recipients = recipient - @subject = "testing isø charsets" - @from = "system@loudthinking.com" - @sent_on = Time.local 2004, 12, 12 - @cc = "nobody@loudthinking.com" - @bcc = "root@loudthinking.com" - @body = "Nothing to see here." - @charset = "iso-8859-1" - end - - def unencoded_subject(recipient) - @recipients = recipient - @subject = "testing unencoded subject" - @from = "system@loudthinking.com" - @sent_on = Time.local 2004, 12, 12 - @cc = "nobody@loudthinking.com" - @bcc = "root@loudthinking.com" - @body = "Nothing to see here." - end - - def extended_headers(recipient) - @recipients = recipient - @subject = "testing extended headers" - @from = "Grytøyr " - @sent_on = Time.local 2004, 12, 12 - @cc = "Grytøyr " - @bcc = "Grytøyr " - @body = "Nothing to see here." - @charset = "iso-8859-1" - end - - def utf8_body(recipient) - @recipients = recipient - @subject = "testing utf-8 body" - @from = "Foo áëô îü " - @sent_on = Time.local 2004, 12, 12 - @cc = "Foo áëô îü " - @bcc = "Foo áëô îü " - @body = "åœö blah" - @charset = "utf-8" - end - - def multipart_with_mime_version(recipient) - recipients recipient - subject "multipart with mime_version" - from "test@example.com" - sent_on Time.local(2004, 12, 12) - mime_version "1.1" - content_type "multipart/alternative" - - part "text/plain" do |p| - p.body = "blah" - end - - part "text/html" do |p| - p.body = "blah" - end - end - - def multipart_with_utf8_subject(recipient) - recipients recipient - subject "Foo áëô îü" - from "test@example.com" - charset "utf-8" - - part "text/plain" do |p| - p.body = "blah" - end - - part "text/html" do |p| - p.body = "blah" - end - end - - def explicitly_multipart_example(recipient, ct=nil) - recipients recipient - subject "multipart example" - from "test@example.com" - sent_on Time.local(2004, 12, 12) - body "plain text default" - content_type ct if ct - - part "text/html" do |p| - p.charset = "iso-8859-1" - p.body = "blah" - end - - attachment :content_type => "image/jpeg", :filename => "foo.jpg", - :body => "123456789" - end - - def implicitly_multipart_example(recipient, cs = nil, order = nil) - @recipients = recipient - @subject = "multipart example" - @from = "test@example.com" - @sent_on = Time.local 2004, 12, 12 - @body = { "recipient" => recipient } - @charset = cs if cs - @implicit_parts_order = order if order - end - - def html_mail(recipient) - recipients recipient - subject "html mail" - from "test@example.com" - body "Emphasize this" - content_type "text/html" - end - - def html_mail_with_underscores(recipient) - subject "html mail with underscores" - body %{_Google} - end - - def custom_template(recipient) - recipients recipient - subject "[Signed up] Welcome #{recipient}" - from "system@loudthinking.com" - sent_on Time.local(2004, 12, 12) - template "signed_up" - - body["recipient"] = recipient - end - - def various_newlines(recipient) - recipients recipient - subject "various newlines" - from "test@example.com" - body "line #1\nline #2\rline #3\r\nline #4\r\r" + - "line #5\n\nline#6\r\n\r\nline #7" - end - - def various_newlines_multipart(recipient) - recipients recipient - subject "various newlines multipart" - from "test@example.com" - content_type "multipart/alternative" - part :content_type => "text/plain", :body => "line #1\nline #2\rline #3\r\nline #4\r\r" - part :content_type => "text/html", :body => "

line #1

\n

line #2

\r

line #3

\r\n

line #4

\r\r" - end - - def nested_multipart(recipient) - recipients recipient - subject "nested multipart" - from "test@example.com" - content_type "multipart/mixed" - part :content_type => "multipart/alternative", :content_disposition => "inline" do |p| - p.part :content_type => "text/plain", :body => "test text\nline #2" - p.part :content_type => "text/html", :body => "test HTML
\nline #2" - end - attachment :content_type => "application/octet-stream",:filename => "test.txt", :body => "test abcdefghijklmnopqstuvwxyz" - end - - def unnamed_attachment(recipient) - recipients recipient - subject "nested multipart" - from "test@example.com" - content_type "multipart/mixed" - part :content_type => "text/plain", :body => "hullo" - attachment :content_type => "application/octet-stream", :body => "test abcdefghijklmnopqstuvwxyz" - end - - def headers_with_nonalpha_chars(recipient) - recipients recipient - subject "nonalpha chars" - from "One: Two " - cc "Three: Four " - bcc "Five: Six " - body "testing" - end - - class < charset } - end - mail - end - - def setup - ActionMailer::Base.delivery_method = :test - ActionMailer::Base.perform_deliveries = true - ActionMailer::Base.deliveries = [] - - @recipient = 'test@localhost' - end - - def test_nested_parts - created = nil - assert_nothing_raised { created = TestMailer.create_nested_multipart(@recipient)} - assert_equal 2,created.parts.size - assert_equal 2,created.parts.first.parts.size - - assert_equal "multipart/mixed", created.content_type - assert_equal "multipart/alternative", created.parts.first.content_type - assert_equal "text/plain", created.parts.first.parts.first.content_type - assert_equal "text/html", created.parts.first.parts[1].content_type - assert_equal "application/octet-stream", created.parts[1].content_type - end - - def test_signed_up - expected = new_mail - expected.to = @recipient - expected.subject = "[Signed up] Welcome #{@recipient}" - expected.body = "Hello there, \n\nMr. #{@recipient}" - expected.from = "system@loudthinking.com" - expected.date = Time.local(2004, 12, 12) - expected.mime_version = nil - - created = nil - assert_nothing_raised { created = TestMailer.create_signed_up(@recipient) } - assert_not_nil created - assert_equal expected.encoded, created.encoded - - assert_nothing_raised { TestMailer.deliver_signed_up(@recipient) } - assert_not_nil ActionMailer::Base.deliveries.first - assert_equal expected.encoded, ActionMailer::Base.deliveries.first.encoded - end - - def test_custom_template - expected = new_mail - expected.to = @recipient - expected.subject = "[Signed up] Welcome #{@recipient}" - expected.body = "Hello there, \n\nMr. #{@recipient}" - expected.from = "system@loudthinking.com" - expected.date = Time.local(2004, 12, 12) - - created = nil - assert_nothing_raised { created = TestMailer.create_custom_template(@recipient) } - assert_not_nil created - assert_equal expected.encoded, created.encoded - end - - def test_cancelled_account - expected = new_mail - expected.to = @recipient - expected.subject = "[Cancelled] Goodbye #{@recipient}" - expected.body = "Goodbye, Mr. #{@recipient}" - expected.from = "system@loudthinking.com" - expected.date = Time.local(2004, 12, 12) - - created = nil - assert_nothing_raised { created = TestMailer.create_cancelled_account(@recipient) } - assert_not_nil created - assert_equal expected.encoded, created.encoded - - assert_nothing_raised { TestMailer.deliver_cancelled_account(@recipient) } - assert_not_nil ActionMailer::Base.deliveries.first - assert_equal expected.encoded, ActionMailer::Base.deliveries.first.encoded - end - - def test_cc_bcc - expected = new_mail - expected.to = @recipient - expected.subject = "testing bcc/cc" - expected.body = "Nothing to see here." - expected.from = "system@loudthinking.com" - expected.cc = "nobody@loudthinking.com" - expected.bcc = "root@loudthinking.com" - expected.date = Time.local 2004, 12, 12 - - created = nil - assert_nothing_raised do - created = TestMailer.create_cc_bcc @recipient - end - assert_not_nil created - assert_equal expected.encoded, created.encoded - - assert_nothing_raised do - TestMailer.deliver_cc_bcc @recipient - end - - assert_not_nil ActionMailer::Base.deliveries.first - assert_equal expected.encoded, ActionMailer::Base.deliveries.first.encoded - end - - def test_iso_charset - expected = new_mail( "iso-8859-1" ) - expected.to = @recipient - expected.subject = encode "testing isø charsets", "iso-8859-1" - expected.body = "Nothing to see here." - expected.from = "system@loudthinking.com" - expected.cc = "nobody@loudthinking.com" - expected.bcc = "root@loudthinking.com" - expected.date = Time.local 2004, 12, 12 - - created = nil - assert_nothing_raised do - created = TestMailer.create_iso_charset @recipient - end - assert_not_nil created - assert_equal expected.encoded, created.encoded - - assert_nothing_raised do - TestMailer.deliver_iso_charset @recipient - end - - assert_not_nil ActionMailer::Base.deliveries.first - assert_equal expected.encoded, ActionMailer::Base.deliveries.first.encoded - end - - def test_unencoded_subject - expected = new_mail - expected.to = @recipient - expected.subject = "testing unencoded subject" - expected.body = "Nothing to see here." - expected.from = "system@loudthinking.com" - expected.cc = "nobody@loudthinking.com" - expected.bcc = "root@loudthinking.com" - expected.date = Time.local 2004, 12, 12 - - created = nil - assert_nothing_raised do - created = TestMailer.create_unencoded_subject @recipient - end - assert_not_nil created - assert_equal expected.encoded, created.encoded - - assert_nothing_raised do - TestMailer.deliver_unencoded_subject @recipient - end - - assert_not_nil ActionMailer::Base.deliveries.first - assert_equal expected.encoded, ActionMailer::Base.deliveries.first.encoded - end - - def test_instances_are_nil - assert_nil ActionMailer::Base.new - assert_nil TestMailer.new - end - - def test_deliveries_array - assert_not_nil ActionMailer::Base.deliveries - assert_equal 0, ActionMailer::Base.deliveries.size - TestMailer.deliver_signed_up(@recipient) - assert_equal 1, ActionMailer::Base.deliveries.size - assert_not_nil ActionMailer::Base.deliveries.first - end - - def test_perform_deliveries_flag - ActionMailer::Base.perform_deliveries = false - TestMailer.deliver_signed_up(@recipient) - assert_equal 0, ActionMailer::Base.deliveries.size - ActionMailer::Base.perform_deliveries = true - TestMailer.deliver_signed_up(@recipient) - assert_equal 1, ActionMailer::Base.deliveries.size - end - - def test_unquote_quoted_printable_subject - msg = <" - - expected = new_mail "iso-8859-1" - expected.to = quote_address_if_necessary @recipient, "iso-8859-1" - expected.subject = "testing extended headers" - expected.body = "Nothing to see here." - expected.from = quote_address_if_necessary "Grytøyr ", "iso-8859-1" - expected.cc = quote_address_if_necessary "Grytøyr ", "iso-8859-1" - expected.bcc = quote_address_if_necessary "Grytøyr ", "iso-8859-1" - expected.date = Time.local 2004, 12, 12 - - created = nil - assert_nothing_raised do - created = TestMailer.create_extended_headers @recipient - end - - assert_not_nil created - assert_equal expected.encoded, created.encoded - - assert_nothing_raised do - TestMailer.deliver_extended_headers @recipient - end - - assert_not_nil ActionMailer::Base.deliveries.first - assert_equal expected.encoded, ActionMailer::Base.deliveries.first.encoded - end - - def test_utf8_body_is_not_quoted - @recipient = "Foo áëô îü " - expected = new_mail "utf-8" - expected.to = quote_address_if_necessary @recipient, "utf-8" - expected.subject = "testing utf-8 body" - expected.body = "åœö blah" - expected.from = quote_address_if_necessary @recipient, "utf-8" - expected.cc = quote_address_if_necessary @recipient, "utf-8" - expected.bcc = quote_address_if_necessary @recipient, "utf-8" - expected.date = Time.local 2004, 12, 12 - - created = TestMailer.create_utf8_body @recipient - assert_match(/åœö blah/, created.encoded) - end - - def test_multiple_utf8_recipients - @recipient = ["\"Foo áëô îü\" ", "\"Example Recipient\" "] - expected = new_mail "utf-8" - expected.to = quote_address_if_necessary @recipient, "utf-8" - expected.subject = "testing utf-8 body" - expected.body = "åœö blah" - expected.from = quote_address_if_necessary @recipient.first, "utf-8" - expected.cc = quote_address_if_necessary @recipient, "utf-8" - expected.bcc = quote_address_if_necessary @recipient, "utf-8" - expected.date = Time.local 2004, 12, 12 - - created = TestMailer.create_utf8_body @recipient - assert_match(/\nFrom: =\?utf-8\?Q\?Foo_.*?\?= \r/, created.encoded) - assert_match(/\nTo: =\?utf-8\?Q\?Foo_.*?\?= , Example Recipient _Google}, mail.body - end - - def test_various_newlines - mail = TestMailer.create_various_newlines(@recipient) - assert_equal("line #1\nline #2\nline #3\nline #4\n\n" + - "line #5\n\nline#6\n\nline #7", mail.body) - end - - def test_various_newlines_multipart - mail = TestMailer.create_various_newlines_multipart(@recipient) - assert_equal "line #1\nline #2\nline #3\nline #4\n\n", mail.parts[0].body - assert_equal "

line #1

\n

line #2

\n

line #3

\n

line #4

\n\n", mail.parts[1].body - end - - def test_headers_removed_on_smtp_delivery - ActionMailer::Base.delivery_method = :smtp - TestMailer.deliver_cc_bcc(@recipient) - assert MockSMTP.deliveries[0][2].include?("root@loudthinking.com") - assert MockSMTP.deliveries[0][2].include?("nobody@loudthinking.com") - assert MockSMTP.deliveries[0][2].include?(@recipient) - assert_match %r{^Cc: nobody@loudthinking.com}, MockSMTP.deliveries[0][0] - assert_match %r{^To: #{@recipient}}, MockSMTP.deliveries[0][0] - assert_no_match %r{^Bcc: root@loudthinking.com}, MockSMTP.deliveries[0][0] - end - - def test_recursive_multipart_processing - fixture = File.read(File.dirname(__FILE__) + "/fixtures/raw_email7") - mail = TMail::Mail.parse(fixture) - assert_equal "This is the first part.\n\nAttachment: test.pdf\n\n\nAttachment: smime.p7s\n", mail.body - end - - def test_decode_encoded_attachment_filename - fixture = File.read(File.dirname(__FILE__) + "/fixtures/raw_email8") - mail = TMail::Mail.parse(fixture) - attachment = mail.attachments.last - assert_equal "01QuienTeDijat.Pitbull.mp3", attachment.original_filename - end - - def test_wrong_mail_header - fixture = File.read(File.dirname(__FILE__) + "/fixtures/raw_email9") - assert_raise(TMail::SyntaxError) { TMail::Mail.parse(fixture) } - end - - def test_decode_message_with_unknown_charset - fixture = File.read(File.dirname(__FILE__) + "/fixtures/raw_email10") - mail = TMail::Mail.parse(fixture) - assert_nothing_raised { mail.body } - end - - def test_decode_message_with_unquoted_atchar_in_header - fixture = File.read(File.dirname(__FILE__) + "/fixtures/raw_email11") - mail = TMail::Mail.parse(fixture) - assert_not_nil mail.from - end - - def test_empty_header_values_omitted - result = TestMailer.create_unnamed_attachment(@recipient).encoded - assert_match %r{Content-Type: application/octet-stream[^;]}, result - assert_match %r{Content-Disposition: attachment[^;]}, result - end - - def test_headers_with_nonalpha_chars - mail = TestMailer.create_headers_with_nonalpha_chars(@recipient) - assert !mail.from_addrs.empty? - assert !mail.cc_addrs.empty? - assert !mail.bcc_addrs.empty? - assert_match(/:/, mail.from_addrs.to_s) - assert_match(/:/, mail.cc_addrs.to_s) - assert_match(/:/, mail.bcc_addrs.to_s) - end - - def test_deliver_with_mail_object - mail = TestMailer::create_headers_with_nonalpha_chars(@recipient) - assert_nothing_raised { TestMailer.deliver(mail) } - assert_equal 1, TestMailer.deliveries.length - end -end - diff --git a/tracks/vendor/rails/actionmailer/test/quoting_test.rb b/tracks/vendor/rails/actionmailer/test/quoting_test.rb deleted file mode 100644 index 6291cd3d..00000000 --- a/tracks/vendor/rails/actionmailer/test/quoting_test.rb +++ /dev/null @@ -1,48 +0,0 @@ -$:.unshift(File.dirname(__FILE__) + "/../lib/") -$:.unshift(File.dirname(__FILE__) + "/../lib/action_mailer/vendor") - -require 'test/unit' -require 'tmail' -require 'tempfile' - -class QuotingTest < Test::Unit::TestCase - def test_quote_multibyte_chars - original = "\303\246 \303\270 and \303\245" - - result = execute_in_sandbox(<<-CODE) - $:.unshift(File.dirname(__FILE__) + "/../lib/") - $KCODE = 'u' - require 'jcode' - require 'action_mailer/quoting' - include ActionMailer::Quoting - quoted_printable(#{original.inspect}, "UTF-8") - CODE - - unquoted = TMail::Unquoter.unquote_and_convert_to(result, nil) - assert_equal unquoted, original - end - - private - - # This whole thing *could* be much simpler, but I don't think Tempfile, - # popen and others exist on all platforms (like Windows). - def execute_in_sandbox(code) - test_name = "#{File.dirname(__FILE__)}/am-quoting-test.#{$$}.rb" - res_name = "#{File.dirname(__FILE__)}/am-quoting-test.#{$$}.out" - - File.open(test_name, "w+") do |file| - file.write(<<-CODE) - block = Proc.new do - #{code} - end - puts block.call - CODE - end - - system("ruby #{test_name} > #{res_name}") or raise "could not run test in sandbox" - File.read(res_name) - ensure - File.delete(test_name) rescue nil - File.delete(res_name) rescue nil - end -end diff --git a/tracks/vendor/rails/actionmailer/test/tmail_test.rb b/tracks/vendor/rails/actionmailer/test/tmail_test.rb deleted file mode 100644 index 3930c7d3..00000000 --- a/tracks/vendor/rails/actionmailer/test/tmail_test.rb +++ /dev/null @@ -1,17 +0,0 @@ -$:.unshift(File.dirname(__FILE__) + "/../lib/") -$:.unshift File.dirname(__FILE__) + "/fixtures/helpers" - -require 'test/unit' -require 'action_mailer' - -class TMailMailTest < Test::Unit::TestCase - def test_body - m = TMail::Mail.new - expected = 'something_with_underscores' - m.encoding = 'quoted-printable' - quoted_body = [expected].pack('*M') - m.body = quoted_body - assert_equal "something_with_underscores=\n", m.quoted_body - assert_equal expected, m.body - end -end diff --git a/tracks/vendor/rails/actionpack/CHANGELOG b/tracks/vendor/rails/actionpack/CHANGELOG deleted file mode 100644 index 9453a59f..00000000 --- a/tracks/vendor/rails/actionpack/CHANGELOG +++ /dev/null @@ -1,2120 +0,0 @@ -*1.1.2* (December 13th, 2005) - -* Update to script.aculo.us 1.5.0 final (equals 1.5.0_rc6) [Thomas Fuchs] - -* Update to Prototype 1.4.0 final [Sam Stephenson] - -* Become part of Rails 1.0 - - -*1.11.1* (December 7th, 2005) - -* More robust relative url root discovery for SCGI compatibility. This solves the 'SCGI routes problem' -- you no longer need to prefix all your routes with the name of the SCGI mountpoint. #3070 [Dave Ringoen] - -* Fix docs for text_area_tag. #3083. [Christopher Cotton] - -* Make ActionController's render honor the :locals option when rendering a :file. #1665. [Emanuel Borsboom, Marcel Molina Jr.] - -* Don't put flash in session if sessions are disabled. [Jeremy Kemper] - -* Strip out trailing &_= for raw post bodies. Closes #2868. [Sam Stephenson] - -* Correct docs for automatic layout assignment. #2610. [Charles M. Gerungan] - -* Always create new AR sessions rather than trying too hard to avoid database traffic. #2731 [Jeremy Kemper] - -* Update to Prototype 1.4.0_rc4. Closes #2943 (old Array.prototype.reverse behavior can be obtained by passing false as an argument). [Sam Stephenson] - -* Update to Prototype 1.4.0_rc3. Closes #1893, #2505, #2550, #2748, #2783. [Sam Stephenson] - -* Updated docs for in_place_editor, fixes a couple bugs and offers extended support for external controls [Justin Palmer] - -* Rename Version constant to VERSION. #2802 [Marcel Molina Jr.] - -* Remove the unused, slow response_dump and session_dump variables from error pages. #1222 [lmarlow@yahoo.com] - -* Update to latest script.aculo.us version (as of [3031]) - -* Update documentation for render :file. #2858 [Tom Werner] - -* Only include builtin filters whose filenames match /^[a-z][a-z_]*_helper.rb$/ to avoid including operating system metadata such as ._foo_helper.rb. #2855 [court3nay@gmail.com] - -* options_for_select allows any objects which respond_to? :first and :last rather than restricting to Array and Range. #2824 [Jacob Robbins , Jeremy Kemper] - -* The auto_link text helper accepts an optional block to format the link text for each url and email address. Example: auto_link(post.body) { |text| truncate(text, 10) } [Jeremy Kemper] - -* assert_tag uses exact matches for string conditions, instead of partial matches. Use regex to do partial matches. #2799 [Jamis Buck] - -* CGI::Session::ActiveRecordStore.data_column_name = 'foobar' to use a different session data column than the 'data' default. [nbpwie102@sneakemail.com] - -* Do not raise an exception when default helper is missing; log a debug message instead. It's nice to delete empty helpers. [Jeremy Kemper] - -* Controllers with acronyms in their names (e.g. PDFController) require the correct default helper (PDFHelper in file pdf_helper.rb). #2262 [jeff@opendbms.com] - - -*1.11.0* (November 7th, 2005) - -* Added request as instance method to views, so you can do <%= request.env["HTTP_REFERER"] %>, just like you can already access response, session, and the likes [DHH] - -* Fix conflict with assert_tag and Glue gem #2255 [david.felstead@gmail.com] - -* Add documentation to assert_tag indicating that it only works with well-formed XHTML #1937, #2570 [Jamis Buck] - -* Added action_pack.rb stub so that ActionPack::Version loads properly [Sam Stephenson] - -* Added short-hand to assert_tag so assert_tag :tag => "span" can be written as assert_tag "span" [DHH] - -* Added skip_before_filter/skip_after_filter for easier control of the filter chain in inheritance hierachies [DHH]. Example: - - class ApplicationController < ActionController::Base - before_filter :authenticate - end - - class WeblogController < ApplicationController - # will run the :authenticate filter - end - - class SignupController < ActionController::Base - # will not run the :authenticate filter - skip_before_filter :authenticate - end - -* Added redirect_to :back as a short-hand for redirect_to(request.env["HTTP_REFERER"]) [DHH] - -* Change javascript_include_tag :defaults to not use script.aculo.us loader, which facilitates the use of plugins for future script.aculo.us and third party javascript extensions, and provide register_javascript_include_default for plugins to specify additional JavaScript files to load. Removed slider.js and builder.js from actionpack. [Thomas Fuchs] - -* Fix problem where redirecting components can cause an infinite loop [Rick Olson] - -* Added support for the queue option on visual_effect [Thomas Fuchs] - -* Update script.aculo.us to V1.5_rc4 [Thomas Fuchs] - -* Fix that render :text didn't interpolate instance variables #2629, #2626 [skaes] - -* Fix line number detection and escape RAILS_ROOT in backtrace Regexp [Nicholas Seckar] - -* Fixed document.getElementsByClassName from Prototype to be speedy again [Sam Stephenson] - -* Recognize ./#{RAILS_ROOT} as RAILS_ROOT in error traces [Nicholas Seckar] - -* Remove ARStore session fingerprinting [Nicholas Seckar] - -* Fix obscure bug in ARStore [Nicholas Seckar] - -* Added TextHelper#strip_tags for removing HTML tags from a string (using HTMLTokenizer) #2229 [marcin@junkheap.net] - -* Added a reader for flash.now, so it's possible to do stuff like flash.now[:alert] ||= 'New if not set' #2422 [Caio Chassot] - - -*1.10.2* (October 26th, 2005) - -* Reset template variables after using render_to_string [skaes@web.de] - -* Expose the session model backing CGI::Session - -* Abbreviate RAILS_ROOT in traces - - -*1.10.1* (October 19th, 2005) - -* Update error trace templates [Nicholas Seckar] - -* Stop showing generated routing code in application traces [Nicholas Seckar] - - -*1.10.0* (October 16th, 2005) - -* Make string-keys locals assigns optional. Add documentation describing depreciated state [skaes@web.de] - -* Improve line number detection for template errors [Nicholas Seckar] - -* Update/clean up documentation (rdoc) - -* Upgrade to Prototype 1.4.0_rc0 [Sam Stephenson] - -* Added assert_vaild. Reports the proper AR error messages as fail message when the passed record is invalid [Tobias Luetke] - -* Add temporary support for passing locals to render using string keys [Nicholas Seckar] - -* Clean up error pages by providing better backtraces [Nicholas Seckar] - -* Raise an exception if an attempt is made to insert more session data into the ActiveRecordStore data column than the column can hold. #2234. [justin@textdrive.com] - -* Removed references to assertions.rb from actionpack assert's backtraces. Makes error reports in functional unit tests much less noisy. [Tobias Luetke] - -* Updated and clarified documentation for JavaScriptHelper to be more concise about the various options for including the JavaScript libs. [Thomas Fuchs] - -* Hide "Retry with Breakpoint" button on error pages until feature is functional. [DHH] - -* Fix Request#host_with_port to use the standard port when Rails is behind a proxy. [Nicholas Seckar] - -* Escape query strings in the href attribute of URLs created by url_helper. #2333 [Michael Schuerig ] - -* Improved line number reporting for template errors [Nicholas Seckar] - -* Added :locals support for render :inline #2463 [mdabney@cavoksolutions.com] - -* Unset the X-Requested-With header when using the xhr wrapper in functional tests so that future requests aren't accidentally xhr'ed #2352 [me@julik.nl, Sam Stephenson] - -* Unescape paths before writing cache to file system. #1877. [Damien Pollet] - -* Wrap javascript_tag contents in a CDATA section and add a cdata_section method to TagHelper #1691 [Michael Schuerig, Sam Stephenson] - -* Misc doc fixes (typos/grammar/etc). #2445. [coffee2code] - -* Speed improvement for session_options. #2287. [skaes@web.de] - -* Make cacheing binary files friendly with Windows. #1975. [Rich Olson] - -* Convert boolean form options form the tag_helper. #809. [Michael Schuerig ] - -* Fixed that an instance variable with the same name as a partial should be implicitly passed as the partial :object #2269 [court3nay] - -* Update Prototype to V1.4.0_pre11, script.aculo.us to [2502] [Thomas Fuchs] - -* Make assert_tag :children count appropriately. Closes #2181. [jamie@bravenet.com] - -* Forced newer versions of RedCloth to use hard breaks [DHH] - -* Added new scriptaculous options for auto_complete_field #2343 [m.stienstra@fngtps.com] - -* Don't prepend the asset host if the string is already a fully-qualified URL - -* Updated to script.aculo.us V1.5.0_rc2 and Prototype to V1.4.0_pre7 [Thomas Fuchs] - -* Undo condition change made in [2345] to prevent normal parameters arriving as StringIO. - -* Tolerate consecutive delimiters in query parameters. #2295 [darashi@gmail.com] - -* Streamline render process, code cleaning. Closes #2294. [skae] - -* Keep flash after components are rendered. #2291 [Rick Olson, Scott] - -* Shorten IE file upload path to filename only to match other browsers. #1507 [court3nay@gmail.com] - -* Fix open/save dialog in IE not opening files send with send_file/send_data, #2279 [Thomas Fuchs] - -* Fixed that auto_discovery_link_tag couldn't take a string as the URL [DHH] - -* Fixed problem with send_file and WEBrick using stdout #1812 [DHH] - -* Optimized tag_options to not sort keys, which is no longer necessary when assert_dom_equal and friend is available #1995 [skae] - -* Added assert_dom_equal and assert_dom_not_equal to compare tags generated by the helpers in an order-indifferent manner #1995 [skae] - -* Fixed that Request#domain caused an exception if the domain header wasn't set in the original http request #1795 [Michael Koziarski] - -* Make the truncate() helper multi-byte safe (assuming $KCODE has been set to something other than "NONE") #2103 - -* Add routing tests from #1945 [ben@groovie.org] - -* Add a routing test case covering #2101 [Nicholas Seckar] - -* Cache relative_url_root for all webservers, not just Apache #2193 [skae] - -* Speed up cookie use by decreasing string copying #2194 [skae] - -* Fixed access to "Host" header with requests made by crappy old HTTP/1.0 clients #2124 [Marcel Molina] - -* Added easy assignment of fragment cache store through use of symbols for included stores (old way still works too) - - Before: - ActionController::Base.fragment_cache_store = - ActionController::Base::Caching::Fragments::FileStore.new("/path/to/cache/directory") - - After: - ActionController::Base.fragment_cache_store = :file_store, "/path/to/cache/directory" - -* Added ActionController::Base.session_store=, session_store, and session_options to make it easier to tweak the session options (instead of going straight to ActionController::CgiRequest::DEFAULT_SESSION_OPTIONS) - -* Added TextHelper#cycle to cycle over an array of values on each hit (useful for alternating row colors etc) #2154 [dave-ml@dribin.org] - -* Ensure that request.path never returns nil. Closes #1675 [Nicholas Seckar] - -* Add ability to specify Route Regexps for controllers. Closes #1917. [Sebastian Kanthak] - -* Provide Named Route's hash methods as helper methods. Closes #1744. [Nicholas Seckar, Steve Purcell] - -* Added :multipart option to ActiveRecordHelper#form to make it possible to add file input fields #2034 [jstirk@oobleyboo.com] - -* Moved auto-completion and in-place editing into the Macros module and their helper counterparts into JavaScriptMacrosHelper - -* Added in-place editing support in the spirit of auto complete with ActionController::Base.in_place_edit_for, JavascriptHelper#in_place_editor_field, and Javascript support from script.aculo.us #2038 [Jon Tirsen] - -* Added :disabled option to all data selects that'll make the elements inaccessible for change #2167, #253 [eigentone] - -* Fixed that TextHelper#auto_link_urls would include punctuation in the links #2166, #1671 [eigentone] - -* Fixed that number_to_currency(1000, {:precision => 0})) should return "$1,000", instead of "$1,000." #2122 [sd@notso.net] - -* Allow link_to_remote to use any DOM-element as the parent of the form elements to be submitted #2137 [erik@ruby-lang.nl]. Example: - - - - - <%= link_to_remote 'Save', :update => "row023", - :submit => "row023", :url => {:action => 'save_row'} %> - - -* Fixed that render :partial would fail when :object was a Hash (due to backwards compatibility issues) #2148 [Sam Stephenson] - -* Fixed JavascriptHelper#auto_complete_for to only include unique items #2153 [Thomas Fuchs] - -* Fixed all AssetHelper methods to work with relative paths, such that javascript_include_tag('stdlib/standard') will look in /javascripts/stdlib/standard instead of '/stdlib/standard/' #1963 - -* Avoid extending view instance with helper modules each request. Closes #1979 - -* Performance improvements to CGI methods. Closes #1980 [Skaes] - -* Added :post option to UrlHelper#link_to that makes it possible to do POST requests through normal ahref links using Javascript - -* Fixed overwrite_params - -* Added ActionController::Base.benchmark and ActionController::Base.silence to allow for easy benchmarking and turning off the log - -* Updated vendor copy of html-scanner to support better xml parsing - -* Added :popup option to UrlHelper#link_to #1996 [gabriel.gironda@gmail.com]. Examples: - - link_to "Help", { :action => "help" }, :popup => true - link_to "Busy loop", { :action => "busy" }, :popup => ['new_window', 'height=300,width=600'] - -* Drop trailing \000 if present on RAW_POST_DATA (works around bug in Safari Ajax implementation) #918 - -* Fix observe_field to fall back to event-based observation if frequency <= 0 #1916 [michael@schubert.cx] - -* Allow use of the :with option for submit_to_remote #1936 [jon@instance-design.co.uk] - -* AbstractRequest#domain returns nil when host is an ip address #2012 [kevin.clark@gmail.com] - -* ActionController documentation update #2051 [fbeausoleil@ftml.net] - -* Yield @content_for_ variables to templates #2058 [Sam Stephenson] - -* Make rendering an empty partial collection behave like :nothing => true #2080 [Sam Stephenson] - -* Add option to specify the singular name used by pagination. - -* Use string key to obtain action value. Allows indifferent hashes to be disabled. - -* Added ActionView::Base.cache_template_loading back. - -* Rewrote compiled templates to decrease code complexity. Removed template load caching in favour of compiled caching. Fixed template error messages. [Nicholas Seckar] - -* Fix Routing to handle :some_param => nil better. [Nicholas Seckar, Luminas] - -* Add support for :include with pagination (subject to existing constraints for :include with :limit and :offset) #1478 [michael@schubert.cx] - -* Prevent the benchmark module from blowing up if a non-HTTP/1.1 request is processed - -* Added :use_short_month option to select_month helper to show month names as abbreviations - -* Make link_to escape the javascript in the confirm option #1964 [nicolas.pouillard@gmail.com] - -* Make assert_redirected_to properly check URL's passed as strings #1910 [Scott Barron] - -* Make sure :layout => false is always used when rendering inside a layout - -* Use raise instead of assert_not_nil in Test::Unit::TestCase#process to ensure that the test variables (controller, request, response) have been set - -* Make sure assigns are built for every request when testing #1866 - -* Allow remote_addr to be queried on TestRequest #1668 - -* Fixed bug when a partial render was passing a local with the same name as the partial - -* Improved performance of test app req/sec with ~10% refactoring the render method #1823 [Stefan Kaes] - -* Improved performance of test app req/sec with 5-30% through a series of Action Pack optimizations #1811 [Stefan Kaes] - -* Changed caching/expiration/hit to report using the DEBUG log level and errors to use the ERROR log level instead of both using INFO - -* Added support for per-action session management #1763 - -* Improved rendering speed on complicated templates by up to 100% (the more complex the templates, the higher the speedup) #1234 [Stephan Kaes]. This did necessasitate a change to the internals of ActionView#render_template that now has four parameters. Developers of custom view handlers (like Amrita) need to update for that. - -* Added options hash as third argument to FormHelper#input, so you can do input('person', 'zip', :size=>10) #1719 [jeremye@bsa.ca.gov] - -* Added Base#expires_in(seconds)/Base#expires_now to control HTTP content cache headers #1755 [Thomas Fuchs] - -* Fixed line number reporting for Builder template errors #1753 [piotr] - -* Fixed assert_routing so that testing controllers in modules works as expected [Nicholas Seckar, Rick Olson] - -* Fixed bug with :success/:failure callbacks for the JavaScriptHelper methods #1730 [court3nay/Thomas Fuchs] - -* Added named_route method to RouteSet instances so that RouteSet instance methods do not prevent certain names from being used. [Nicholas Seckar] - -* Fixed routes so that routes which do not specify :action in the path or in the requirements have a default of :action => 'index', In addition, fixed url generation so that :action => 'index' does not need to be provided for such urls. [Nicholas Seckar, Markjuh] - -* Worked around a Safari bug where it wouldn't pass headers through if the response was zero length by having render :nothing return ' ' instead of '' - -* Fixed Request#subdomains to handle "foo.foo.com" correctly - - -*1.9.1* (11 July, 2005) - -* Fixed that auto_complete_for didn't force the input string to lower case even as the db comparison was - -* Fixed that Action View should always use the included Builder, never attempt to require the gem, to ensure compatibility - -* Added that nil options are not included in tags, so tag("p", :ignore => nil) now returns

not

but that tag("p", :ignore => "") still includes it #1465 [michael@schuerig.de] - -* Fixed that UrlHelper#link_to_unless/link_to_if used html_escape on the name if no link was to be applied. This is unnecessary and breaks its use with images #1649 [joergd@pobox.com] - -* Improved error message for DoubleRenderError - -* Fixed routing to allow for testing of *path components #1650 [Nicholas Seckar] - -* Added :handle as an option to sortable_element to restrict the drag handle to a given class #1642 [thejohnny] - -* Added a bunch of script.aculo.us features #1644, #1677, #1695 [Thomas Fuchs] - * Effect.ScrollTo, to smoothly scroll the page to an element - * Better Firefox flickering handling on SlideUp/SlideDown - * Removed a possible memory leak in IE with draggables - * Added support for cancelling dragging my hitting ESC - * Added capability to remove draggables/droppables and redeclare sortables in dragdrop.js (this makes it possible to call sortable_element on the same element more than once, e.g. in AJAX returns that modify the sortable element. all current sortable 'stuff' on the element will be discarded and the sortable will be rebuilt) - * Always reset background color on Effect.Highlight; this make change backwards-compatibility, to be sure include style="background-color:(target-color)" on your elements or else elements will fall back to their CSS rules (which is a good thing in most circumstances) - * Removed circular references from element to prevent memory leaks (still not completely gone in IE) - * Changes to class extension in effects.js - * Make Effect.Highlight restore any previously set background color when finishing (makes effect work with CSS classes that set a background color) - * Fixed myriads of memory leaks in IE and Gecko-based browsers [David Zülke] - * Added incremental and local autocompleting and loads of documentation to controls.js [Ivan Krstic] - * Extended the auto_complete_field helper to accept tokens option - * Changed object extension mechanism to favor Object.extend to make script.aculo.us easily adaptable to support 3rd party libs like IE7.js [David Zülke] - -* Fixed that named routes didn't use the default values for action and possible other parameters #1534 [Nicholas Seckar] - -* Fixed JavascriptHelper#visual_effect to use camelize such that :blind_up will work #1639 [pelletierm@eastmedia.net] - -* Fixed that a SessionRestoreError was thrown if a model object was placed in the session that wasn't available to all controllers. This means that it's no longer necessary to use the 'model :post' work-around in ApplicationController to have a Post model in your session. - - -*1.9.0* (6 July, 2005) - -* Added logging of the request URI in the benchmark statement (makes it easy to grep for slow actions) - -* Added javascript_include_tag :defaults shortcut that'll include all the default javascripts included with Action Pack (prototype, effects, controls, dragdrop) - -* Cache several controller variables that are expensive to calculate #1229 [skaes@web.de] - -* The session class backing CGI::Session::ActiveRecordStore may be replaced with any class that duck-types with a subset of Active Record. See docs for details #1238 [skaes@web.de] - -* Fixed that hashes was not working properly when passed by GET to lighttpd #849 [Nicholas Seckar] - -* Fixed assert_template nil will be true when no template was rendered #1565 [maceywj@telus.net] - -* Added :prompt option to FormOptions#select (and the users of it, like FormOptions#select_country etc) to create "Please select" style descriptors #1181 [Michael Schuerig] - -* Added JavascriptHelper#update_element_function, which returns a Javascript function (or expression) that'll update a DOM element according to the options passed #933 [mortonda@dgrmm.net]. Examples: - - <%= update_element_function("products", :action => :insert, :position => :bottom, :content => "

New product!

") %> - - <% update_element_function("products", :action => :replace, :binding => binding) do %> -

Product 1

-

Product 2

- <% end %> - -* Added :field_name option to DateHelper#select_(year|month|day) to deviate from the year/month/day defaults #1266 [Marcel Molina] - -* Added JavascriptHelper#draggable_element and JavascriptHelper#drop_receiving_element to facilitate easy dragging and dropping through the script.aculo.us libraries #1578 [Thomas Fuchs] - -* Added that UrlHelper#mail_to will now also encode the default link title #749 [f.svehla@gmail.com] - -* Removed the default option of wrap=virtual on FormHelper#text_area to ensure XHTML compatibility #1300 [thomas@columbus.rr.com] - -* Adds the ability to include XML CDATA tags using Builder #1563 [Josh Knowles]. Example: - - xml.cdata! "some text" # => - -* Added evaluation of - # - # javascript_include_tag "common.javascript", "/elsewhere/cools" # => - # - # - # - # javascript_include_tag :defaults # => - # - # - # ... - # *see below - # - # If there's an application.js file in your public/javascripts directory, - # javascript_include_tag :defaults will automatically include it. This file - # facilitates the inclusion of small snippets of JavaScript code, along the lines of - # controllers/application.rb and helpers/application_helper.rb. - def javascript_include_tag(*sources) - options = sources.last.is_a?(Hash) ? sources.pop.stringify_keys : { } - if sources.first == :defaults - sources = @@javascript_default_sources.dup - if defined?(RAILS_ROOT) and File.exists?("#{RAILS_ROOT}/public/javascripts/application.js") - sources << 'application' - end - end - sources.collect { |source| - source = javascript_path(source) - content_tag("script", "", { "type" => "text/javascript", "src" => source }.merge(options)) - }.join("\n") - end - - # Register one or more additional JavaScript files to be included when - # - # javascript_include_tag :defaults - # - # is called. This method is intended to be called only from plugin initialization - # to register extra .js files the plugin installed in public/javascripts. - def self.register_javascript_include_default(*sources) - @@javascript_default_sources.concat(sources) - end - - def self.reset_javascript_include_default #:nodoc: - @@javascript_default_sources = JAVASCRIPT_DEFAULT_SOURCES.dup - end - - # Returns path to a stylesheet asset. Example: - # - # stylesheet_path "style" # => /stylesheets/style.css - def stylesheet_path(source) - compute_public_path(source, 'stylesheets', 'css') - end - - # Returns a css link tag per source given as argument. Examples: - # - # stylesheet_link_tag "style" # => - # - # - # stylesheet_link_tag "style", :media => "all" # => - # - # - # stylesheet_link_tag "random.styles", "/css/stylish" # => - # - # - def stylesheet_link_tag(*sources) - options = sources.last.is_a?(Hash) ? sources.pop.stringify_keys : { } - sources.collect { |source| - source = stylesheet_path(source) - tag("link", { "rel" => "Stylesheet", "type" => "text/css", "media" => "screen", "href" => source }.merge(options)) - }.join("\n") - end - - # Returns path to an image asset. Example: - # - # The +src+ can be supplied as a... - # * full path, like "/my_images/image.gif" - # * file name, like "rss.gif", that gets expanded to "/images/rss.gif" - # * file name without extension, like "logo", that gets expanded to "/images/logo.png" - def image_path(source) - compute_public_path(source, 'images', 'png') - end - - # Returns an image tag converting the +options+ into html options on the tag, but with these special cases: - # - # * :alt - If no alt text is given, the file name part of the +src+ is used (capitalized and without the extension) - # * :size - Supplied as "XxY", so "30x45" becomes width="30" and height="45" - # - # The +src+ can be supplied as a... - # * full path, like "/my_images/image.gif" - # * file name, like "rss.gif", that gets expanded to "/images/rss.gif" - # * file name without extension, like "logo", that gets expanded to "/images/logo.png" - def image_tag(source, options = {}) - options.symbolize_keys - - options[:src] = image_path(source) - options[:alt] ||= File.basename(options[:src], '.*').split('.').first.capitalize - - if options[:size] - options[:width], options[:height] = options[:size].split("x") - options.delete :size - end - - tag("img", options) - end - - private - def compute_public_path(source, dir, ext) - source = "/#{dir}/#{source}" unless source.first == "/" || source.include?(":") - source = "#{source}.#{ext}" unless source.include?(".") - source = "#{@controller.request.relative_url_root}#{source}" unless %r{^[-a-z]+://} =~ source - source = ActionController::Base.asset_host + source unless source.include?(":") - source - end - end - end -end diff --git a/tracks/vendor/rails/actionpack/lib/action_view/helpers/benchmark_helper.rb b/tracks/vendor/rails/actionpack/lib/action_view/helpers/benchmark_helper.rb deleted file mode 100644 index 1d53be51..00000000 --- a/tracks/vendor/rails/actionpack/lib/action_view/helpers/benchmark_helper.rb +++ /dev/null @@ -1,24 +0,0 @@ -require 'benchmark' - -module ActionView - module Helpers - module BenchmarkHelper - # Measures the execution time of a block in a template and reports the result to the log. Example: - # - # <% benchmark "Notes section" do %> - # <%= expensive_notes_operation %> - # <% end %> - # - # Will add something like "Notes section (0.34523)" to the log. - # - # You may give an optional logger level as the second argument - # (:debug, :info, :warn, :error). The default is :info. - def benchmark(message = "Benchmarking", level = :info) - if @logger - real = Benchmark.realtime { yield } - @logger.send level, "#{message} (#{'%.5f' % real})" - end - end - end - end -end diff --git a/tracks/vendor/rails/actionpack/lib/action_view/helpers/cache_helper.rb b/tracks/vendor/rails/actionpack/lib/action_view/helpers/cache_helper.rb deleted file mode 100644 index de2707ac..00000000 --- a/tracks/vendor/rails/actionpack/lib/action_view/helpers/cache_helper.rb +++ /dev/null @@ -1,10 +0,0 @@ -module ActionView - module Helpers - # See ActionController::Caching::Fragments for usage instructions. - module CacheHelper - def cache(name = {}, &block) - @controller.cache_erb_fragment(block, name) - end - end - end -end diff --git a/tracks/vendor/rails/actionpack/lib/action_view/helpers/capture_helper.rb b/tracks/vendor/rails/actionpack/lib/action_view/helpers/capture_helper.rb deleted file mode 100644 index 5c1f32a9..00000000 --- a/tracks/vendor/rails/actionpack/lib/action_view/helpers/capture_helper.rb +++ /dev/null @@ -1,89 +0,0 @@ -module ActionView - module Helpers - # Capture lets you extract parts of code into instance variables which - # can be used in other points of the template or even layout file. - # - # == Capturing a block into an instance variable - # - # <% @script = capture do %> - # [some html...] - # <% end %> - # - # - # == Add javascript to header using content_for - # - # content_for("name") is a wrapper for capture which will store the - # fragment in a instance variable similar to @content_for_layout. - # - # layout.rhtml: - # - # - # - # layout with js - # - # - # - # <%= @content_for_layout %> - # - # - # - # view.rhtml - # - # This page shows an alert box! - # - # <% content_for("script") do %> - # alert('hello world') - # <% end %> - # - # Normal view text - module CaptureHelper - # Capture allows you to extract a part of the template into an - # instance variable. You can use this instance variable anywhere - # in your templates and even in your layout. - # - # Example: - # - # <% @greeting = capture do %> - # Welcome To my shiny new web page! - # <% end %> - def capture(*args, &block) - # execute the block - buffer = eval("_erbout", block.binding) - pos = buffer.length - block.call(*args) - - # extract the block - data = buffer[pos..-1] - - # replace it in the original with empty string - buffer[pos..-1] = '' - - data - end - - # Content_for will store the given block - # in an instance variable for later use in another template - # or in the layout. - # - # The name of the instance variable is content_for_ - # to stay consistent with @content_for_layout which is used - # by ActionView's layouts - # - # Example: - # - # <% content_for("header") do %> - # alert('hello world') - # <% end %> - # - # You can use @content_for_header anywhere in your templates. - # - # NOTE: Beware that content_for is ignored in caches. So you shouldn't use it - # for elements that are going to be fragment cached. - def content_for(name, &block) - eval "@content_for_#{name} = (@content_for_#{name} || '') + capture(&block)" - end - end - end -end diff --git a/tracks/vendor/rails/actionpack/lib/action_view/helpers/date_helper.rb b/tracks/vendor/rails/actionpack/lib/action_view/helpers/date_helper.rb deleted file mode 100644 index ba1834b5..00000000 --- a/tracks/vendor/rails/actionpack/lib/action_view/helpers/date_helper.rb +++ /dev/null @@ -1,297 +0,0 @@ -require "date" - -module ActionView - module Helpers - # The Date Helper primarily creates select/option tags for different kinds of dates and date elements. All of the select-type methods - # share a number of common options that are as follows: - # - # * :prefix - overwrites the default prefix of "date" used for the select names. So specifying "birthday" would give - # birthday[month] instead of date[month] if passed to the select_month method. - # * :include_blank - set to true if it should be possible to set an empty date. - # * :discard_type - set to true if you want to discard the type part of the select name. If set to true, the select_month - # method would use simply "date" (which can be overwritten using :prefix) instead of "date[month]". - module DateHelper - DEFAULT_PREFIX = 'date' unless const_defined?('DEFAULT_PREFIX') - - # Reports the approximate distance in time between two Time objects or integers. - # For example, if the distance is 47 minutes, it'll return - # "about 1 hour". See the source for the complete wording list. - # - # Integers are interpreted as seconds. So, - # distance_of_time_in_words(50) returns "less than a minute". - # - # Set include_seconds to true if you want more detailed approximations if distance < 1 minute - def distance_of_time_in_words(from_time, to_time = 0, include_seconds = false) - from_time = from_time.to_time if from_time.respond_to?(:to_time) - to_time = to_time.to_time if to_time.respond_to?(:to_time) - distance_in_minutes = (((to_time - from_time).abs)/60).round - distance_in_seconds = ((to_time - from_time).abs).round - - case distance_in_minutes - when 0..1 - return (distance_in_minutes==0) ? 'less than a minute' : '1 minute' unless include_seconds - case distance_in_seconds - when 0..5 then 'less than 5 seconds' - when 6..10 then 'less than 10 seconds' - when 11..20 then 'less than 20 seconds' - when 21..40 then 'half a minute' - when 41..59 then 'less than a minute' - else '1 minute' - end - - when 2..45 then "#{distance_in_minutes} minutes" - when 46..90 then 'about 1 hour' - when 90..1440 then "about #{(distance_in_minutes.to_f / 60.0).round} hours" - when 1441..2880 then '1 day' - else "#{(distance_in_minutes / 1440).round} days" - end - end - - # Like distance_of_time_in_words, but where to_time is fixed to Time.now. - def time_ago_in_words(from_time, include_seconds = false) - distance_of_time_in_words(from_time, Time.now, include_seconds) - end - - alias_method :distance_of_time_in_words_to_now, :time_ago_in_words - - # Returns a set of select tags (one for year, month, and day) pre-selected for accessing a specified date-based attribute (identified by - # +method+) on an object assigned to the template (identified by +object+). It's possible to tailor the selects through the +options+ hash, - # which accepts all the keys that each of the individual select builders do (like :use_month_numbers for select_month) as well as a range of - # discard options. The discard options are :discard_year, :discard_month and :discard_day. Set to true, they'll - # drop the respective select. Discarding the month select will also automatically discard the day select. It's also possible to explicitly - # set the order of the tags using the :order option with an array of symbols :year, :month and :day in - # the desired order. Symbols may be omitted and the respective select is not included. - # - # Passing :disabled => true as part of the +options+ will make elements inaccessible for change. - # - # NOTE: Discarded selects will default to 1. So if no month select is available, January will be assumed. - # - # Examples: - # - # date_select("post", "written_on") - # date_select("post", "written_on", :start_year => 1995) - # date_select("post", "written_on", :start_year => 1995, :use_month_numbers => true, - # :discard_day => true, :include_blank => true) - # date_select("post", "written_on", :order => [:day, :month, :year]) - # date_select("user", "birthday", :order => [:month, :day]) - # - # The selects are prepared for multi-parameter assignment to an Active Record object. - def date_select(object, method, options = {}) - InstanceTag.new(object, method, self).to_date_select_tag(options) - end - - # Returns a set of select tags (one for year, month, day, hour, and minute) pre-selected for accessing a specified datetime-based - # attribute (identified by +method+) on an object assigned to the template (identified by +object+). Examples: - # - # datetime_select("post", "written_on") - # datetime_select("post", "written_on", :start_year => 1995) - # - # The selects are prepared for multi-parameter assignment to an Active Record object. - def datetime_select(object, method, options = {}) - InstanceTag.new(object, method, self).to_datetime_select_tag(options) - end - - # Returns a set of html select-tags (one for year, month, and day) pre-selected with the +date+. - def select_date(date = Date.today, options = {}) - select_year(date, options) + select_month(date, options) + select_day(date, options) - end - - # Returns a set of html select-tags (one for year, month, day, hour, and minute) pre-selected with the +datetime+. - def select_datetime(datetime = Time.now, options = {}) - select_year(datetime, options) + select_month(datetime, options) + select_day(datetime, options) + - select_hour(datetime, options) + select_minute(datetime, options) - end - - # Returns a set of html select-tags (one for hour and minute) - def select_time(datetime = Time.now, options = {}) - h = select_hour(datetime, options) + select_minute(datetime, options) + (options[:include_seconds] ? select_second(datetime, options) : '') - end - - # Returns a select tag with options for each of the seconds 0 through 59 with the current second selected. - # The second can also be substituted for a second number. - # Override the field name using the :field_name option, 'second' by default. - def select_second(datetime, options = {}) - second_options = [] - - 0.upto(59) do |second| - second_options << ((datetime && (datetime.kind_of?(Fixnum) ? datetime : datetime.sec) == second) ? - %(\n) : - %(\n) - ) - end - - select_html(options[:field_name] || 'second', second_options, options[:prefix], options[:include_blank], options[:discard_type], options[:disabled]) - end - - # Returns a select tag with options for each of the minutes 0 through 59 with the current minute selected. - # Also can return a select tag with options by minute_step from 0 through 59 with the 00 minute selected - # The minute can also be substituted for a minute number. - # Override the field name using the :field_name option, 'minute' by default. - def select_minute(datetime, options = {}) - minute_options = [] - - 0.step(59, options[:minute_step] || 1) do |minute| - minute_options << ((datetime && (datetime.kind_of?(Fixnum) ? datetime : datetime.min) == minute) ? - %(\n) : - %(\n) - ) - end - - select_html(options[:field_name] || 'minute', minute_options, options[:prefix], options[:include_blank], options[:discard_type], options[:disabled]) - end - - # Returns a select tag with options for each of the hours 0 through 23 with the current hour selected. - # The hour can also be substituted for a hour number. - # Override the field name using the :field_name option, 'hour' by default. - def select_hour(datetime, options = {}) - hour_options = [] - - 0.upto(23) do |hour| - hour_options << ((datetime && (datetime.kind_of?(Fixnum) ? datetime : datetime.hour) == hour) ? - %(\n) : - %(\n) - ) - end - - select_html(options[:field_name] || 'hour', hour_options, options[:prefix], options[:include_blank], options[:discard_type], options[:disabled]) - end - - # Returns a select tag with options for each of the days 1 through 31 with the current day selected. - # The date can also be substituted for a hour number. - # Override the field name using the :field_name option, 'day' by default. - def select_day(date, options = {}) - day_options = [] - - 1.upto(31) do |day| - day_options << ((date && (date.kind_of?(Fixnum) ? date : date.day) == day) ? - %(\n) : - %(\n) - ) - end - - select_html(options[:field_name] || 'day', day_options, options[:prefix], options[:include_blank], options[:discard_type], options[:disabled]) - end - - # Returns a select tag with options for each of the months January through December with the current month selected. - # The month names are presented as keys (what's shown to the user) and the month numbers (1-12) are used as values - # (what's submitted to the server). It's also possible to use month numbers for the presentation instead of names -- - # set the :use_month_numbers key in +options+ to true for this to happen. If you want both numbers and names, - # set the :add_month_numbers key in +options+ to true. Examples: - # - # select_month(Date.today) # Will use keys like "January", "March" - # select_month(Date.today, :use_month_numbers => true) # Will use keys like "1", "3" - # select_month(Date.today, :add_month_numbers => true) # Will use keys like "1 - January", "3 - March" - # - # Override the field name using the :field_name option, 'month' by default. - # - # If you would prefer to show month names as abbreviations, set the - # :use_short_month key in +options+ to true. - def select_month(date, options = {}) - month_options = [] - month_names = options[:use_short_month] ? Date::ABBR_MONTHNAMES : Date::MONTHNAMES - - 1.upto(12) do |month_number| - month_name = if options[:use_month_numbers] - month_number - elsif options[:add_month_numbers] - month_number.to_s + ' - ' + month_names[month_number] - else - month_names[month_number] - end - - month_options << ((date && (date.kind_of?(Fixnum) ? date : date.month) == month_number) ? - %(\n) : - %(\n) - ) - end - - select_html(options[:field_name] || 'month', month_options, options[:prefix], options[:include_blank], options[:discard_type], options[:disabled]) - end - - # Returns a select tag with options for each of the five years on each side of the current, which is selected. The five year radius - # can be changed using the :start_year and :end_year keys in the +options+. Both ascending and descending year - # lists are supported by making :start_year less than or greater than :end_year. The date can also be - # substituted for a year given as a number. Example: - # - # select_year(Date.today, :start_year => 1992, :end_year => 2007) # ascending year values - # select_year(Date.today, :start_year => 2005, :end_year => 1900) # descending year values - # - # Override the field name using the :field_name option, 'year' by default. - def select_year(date, options = {}) - year_options = [] - y = date ? (date.kind_of?(Fixnum) ? (y = (date == 0) ? Date.today.year : date) : date.year) : Date.today.year - - start_year, end_year = (options[:start_year] || y-5), (options[:end_year] || y+5) - step_val = start_year < end_year ? 1 : -1 - - start_year.step(end_year, step_val) do |year| - year_options << ((date && (date.kind_of?(Fixnum) ? date : date.year) == year) ? - %(\n) : - %(\n) - ) - end - - select_html(options[:field_name] || 'year', year_options, options[:prefix], options[:include_blank], options[:discard_type], options[:disabled]) - end - - private - def select_html(type, options, prefix = nil, include_blank = false, discard_type = false, disabled = false) - select_html = %(\n" - end - - def leading_zero_on_single_digits(number) - number > 9 ? number : "0#{number}" - end - end - - class InstanceTag #:nodoc: - include DateHelper - - def to_date_select_tag(options = {}) - defaults = { :discard_type => true } - options = defaults.merge(options) - options_with_prefix = Proc.new { |position| options.merge(:prefix => "#{@object_name}[#{@method_name}(#{position}i)]") } - date = options[:include_blank] ? (value || 0) : (value || Date.today) - - date_select = '' - options[:order] = [:month, :year, :day] if options[:month_before_year] # For backwards compatibility - options[:order] ||= [:year, :month, :day] - - position = {:year => 1, :month => 2, :day => 3} - - discard = {} - discard[:year] = true if options[:discard_year] - discard[:month] = true if options[:discard_month] - discard[:day] = true if options[:discard_day] or options[:discard_month] - - options[:order].each do |param| - date_select << self.send("select_#{param}", date, options_with_prefix.call(position[param])) unless discard[param] - end - - date_select - end - - def to_datetime_select_tag(options = {}) - defaults = { :discard_type => true } - options = defaults.merge(options) - options_with_prefix = Proc.new { |position| options.merge(:prefix => "#{@object_name}[#{@method_name}(#{position}i)]") } - datetime = options[:include_blank] ? (value || nil) : (value || Time.now) - - datetime_select = select_year(datetime, options_with_prefix.call(1)) - datetime_select << select_month(datetime, options_with_prefix.call(2)) unless options[:discard_month] - datetime_select << select_day(datetime, options_with_prefix.call(3)) unless options[:discard_day] || options[:discard_month] - datetime_select << ' — ' + select_hour(datetime, options_with_prefix.call(4)) unless options[:discard_hour] - datetime_select << ' : ' + select_minute(datetime, options_with_prefix.call(5)) unless options[:discard_minute] || options[:discard_hour] - - datetime_select - end - end - end -end diff --git a/tracks/vendor/rails/actionpack/lib/action_view/helpers/debug_helper.rb b/tracks/vendor/rails/actionpack/lib/action_view/helpers/debug_helper.rb deleted file mode 100644 index 8baea6f4..00000000 --- a/tracks/vendor/rails/actionpack/lib/action_view/helpers/debug_helper.rb +++ /dev/null @@ -1,17 +0,0 @@ -module ActionView - module Helpers - # Provides a set of methods for making it easier to locate problems. - module DebugHelper - # Returns a
-tag set with the +object+ dumped by YAML. Very readable way to inspect an object.
-      def debug(object)
-        begin
-          Marshal::dump(object)
-          "
#{h(object.to_yaml).gsub("  ", "  ")}
" - rescue Object => e - # Object couldn't be dumped, perhaps because of singleton methods -- this is the fallback - "#{h(object.inspect)}" - end - end - end - end -end \ No newline at end of file diff --git a/tracks/vendor/rails/actionpack/lib/action_view/helpers/form_helper.rb b/tracks/vendor/rails/actionpack/lib/action_view/helpers/form_helper.rb deleted file mode 100644 index eadaeaea..00000000 --- a/tracks/vendor/rails/actionpack/lib/action_view/helpers/form_helper.rb +++ /dev/null @@ -1,290 +0,0 @@ -require 'cgi' -require File.dirname(__FILE__) + '/date_helper' -require File.dirname(__FILE__) + '/tag_helper' - -module ActionView - module Helpers - # Provides a set of methods for working with forms and especially forms related to objects assigned to the template. - # The following is an example of a complete form for a person object that works for both creates and updates built - # with all the form helpers. The @person object was assigned by an action on the controller: - # - # Name: - # <%= text_field "person", "name", "size" => 20 %> - # - # Password: - # <%= password_field "person", "password", "maxsize" => 20 %> - # - # Single?: - # <%= check_box "person", "single" %> - # - # Description: - # <%= text_area "person", "description", "cols" => 20 %> - # - # - # - # - # ...is compiled to: - # - #
- # Name: - # - # - # Password: - # - # - # Single?: - # - # - # Description: - # - # - # - #
- # - # If the object name contains square brackets the id for the object will be inserted. Example: - # - # <%= textfield "person[]", "name" %> - # - # ...becomes: - # - # - # - # If the helper is being used to generate a repetitive sequence of similar form elements, for example in a partial - # used by render_collection_of_partials, the "index" option may come in handy. Example: - # - # <%= text_field "person", "name", "index" => 1 %> - # - # becomes - # - # - # - # There's also methods for helping to build form tags in link:classes/ActionView/Helpers/FormOptionsHelper.html, - # link:classes/ActionView/Helpers/DateHelper.html, and link:classes/ActionView/Helpers/ActiveRecordHelper.html - module FormHelper - # Returns an input tag of the "text" type tailored for accessing a specified attribute (identified by +method+) on an object - # assigned to the template (identified by +object+). Additional options on the input tag can be passed as a - # hash with +options+. - # - # Examples (call, result): - # text_field("post", "title", "size" => 20) - # - def text_field(object, method, options = {}) - InstanceTag.new(object, method, self).to_input_field_tag("text", options) - end - - # Works just like text_field, but returns an input tag of the "password" type instead. - def password_field(object, method, options = {}) - InstanceTag.new(object, method, self).to_input_field_tag("password", options) - end - - # Works just like text_field, but returns an input tag of the "hidden" type instead. - def hidden_field(object, method, options = {}) - InstanceTag.new(object, method, self).to_input_field_tag("hidden", options) - end - - # Works just like text_field, but returns an input tag of the "file" type instead, which won't have a default value. - def file_field(object, method, options = {}) - InstanceTag.new(object, method, self).to_input_field_tag("file", options) - end - - # Returns a textarea opening and closing tag set tailored for accessing a specified attribute (identified by +method+) - # on an object assigned to the template (identified by +object+). Additional options on the input tag can be passed as a - # hash with +options+. - # - # Example (call, result): - # text_area("post", "body", "cols" => 20, "rows" => 40) - # - def text_area(object, method, options = {}) - InstanceTag.new(object, method, self).to_text_area_tag(options) - end - - # Returns a checkbox tag tailored for accessing a specified attribute (identified by +method+) on an object - # assigned to the template (identified by +object+). It's intended that +method+ returns an integer and if that - # integer is above zero, then the checkbox is checked. Additional options on the input tag can be passed as a - # hash with +options+. The +checked_value+ defaults to 1 while the default +unchecked_value+ - # is set to 0 which is convenient for boolean values. Usually unchecked checkboxes don't post anything. - # We work around this problem by adding a hidden value with the same name as the checkbox. - # - # Example (call, result). Imagine that @post.validated? returns 1: - # check_box("post", "validated") - # - # - # - # Example (call, result). Imagine that @puppy.gooddog returns no: - # check_box("puppy", "gooddog", {}, "yes", "no") - # - # - def check_box(object, method, options = {}, checked_value = "1", unchecked_value = "0") - InstanceTag.new(object, method, self).to_check_box_tag(options, checked_value, unchecked_value) - end - - # Returns a radio button tag for accessing a specified attribute (identified by +method+) on an object - # assigned to the template (identified by +object+). If the current value of +method+ is +tag_value+ the - # radio button will be checked. Additional options on the input tag can be passed as a - # hash with +options+. - # Example (call, result). Imagine that @post.category returns "rails": - # radio_button("post", "category", "rails") - # radio_button("post", "category", "java") - # - # - # - def radio_button(object, method, tag_value, options = {}) - InstanceTag.new(object, method, self).to_radio_button_tag(tag_value, options) - end - end - - class InstanceTag #:nodoc: - include Helpers::TagHelper - - attr_reader :method_name, :object_name - - DEFAULT_FIELD_OPTIONS = { "size" => 30 }.freeze unless const_defined?(:DEFAULT_FIELD_OPTIONS) - DEFAULT_RADIO_OPTIONS = { }.freeze unless const_defined?(:DEFAULT_RADIO_OPTIONS) - DEFAULT_TEXT_AREA_OPTIONS = { "cols" => 40, "rows" => 20 }.freeze unless const_defined?(:DEFAULT_TEXT_AREA_OPTIONS) - DEFAULT_DATE_OPTIONS = { :discard_type => true }.freeze unless const_defined?(:DEFAULT_DATE_OPTIONS) - - def initialize(object_name, method_name, template_object, local_binding = nil) - @object_name, @method_name = object_name.to_s, method_name.to_s - @template_object, @local_binding = template_object, local_binding - if @object_name.sub!(/\[\]$/,"") - @auto_index = @template_object.instance_variable_get("@#{Regexp.last_match.pre_match}").id_before_type_cast - end - end - - def to_input_field_tag(field_type, options = {}) - options = options.stringify_keys - options["size"] ||= options["maxlength"] || DEFAULT_FIELD_OPTIONS["size"] - options = DEFAULT_FIELD_OPTIONS.merge(options) - if field_type == "hidden" - options.delete("size") - end - options["type"] = field_type - options["value"] ||= value_before_type_cast unless field_type == "file" - add_default_name_and_id(options) - tag("input", options) - end - - def to_radio_button_tag(tag_value, options = {}) - options = DEFAULT_RADIO_OPTIONS.merge(options.stringify_keys) - options["type"] = "radio" - options["value"] = tag_value - options["checked"] = "checked" if value.to_s == tag_value.to_s - pretty_tag_value = tag_value.to_s.gsub(/\s/, "_").gsub(/\W/, "").downcase - options["id"] = @auto_index ? - "#{@object_name}_#{@auto_index}_#{@method_name}_#{pretty_tag_value}" : - "#{@object_name}_#{@method_name}_#{pretty_tag_value}" - add_default_name_and_id(options) - tag("input", options) - end - - def to_text_area_tag(options = {}) - options = DEFAULT_TEXT_AREA_OPTIONS.merge(options.stringify_keys) - add_default_name_and_id(options) - content_tag("textarea", html_escape(value_before_type_cast), options) - end - - def to_check_box_tag(options = {}, checked_value = "1", unchecked_value = "0") - options = options.stringify_keys - options["type"] = "checkbox" - options["value"] = checked_value - checked = case value - when TrueClass, FalseClass - value - when NilClass - false - when Integer - value != 0 - when String - value == checked_value - else - value.to_i != 0 - end - if checked || options["checked"] == "checked" - options["checked"] = "checked" - else - options.delete("checked") - end - add_default_name_and_id(options) - tag("input", options) << tag("input", "name" => options["name"], "type" => "hidden", "value" => unchecked_value) - end - - def to_date_tag() - defaults = DEFAULT_DATE_OPTIONS.dup - date = value || Date.today - options = Proc.new { |position| defaults.merge(:prefix => "#{@object_name}[#{@method_name}(#{position}i)]") } - html_day_select(date, options.call(3)) + - html_month_select(date, options.call(2)) + - html_year_select(date, options.call(1)) - end - - def to_boolean_select_tag(options = {}) - options = options.stringify_keys - add_default_name_and_id(options) - tag_text = "" - end - - def to_content_tag(tag_name, options = {}) - content_tag(tag_name, value, options) - end - - def object - @template_object.instance_variable_get "@#{@object_name}" - end - - def value - object.send(@method_name) unless object.nil? - end - - def value_before_type_cast - unless object.nil? - object.respond_to?(@method_name + "_before_type_cast") ? - object.send(@method_name + "_before_type_cast") : - object.send(@method_name) - end - end - - private - def add_default_name_and_id(options) - if options.has_key?("index") - options["name"] ||= tag_name_with_index(options["index"]) - options["id"] ||= tag_id_with_index(options["index"]) - options.delete("index") - elsif @auto_index - options["name"] ||= tag_name_with_index(@auto_index) - options["id"] ||= tag_id_with_index(@auto_index) - else - options["name"] ||= tag_name - options["id"] ||= tag_id - end - end - - def tag_name - "#{@object_name}[#{@method_name}]" - end - - def tag_name_with_index(index) - "#{@object_name}[#{index}][#{@method_name}]" - end - - def tag_id - "#{@object_name}_#{@method_name}" - end - - def tag_id_with_index(index) - "#{@object_name}_#{index}_#{@method_name}" - end - end - end -end diff --git a/tracks/vendor/rails/actionpack/lib/action_view/helpers/form_options_helper.rb b/tracks/vendor/rails/actionpack/lib/action_view/helpers/form_options_helper.rb deleted file mode 100644 index a529b71e..00000000 --- a/tracks/vendor/rails/actionpack/lib/action_view/helpers/form_options_helper.rb +++ /dev/null @@ -1,339 +0,0 @@ -require 'cgi' -require 'erb' -require File.dirname(__FILE__) + '/form_helper' - -module ActionView - module Helpers - # Provides a number of methods for turning different kinds of containers into a set of option tags. - # == Options - # The collection_select, country_select, select, - # and time_zone_select methods take an options parameter, - # a hash. - # - # * :include_blank - set to true if the first option element of the select element is a blank. Useful if there is not a default value required for the select element. For example, - # - # select("post", "category", Post::CATEGORIES, {:include_blank => true}) - # - # could become: - # - # - # - # * :prompt - set to true or a prompt string. When the select element doesn't have a value yet, this prepends an option with a generic prompt -- "Please select" -- or the given prompt string. - # - # Another common case is a select tag for an belongs_to-associated object. For example, - # - # select("post", "person_id", Person.find_all.collect {|p| [ p.name, p.id ] }) - # - # could become: - # - # - module FormOptionsHelper - include ERB::Util - - # Create a select tag and a series of contained option tags for the provided object and method. - # The option currently held by the object will be selected, provided that the object is available. - # See options_for_select for the required format of the choices parameter. - # - # Example with @post.person_id => 1: - # select("post", "person_id", Person.find_all.collect {|p| [ p.name, p.id ] }, { :include_blank => true }) - # - # could become: - # - # - # - # This can be used to provide a default set of options in the standard way: before rendering the create form, a - # new model instance is assigned the default options and bound to @model_name. Usually this model is not saved - # to the database. Instead, a second model object is created when the create request is received. - # This allows the user to submit a form page more than once with the expected results of creating multiple records. - # In addition, this allows a single partial to be used to generate form inputs for both edit and create forms. - def select(object, method, choices, options = {}, html_options = {}) - InstanceTag.new(object, method, self).to_select_tag(choices, options, html_options) - end - - # Return select and option tags for the given object and method using options_from_collection_for_select to generate the list of option tags. - def collection_select(object, method, collection, value_method, text_method, options = {}, html_options = {}) - InstanceTag.new(object, method, self).to_collection_select_tag(collection, value_method, text_method, options, html_options) - end - - # Return select and option tags for the given object and method, using country_options_for_select to generate the list of option tags. - def country_select(object, method, priority_countries = nil, options = {}, html_options = {}) - InstanceTag.new(object, method, self).to_country_select_tag(priority_countries, options, html_options) - end - - # Return select and option tags for the given object and method, using - # #time_zone_options_for_select to generate the list of option tags. - # - # In addition to the :include_blank option documented above, - # this method also supports a :model option, which defaults - # to TimeZone. This may be used by users to specify a different time - # zone model object. (See #time_zone_options_for_select for more - # information.) - def time_zone_select(object, method, priority_zones = nil, options = {}, html_options = {}) - InstanceTag.new(object, method, self).to_time_zone_select_tag(priority_zones, options, html_options) - end - - # Accepts a container (hash, array, enumerable, your type) and returns a string of option tags. Given a container - # where the elements respond to first and last (such as a two-element array), the "lasts" serve as option values and - # the "firsts" as option text. Hashes are turned into this form automatically, so the keys become "firsts" and values - # become lasts. If +selected+ is specified, the matching "last" or element will get the selected option-tag. +Selected+ - # may also be an array of values to be selected when using a multiple select. - # - # Examples (call, result): - # options_for_select([["Dollar", "$"], ["Kroner", "DKK"]]) - # \n - # - # options_for_select([ "VISA", "MasterCard" ], "MasterCard") - # \n - # - # options_for_select({ "Basic" => "$20", "Plus" => "$40" }, "$40") - # \n - # - # options_for_select([ "VISA", "MasterCard", "Discover" ], ["VISA", "Discover"]) - # \n\n - # - # NOTE: Only the option tags are returned, you have to wrap this call in a regular HTML select tag. - def options_for_select(container, selected = nil) - container = container.to_a if Hash === container - - options_for_select = container.inject([]) do |options, element| - if !element.is_a?(String) and element.respond_to?(:first) and element.respond_to?(:last) - is_selected = ( (selected.respond_to?(:include?) ? selected.include?(element.last) : element.last == selected) ) - is_selected = ( (selected.respond_to?(:include?) && !selected.is_a?(String) ? selected.include?(element.last) : element.last == selected) ) - if is_selected - options << "" - else - options << "" - end - else - is_selected = ( (selected.respond_to?(:include?) ? selected.include?(element) : element == selected) ) - is_selected = ( (selected.respond_to?(:include?) && !selected.is_a?(String) ? selected.include?(element) : element == selected) ) - options << ((is_selected) ? "" : "") - end - end - - options_for_select.join("\n") - end - - # Returns a string of option tags that have been compiled by iterating over the +collection+ and assigning the - # the result of a call to the +value_method+ as the option value and the +text_method+ as the option text. - # If +selected_value+ is specified, the element returning a match on +value_method+ will get the selected option tag. - # - # Example (call, result). Imagine a loop iterating over each +person+ in @project.people to generate an input tag: - # options_from_collection_for_select(@project.people, "id", "name") - # - # - # NOTE: Only the option tags are returned, you have to wrap this call in a regular HTML select tag. - def options_from_collection_for_select(collection, value_method, text_method, selected_value = nil) - options_for_select( - collection.inject([]) { |options, object| options << [ object.send(text_method), object.send(value_method) ] }, - selected_value - ) - end - - # Returns a string of option tags, like options_from_collection_for_select, but surrounds them with tags. - # - # An array of group objects are passed. Each group should return an array of options when calling group_method - # Each group should return its name when calling group_label_method. - # - # html_option_groups_from_collection(@continents, "countries", "continent_name", "country_id", "country_name", @selected_country.id) - # - # Could become: - # - # - # - # ... - # - # - # - # - # - # ... - # - # - # with objects of the following classes: - # class Continent - # def initialize(p_name, p_countries) @continent_name = p_name; @countries = p_countries; end - # def continent_name() @continent_name; end - # def countries() @countries; end - # end - # class Country - # def initialize(id, name) @id = id; @name = name end - # def country_id() @id; end - # def country_name() @name; end - # end - # - # NOTE: Only the option tags are returned, you have to wrap this call in a regular HTML select tag. - def option_groups_from_collection_for_select(collection, group_method, group_label_method, - option_key_method, option_value_method, selected_key = nil) - collection.inject("") do |options_for_select, group| - group_label_string = eval("group.#{group_label_method}") - options_for_select += "" - options_for_select += options_from_collection_for_select(eval("group.#{group_method}"), option_key_method, option_value_method, selected_key) - options_for_select += '' - end - end - - # Returns a string of option tags for pretty much any country in the world. Supply a country name as +selected+ to - # have it marked as the selected option tag. You can also supply an array of countries as +priority_countries+, so - # that they will be listed above the rest of the (long) list. - # - # NOTE: Only the option tags are returned, you have to wrap this call in a regular HTML select tag. - def country_options_for_select(selected = nil, priority_countries = nil) - country_options = "" - - if priority_countries - country_options += options_for_select(priority_countries, selected) - country_options += "\n" - end - - if priority_countries && priority_countries.include?(selected) - country_options += options_for_select(COUNTRIES - priority_countries, selected) - else - country_options += options_for_select(COUNTRIES, selected) - end - - return country_options - end - - # Returns a string of option tags for pretty much any time zone in the - # world. Supply a TimeZone object as +selected+ to have it marked as the - # selected option tag. You can also supply an array of TimeZone objects - # as +priority_zones+, so that they will be listed above the rest of the - # (long) list. (You can use TimeZone.us_zones as a convenience for - # obtaining a list of the US time zones.) - # - # The +selected+ parameter must be either +nil+, or a string that names - # a TimeZone. - # - # By default, +model+ is the TimeZone constant (which can be obtained - # in ActiveRecord as a value object). The only requirement is that the - # +model+ parameter be an object that responds to #all, and returns - # an array of objects that represent time zones. - # - # NOTE: Only the option tags are returned, you have to wrap this call in - # a regular HTML select tag. - def time_zone_options_for_select(selected = nil, priority_zones = nil, model = TimeZone) - zone_options = "" - - zones = model.all - convert_zones = lambda { |list| list.map { |z| [ z.to_s, z.name ] } } - - if priority_zones - zone_options += options_for_select(convert_zones[priority_zones], selected) - zone_options += "\n" - - zones = zones.reject { |z| priority_zones.include?( z ) } - end - - zone_options += options_for_select(convert_zones[zones], selected) - zone_options - end - - private - # All the countries included in the country_options output. - COUNTRIES = [ "Afghanistan", "Albania", "Algeria", "American Samoa", "Andorra", "Angola", "Anguilla", - "Antarctica", "Antigua And Barbuda", "Argentina", "Armenia", "Aruba", "Australia", - "Austria", "Azerbaijan", "Bahamas", "Bahrain", "Bangladesh", "Barbados", "Belarus", - "Belgium", "Belize", "Benin", "Bermuda", "Bhutan", "Bolivia", "Bosnia and Herzegowina", - "Botswana", "Bouvet Island", "Brazil", "British Indian Ocean Territory", - "Brunei Darussalam", "Bulgaria", "Burkina Faso", "Burma", "Burundi", "Cambodia", - "Cameroon", "Canada", "Cape Verde", "Cayman Islands", "Central African Republic", - "Chad", "Chile", "China", "Christmas Island", "Cocos (Keeling) Islands", "Colombia", - "Comoros", "Congo", "Congo, the Democratic Republic of the", "Cook Islands", - "Costa Rica", "Cote d'Ivoire", "Croatia", "Cuba", "Cyprus", "Czech Republic", "Denmark", - "Djibouti", "Dominica", "Dominican Republic", "East Timor", "Ecuador", "Egypt", - "El Salvador", "England", "Equatorial Guinea", "Eritrea", "Espana", "Estonia", - "Ethiopia", "Falkland Islands", "Faroe Islands", "Fiji", "Finland", "France", - "French Guiana", "French Polynesia", "French Southern Territories", "Gabon", "Gambia", - "Georgia", "Germany", "Ghana", "Gibraltar", "Great Britain", "Greece", "Greenland", - "Grenada", "Guadeloupe", "Guam", "Guatemala", "Guinea", "Guinea-Bissau", "Guyana", - "Haiti", "Heard and Mc Donald Islands", "Honduras", "Hong Kong", "Hungary", "Iceland", - "India", "Indonesia", "Ireland", "Israel", "Italy", "Iran", "Iraq", "Jamaica", "Japan", "Jordan", - "Kazakhstan", "Kenya", "Kiribati", "Korea, Republic of", "Korea (South)", "Kuwait", - "Kyrgyzstan", "Lao People's Democratic Republic", "Latvia", "Lebanon", "Lesotho", - "Liberia", "Liechtenstein", "Lithuania", "Luxembourg", "Macau", "Macedonia", - "Madagascar", "Malawi", "Malaysia", "Maldives", "Mali", "Malta", "Marshall Islands", - "Martinique", "Mauritania", "Mauritius", "Mayotte", "Mexico", - "Micronesia, Federated States of", "Moldova, Republic of", "Monaco", "Mongolia", - "Montserrat", "Morocco", "Mozambique", "Myanmar", "Namibia", "Nauru", "Nepal", - "Netherlands", "Netherlands Antilles", "New Caledonia", "New Zealand", "Nicaragua", - "Niger", "Nigeria", "Niue", "Norfolk Island", "Northern Ireland", - "Northern Mariana Islands", "Norway", "Oman", "Pakistan", "Palau", "Panama", - "Papua New Guinea", "Paraguay", "Peru", "Philippines", "Pitcairn", "Poland", - "Portugal", "Puerto Rico", "Qatar", "Reunion", "Romania", "Russia", "Rwanda", - "Saint Kitts and Nevis", "Saint Lucia", "Saint Vincent and the Grenadines", - "Samoa (Independent)", "San Marino", "Sao Tome and Principe", "Saudi Arabia", - "Scotland", "Senegal", "Serbia and Montenegro", "Seychelles", "Sierra Leone", "Singapore", - "Slovakia", "Slovenia", "Solomon Islands", "Somalia", "South Africa", - "South Georgia and the South Sandwich Islands", "South Korea", "Spain", "Sri Lanka", - "St. Helena", "St. Pierre and Miquelon", "Suriname", "Svalbard and Jan Mayen Islands", - "Swaziland", "Sweden", "Switzerland", "Taiwan", "Tajikistan", "Tanzania", "Thailand", - "Togo", "Tokelau", "Tonga", "Trinidad", "Trinidad and Tobago", "Tunisia", "Turkey", - "Turkmenistan", "Turks and Caicos Islands", "Tuvalu", "Uganda", "Ukraine", - "United Arab Emirates", "United Kingdom", "United States", - "United States Minor Outlying Islands", "Uruguay", "Uzbekistan", "Vanuatu", - "Vatican City State (Holy See)", "Venezuela", "Viet Nam", "Virgin Islands (British)", - "Virgin Islands (U.S.)", "Wales", "Wallis and Futuna Islands", "Western Sahara", - "Yemen", "Zambia", "Zimbabwe" ] unless const_defined?("COUNTRIES") - end - - class InstanceTag #:nodoc: - include FormOptionsHelper - - def to_select_tag(choices, options, html_options) - html_options = html_options.stringify_keys - add_default_name_and_id(html_options) - content_tag("select", add_options(options_for_select(choices, value), options, value), html_options) - end - - def to_collection_select_tag(collection, value_method, text_method, options, html_options) - html_options = html_options.stringify_keys - add_default_name_and_id(html_options) - content_tag( - "select", add_options(options_from_collection_for_select(collection, value_method, text_method, value), options, value), html_options - ) - end - - def to_country_select_tag(priority_countries, options, html_options) - html_options = html_options.stringify_keys - add_default_name_and_id(html_options) - content_tag("select", add_options(country_options_for_select(value, priority_countries), options, value), html_options) - end - - def to_time_zone_select_tag(priority_zones, options, html_options) - html_options = html_options.stringify_keys - add_default_name_and_id(html_options) - content_tag("select", - add_options( - time_zone_options_for_select(value, priority_zones, options[:model] || TimeZone), - options, value - ), html_options - ) - end - - private - def add_options(option_tags, options, value = nil) - option_tags = "\n" + option_tags if options[:include_blank] - - if value.blank? && options[:prompt] - ("\n") + option_tags - else - option_tags - end - end - end - end -end diff --git a/tracks/vendor/rails/actionpack/lib/action_view/helpers/form_tag_helper.rb b/tracks/vendor/rails/actionpack/lib/action_view/helpers/form_tag_helper.rb deleted file mode 100644 index a31c6b0c..00000000 --- a/tracks/vendor/rails/actionpack/lib/action_view/helpers/form_tag_helper.rb +++ /dev/null @@ -1,136 +0,0 @@ -require 'cgi' -require File.dirname(__FILE__) + '/tag_helper' - -module ActionView - module Helpers - # Provides a number of methods for creating form tags that doesn't rely on conventions with an object assigned to the template like - # FormHelper does. With the FormTagHelper, you provide the names and values yourself. - # - # NOTE: The html options disabled, readonly, and multiple can all be treated as booleans. So specifying :disabled => true - # will give disabled="disabled". - module FormTagHelper - # Starts a form tag that points the action to an url configured with url_for_options just like - # ActionController::Base#url_for. The method for the form defaults to POST. - # - # Options: - # * :multipart - If set to true, the enctype is set to "multipart/form-data". - # * :method - The method to use when submitting the form, usually either "get" or "post". - def form_tag(url_for_options = {}, options = {}, *parameters_for_url) - html_options = { "method" => "post" }.merge(options.stringify_keys) - - if html_options["multipart"] - html_options["enctype"] = "multipart/form-data" - html_options.delete("multipart") - end - - html_options["action"] = url_for(url_for_options, *parameters_for_url) - tag("form", html_options, true) - end - - alias_method :start_form_tag, :form_tag - - # Outputs "" - def end_form_tag - "" - end - - # Creates a dropdown selection box, or if the :multiple option is set to true, a multiple - # choice selection box. - # - # Helpers::FormOptions can be used to create common select boxes such as countries, time zones, or - # associated records. - # - # option_tags is a string containing the option tags for the select box: - # # Outputs - # select_tag "people", "" - # - # Options: - # * :multiple - If set to true the selection will allow multiple choices. - def select_tag(name, option_tags = nil, options = {}) - content_tag("select", option_tags, { "name" => name, "id" => name }.update(options.stringify_keys)) - end - - # Creates a standard text field. - # - # Options: - # * :disabled - If set to true, the user will not be able to use this input. - # * :size - The number of visible characters that will fit in the input. - # * :maxlength - The maximum number of characters that the browser will allow the user to enter. - # - # A hash of standard HTML options for the tag. - def text_field_tag(name, value = nil, options = {}) - tag("input", { "type" => "text", "name" => name, "id" => name, "value" => value }.update(options.stringify_keys)) - end - - # Creates a hidden field. - # - # Takes the same options as text_field_tag - def hidden_field_tag(name, value = nil, options = {}) - text_field_tag(name, value, options.stringify_keys.update("type" => "hidden")) - end - - # Creates a file upload field. - # - # If you are using file uploads then you will also need to set the multipart option for the form: - # <%= form_tag { :action => "post" }, { :multipart => true } %> - # <%= file_field_tag "file" %> - # <%= submit_tag %> - # <%= end_form_tag %> - # - # The specified URL will then be passed a File object containing the selected file, or if the field - # was left blank, a StringIO object. - def file_field_tag(name, options = {}) - text_field_tag(name, nil, options.update("type" => "file")) - end - - # Creates a password field. - # - # Takes the same options as text_field_tag - def password_field_tag(name = "password", value = nil, options = {}) - text_field_tag(name, value, options.update("type" => "password")) - end - - # Creates a text input area. - # - # Options: - # * :size - A string specifying the dimensions of the textarea. - # # Outputs - # <%= text_area_tag "body", nil, :size => "25x10" %> - def text_area_tag(name, content = nil, options = {}) - options = options.stringify_keys - if options["size"] - options["cols"], options["rows"] = options["size"].split("x") - options.delete("size") - end - - content_tag("textarea", content, { "name" => name, "id" => name }.update(options.stringify_keys)) - end - - # Creates a check box. - def check_box_tag(name, value = "1", checked = false, options = {}) - html_options = { "type" => "checkbox", "name" => name, "id" => name, "value" => value }.update(options.stringify_keys) - html_options["checked"] = "checked" if checked - tag("input", html_options) - end - - # Creates a radio button. - def radio_button_tag(name, value, checked = false, options = {}) - html_options = { "type" => "radio", "name" => name, "id" => name, "value" => value }.update(options.stringify_keys) - html_options["checked"] = "checked" if checked - tag("input", html_options) - end - - # Creates a submit button with the text value as the caption. - def submit_tag(value = "Save changes", options = {}) - tag("input", { "type" => "submit", "name" => "commit", "value" => value }.update(options.stringify_keys)) - end - - # Displays an image which when clicked will submit the form. - # - # source is passed to AssetTagHelper#image_path - def image_submit_tag(source, options = {}) - tag("input", { "type" => "image", "src" => image_path(source) }.update(options.stringify_keys)) - end - end - end -end diff --git a/tracks/vendor/rails/actionpack/lib/action_view/helpers/java_script_macros_helper.rb b/tracks/vendor/rails/actionpack/lib/action_view/helpers/java_script_macros_helper.rb deleted file mode 100644 index f0fc0925..00000000 --- a/tracks/vendor/rails/actionpack/lib/action_view/helpers/java_script_macros_helper.rb +++ /dev/null @@ -1,190 +0,0 @@ -require File.dirname(__FILE__) + '/tag_helper' - -module ActionView - module Helpers - # Provides a set of helpers for creating JavaScript macros that rely on and often bundle methods from JavaScriptHelper into - # larger units. These macros also rely on counterparts in the controller that provide them with their backing. The in-place - # editing relies on ActionController::Base.in_place_edit_for and the autocompletion relies on - # ActionController::Base.auto_complete_for. - module JavaScriptMacrosHelper - # Makes an HTML element specified by the DOM ID +field_id+ become an in-place - # editor of a property. - # - # A form is automatically created and displayed when the user clicks the element, - # something like this: - #
- # - # - # cancel - #
- # - # The form is serialized and sent to the server using an AJAX call, the action on - # the server should process the value and return the updated value in the body of - # the reponse. The element will automatically be updated with the changed value - # (as returned from the server). - # - # Required +options+ are: - # :url:: Specifies the url where the updated value should - # be sent after the user presses "ok". - # - # Addtional +options+ are: - # :rows:: Number of rows (more than 1 will use a TEXTAREA) - # :cancel_text:: The text on the cancel link. (default: "cancel") - # :save_text:: The text on the save link. (default: "ok") - # :external_control:: The id of an external control used to enter edit mode. - # :options:: Pass through options to the AJAX call (see prototype's Ajax.Updater) - # :with:: JavaScript snippet that should return what is to be sent - # in the AJAX call, +form+ is an implicit parameter - def in_place_editor(field_id, options = {}) - function = "new Ajax.InPlaceEditor(" - function << "'#{field_id}', " - function << "'#{url_for(options[:url])}'" - - js_options = {} - js_options['cancelText'] = %('#{options[:cancel_text]}') if options[:cancel_text] - js_options['okText'] = %('#{options[:save_text]}') if options[:save_text] - js_options['rows'] = options[:rows] if options[:rows] - js_options['externalControl'] = options[:external_control] if options[:external_control] - js_options['ajaxOptions'] = options[:options] if options[:options] - js_options['callback'] = "function(form) { return #{options[:with]} }" if options[:with] - function << (', ' + options_for_javascript(js_options)) unless js_options.empty? - - function << ')' - - javascript_tag(function) - end - - # Renders the value of the specified object and method with in-place editing capabilities. - # - # See the RDoc on ActionController::InPlaceEditing to learn more about this. - def in_place_editor_field(object, method, tag_options = {}, in_place_editor_options = {}) - tag = ::ActionView::Helpers::InstanceTag.new(object, method, self) - tag_options = {:tag => "span", :id => "#{object}_#{method}_#{tag.object.id}_in_place_editor", :class => "in_place_editor_field"}.merge!(tag_options) - in_place_editor_options[:url] = in_place_editor_options[:url] || url_for({ :action => "set_#{object}_#{method}", :id => tag.object.id }) - tag.to_content_tag(tag_options.delete(:tag), tag_options) + - in_place_editor(tag_options[:id], in_place_editor_options) - end - - # Adds AJAX autocomplete functionality to the text input field with the - # DOM ID specified by +field_id+. - # - # This function expects that the called action returns a HTML
    list, - # or nothing if no entries should be displayed for autocompletion. - # - # You'll probably want to turn the browser's built-in autocompletion off, - # su be sure to include a autocomplete="off" attribute with your text - # input field. - # - # Required +options+ are: - # :url:: URL to call for autocompletion results - # in url_for format. - # - # Addtional +options+ are: - # :update:: Specifies the DOM ID of the element whose - # innerHTML should be updated with the autocomplete - # entries returned by the AJAX request. - # Defaults to field_id + '_auto_complete' - # :with:: A JavaScript expression specifying the - # parameters for the XMLHttpRequest. This defaults - # to 'fieldname=value'. - # :indicator:: Specifies the DOM ID of an element which will be - # displayed while autocomplete is running. - # :tokens:: A string or an array of strings containing - # separator tokens for tokenized incremental - # autocompletion. Example: :tokens => ',' would - # allow multiple autocompletion entries, separated - # by commas. - # :min_chars:: The minimum number of characters that should be - # in the input field before an Ajax call is made - # to the server. - # :on_hide:: A Javascript expression that is called when the - # autocompletion div is hidden. The expression - # should take two variables: element and update. - # Element is a DOM element for the field, update - # is a DOM element for the div from which the - # innerHTML is replaced. - # :on_show:: Like on_hide, only now the expression is called - # then the div is shown. - def auto_complete_field(field_id, options = {}) - function = "new Ajax.Autocompleter(" - function << "'#{field_id}', " - function << "'" + (options[:update] || "#{field_id}_auto_complete") + "', " - function << "'#{url_for(options[:url])}'" - - js_options = {} - js_options[:tokens] = array_or_string_for_javascript(options[:tokens]) if options[:tokens] - js_options[:callback] = "function(element, value) { return #{options[:with]} }" if options[:with] - js_options[:indicator] = "'#{options[:indicator]}'" if options[:indicator] - {:on_show => :onShow, :on_hide => :onHide, :min_chars => :min_chars}.each do |k,v| - js_options[v] = options[k] if options[k] - end - function << (', ' + options_for_javascript(js_options) + ')') - - javascript_tag(function) - end - - # Use this method in your view to generate a return for the AJAX autocomplete requests. - # - # Example action: - # - # def auto_complete_for_item_title - # @items = Item.find(:all, - # :conditions => [ 'LOWER(description) LIKE ?', - # '%' + request.raw_post.downcase + '%' ]) - # render :inline => '<%= auto_complete_result(@items, 'description') %>' - # end - # - # The auto_complete_result can of course also be called from a view belonging to the - # auto_complete action if you need to decorate it further. - def auto_complete_result(entries, field, phrase = nil) - return unless entries - items = entries.map { |entry| content_tag("li", phrase ? highlight(entry[field], phrase) : h(entry[field])) } - content_tag("ul", items.uniq) - end - - # Wrapper for text_field with added AJAX autocompletion functionality. - # - # In your controller, you'll need to define an action called - # auto_complete_for_object_method to respond the AJAX calls, - # - # See the RDoc on ActionController::AutoComplete to learn more about this. - def text_field_with_auto_complete(object, method, tag_options = {}, completion_options = {}) - (completion_options[:skip_style] ? "" : auto_complete_stylesheet) + - text_field(object, method, tag_options) + - content_tag("div", "", :id => "#{object}_#{method}_auto_complete", :class => "auto_complete") + - auto_complete_field("#{object}_#{method}", { :url => { :action => "auto_complete_for_#{object}_#{method}" } }.update(completion_options)) - end - - private - def auto_complete_stylesheet - content_tag("style", <<-EOT - div.auto_complete { - width: 350px; - background: #fff; - } - div.auto_complete ul { - border:1px solid #888; - margin:0; - padding:0; - width:100%; - list-style-type:none; - } - div.auto_complete ul li { - margin:0; - padding:3px; - } - div.auto_complete ul li.selected { - background-color: #ffb; - } - div.auto_complete ul strong.highlight { - color: #800; - margin:0; - padding:0; - } - EOT - ) - end - - end - end -end diff --git a/tracks/vendor/rails/actionpack/lib/action_view/helpers/javascript_helper.rb b/tracks/vendor/rails/actionpack/lib/action_view/helpers/javascript_helper.rb deleted file mode 100644 index e7109e92..00000000 --- a/tracks/vendor/rails/actionpack/lib/action_view/helpers/javascript_helper.rb +++ /dev/null @@ -1,528 +0,0 @@ -require File.dirname(__FILE__) + '/tag_helper' - -module ActionView - module Helpers - # Provides a set of helpers for calling JavaScript functions and, most importantly, to call remote methods using what has - # been labelled AJAX[http://www.adaptivepath.com/publications/essays/archives/000385.php]. This means that you can call - # actions in your controllers without reloading the page, but still update certain parts of it using injections into the - # DOM. The common use case is having a form that adds a new element to a list without reloading the page. - # - # To be able to use the JavaScript helpers, you must include the Prototype JavaScript Framework and for some functions - # script.aculo.us (which both come with Rails) on your pages. Choose one of these options: - # - # * Use <%= javascript_include_tag :defaults %> in the HEAD section of your page (recommended): - # The function will return references to the JavaScript files created by the +rails+ command in your - # public/javascripts directory. Using it is recommended as the browser can then cache the libraries - # instead of fetching all the functions anew on every request. - # * Use <%= javascript_include_tag 'prototype' %>: As above, but will only include the Prototype core library, - # which means you are able to use all basic AJAX functionality. For the script.aculo.us-based JavaScript helpers, - # like visual effects, autocompletion, drag and drop and so on, you should use the method described above. - # * Use <%= define_javascript_functions %>: this will copy all the JavaScript support functions within a single - # script block. - # - # For documentation on +javascript_include_tag+ see ActionView::Helpers::AssetTagHelper. - # - # If you're the visual type, there's an AJAX movie[http://www.rubyonrails.com/media/video/rails-ajax.mov] demonstrating - # the use of form_remote_tag. - module JavaScriptHelper - unless const_defined? :CALLBACKS - CALLBACKS = - [:uninitialized, :loading, :loaded, :interactive, :complete, :failure, :success].push((100..599).to_a).flatten - AJAX_OPTIONS = [ :before, :after, :condition, :url, :asynchronous, :method, - :insertion, :position, :form, :with, :update, :script ].concat(CALLBACKS) - JAVASCRIPT_PATH = File.join(File.dirname(__FILE__), 'javascripts') - end - - # Returns a link that'll trigger a javascript +function+ using the - # onclick handler and return false after the fact. - # - # Examples: - # link_to_function "Greeting", "alert('Hello world!')" - # link_to_function(image_tag("delete"), "if confirm('Really?'){ do_delete(); }") - def link_to_function(name, function, html_options = {}) - content_tag( - "a", name, - {:href => "#", :onclick => "#{function}; return false;"}.merge(html_options.symbolize_keys) - ) - end - - # Returns a link to a remote action defined by options[:url] - # (using the url_for format) that's called in the background using - # XMLHttpRequest. The result of that request can then be inserted into a - # DOM object whose id can be specified with options[:update]. - # Usually, the result would be a partial prepared by the controller with - # either render_partial or render_partial_collection. - # - # Examples: - # link_to_remote "Delete this post", :update => "posts", :url => { :action => "destroy", :id => post.id } - # link_to_remote(image_tag("refresh"), :update => "emails", :url => { :action => "list_emails" }) - # - # You can also specify a hash for options[:update] to allow for - # easy redirection of output to an other DOM element if a server-side error occurs: - # - # Example: - # link_to_remote "Delete this post", - # :url => { :action => "destroy", :id => post.id }, - # :update => { :success => "posts", :failure => "error" } - # - # Optionally, you can use the options[:position] parameter to influence - # how the target DOM element is updated. It must be one of - # :before, :top, :bottom, or :after. - # - # By default, these remote requests are processed asynchronous during - # which various JavaScript callbacks can be triggered (for progress indicators and - # the likes). All callbacks get access to the request object, - # which holds the underlying XMLHttpRequest. - # - # To access the server response, use request.responseText, to - # find out the HTTP status, use request.status. - # - # Example: - # link_to_remote word, - # :url => { :action => "undo", :n => word_counter }, - # :complete => "undoRequestCompleted(request)" - # - # The callbacks that may be specified are (in order): - # - # :loading:: Called when the remote document is being - # loaded with data by the browser. - # :loaded:: Called when the browser has finished loading - # the remote document. - # :interactive:: Called when the user can interact with the - # remote document, even though it has not - # finished loading. - # :success:: Called when the XMLHttpRequest is completed, - # and the HTTP status code is in the 2XX range. - # :failure:: Called when the XMLHttpRequest is completed, - # and the HTTP status code is not in the 2XX - # range. - # :complete:: Called when the XMLHttpRequest is complete - # (fires after success/failure if they are present)., - # - # You can further refine :success and :failure by adding additional - # callbacks for specific status codes: - # - # Example: - # link_to_remote word, - # :url => { :action => "action" }, - # 404 => "alert('Not found...? Wrong URL...?')", - # :failure => "alert('HTTP Error ' + request.status + '!')" - # - # A status code callback overrides the success/failure handlers if present. - # - # If you for some reason or another need synchronous processing (that'll - # block the browser while the request is happening), you can specify - # options[:type] = :synchronous. - # - # You can customize further browser side call logic by passing - # in JavaScript code snippets via some optional parameters. In - # their order of use these are: - # - # :confirm:: Adds confirmation dialog. - # :condition:: Perform remote request conditionally - # by this expression. Use this to - # describe browser-side conditions when - # request should not be initiated. - # :before:: Called before request is initiated. - # :after:: Called immediately after request was - # initiated and before :loading. - # :submit:: Specifies the DOM element ID that's used - # as the parent of the form elements. By - # default this is the current form, but - # it could just as well be the ID of a - # table row or any other DOM element. - def link_to_remote(name, options = {}, html_options = {}) - link_to_function(name, remote_function(options), html_options) - end - - # Periodically calls the specified url (options[:url]) every options[:frequency] seconds (default is 10). - # Usually used to update a specified div (options[:update]) with the results of the remote call. - # The options for specifying the target with :url and defining callbacks is the same as link_to_remote. - def periodically_call_remote(options = {}) - frequency = options[:frequency] || 10 # every ten seconds by default - code = "new PeriodicalExecuter(function() {#{remote_function(options)}}, #{frequency})" - javascript_tag(code) - end - - # Returns a form tag that will submit using XMLHttpRequest in the background instead of the regular - # reloading POST arrangement. Even though it's using JavaScript to serialize the form elements, the form submission - # will work just like a regular submission as viewed by the receiving side (all elements available in @params). - # The options for specifying the target with :url and defining callbacks is the same as link_to_remote. - # - # A "fall-through" target for browsers that doesn't do JavaScript can be specified with the :action/:method options on :html - # - # form_remote_tag :html => { :action => url_for(:controller => "some", :action => "place") } - # The Hash passed to the :html key is equivalent to the options (2nd) argument in the FormTagHelper.form_tag method. - # - # By default the fall-through action is the same as the one specified in the :url (and the default method is :post). - def form_remote_tag(options = {}) - options[:form] = true - - options[:html] ||= {} - options[:html][:onsubmit] = "#{remote_function(options)}; return false;" - options[:html][:action] = options[:html][:action] || url_for(options[:url]) - options[:html][:method] = options[:html][:method] || "post" - - tag("form", options[:html], true) - end - - # Returns a button input tag that will submit form using XMLHttpRequest in the background instead of regular - # reloading POST arrangement. options argument is the same as in form_remote_tag - def submit_to_remote(name, value, options = {}) - options[:with] ||= 'Form.serialize(this.form)' - - options[:html] ||= {} - options[:html][:type] = 'button' - options[:html][:onclick] = "#{remote_function(options)}; return false;" - options[:html][:name] = name - options[:html][:value] = value - - tag("input", options[:html], false) - end - - # Returns a Javascript function (or expression) that'll update a DOM element according to the options passed. - # - # * :content: The content to use for updating. Can be left out if using block, see example. - # * :action: Valid options are :update (assumed by default), :empty, :remove - # * :position If the :action is :update, you can optionally specify one of the following positions: :before, :top, :bottom, :after. - # - # Examples: - # <%= javascript_tag(update_element_function( - # "products", :position => :bottom, :content => "

    New product!

    ")) %> - # - # <% replacement_function = update_element_function("products") do %> - #

    Product 1

    - #

    Product 2

    - # <% end %> - # <%= javascript_tag(replacement_function) %> - # - # This method can also be used in combination with remote method call where the result is evaluated afterwards to cause - # multiple updates on a page. Example: - # - # # Calling view - # <%= form_remote_tag :url => { :action => "buy" }, :complete => evaluate_remote_response %> - # all the inputs here... - # - # # Controller action - # def buy - # @product = Product.find(1) - # end - # - # # Returning view - # <%= update_element_function( - # "cart", :action => :update, :position => :bottom, - # :content => "

    New Product: #{@product.name}

    ")) %> - # <% update_element_function("status", :binding => binding) do %> - # You've bought a new product! - # <% end %> - # - # Notice how the second call doesn't need to be in an ERb output block since it uses a block and passes in the binding - # to render directly. This trick will however only work in ERb (not Builder or other template forms). - def update_element_function(element_id, options = {}, &block) - - content = escape_javascript(options[:content] || '') - content = escape_javascript(capture(&block)) if block - - javascript_function = case (options[:action] || :update) - when :update - if options[:position] - "new Insertion.#{options[:position].to_s.camelize}('#{element_id}','#{content}')" - else - "$('#{element_id}').innerHTML = '#{content}'" - end - - when :empty - "$('#{element_id}').innerHTML = ''" - - when :remove - "Element.remove('#{element_id}')" - - else - raise ArgumentError, "Invalid action, choose one of :update, :remove, :empty" - end - - javascript_function << ";\n" - options[:binding] ? concat(javascript_function, options[:binding]) : javascript_function - end - - # Returns 'eval(request.responseText)' which is the Javascript function that form_remote_tag can call in :complete to - # evaluate a multiple update return document using update_element_function calls. - def evaluate_remote_response - "eval(request.responseText)" - end - - # Returns the javascript needed for a remote function. - # Takes the same arguments as link_to_remote. - # - # Example: - # - def remote_function(options) - javascript_options = options_for_ajax(options) - - update = '' - if options[:update] and options[:update].is_a?Hash - update = [] - update << "success:'#{options[:update][:success]}'" if options[:update][:success] - update << "failure:'#{options[:update][:failure]}'" if options[:update][:failure] - update = '{' + update.join(',') + '}' - elsif options[:update] - update << "'#{options[:update]}'" - end - - function = update.empty? ? - "new Ajax.Request(" : - "new Ajax.Updater(#{update}, " - - function << "'#{url_for(options[:url])}'" - function << ", #{javascript_options})" - - function = "#{options[:before]}; #{function}" if options[:before] - function = "#{function}; #{options[:after]}" if options[:after] - function = "if (#{options[:condition]}) { #{function}; }" if options[:condition] - function = "if (confirm('#{escape_javascript(options[:confirm])}')) { #{function}; }" if options[:confirm] - - return function - end - - # Includes the Action Pack JavaScript libraries inside a single ' - end - - # Observes the field with the DOM ID specified by +field_id+ and makes - # an AJAX call when its contents have changed. - # - # Required +options+ are: - # :url:: +url_for+-style options for the action to call - # when the field has changed. - # - # Additional options are: - # :frequency:: The frequency (in seconds) at which changes to - # this field will be detected. Not setting this - # option at all or to a value equal to or less than - # zero will use event based observation instead of - # time based observation. - # :update:: Specifies the DOM ID of the element whose - # innerHTML should be updated with the - # XMLHttpRequest response text. - # :with:: A JavaScript expression specifying the - # parameters for the XMLHttpRequest. This defaults - # to 'value', which in the evaluated context - # refers to the new field value. - # - # Additionally, you may specify any of the options documented in - # link_to_remote. - def observe_field(field_id, options = {}) - if options[:frequency] and options[:frequency] > 0 - build_observer('Form.Element.Observer', field_id, options) - else - build_observer('Form.Element.EventObserver', field_id, options) - end - end - - # Like +observe_field+, but operates on an entire form identified by the - # DOM ID +form_id+. +options+ are the same as +observe_field+, except - # the default value of the :with option evaluates to the - # serialized (request string) value of the form. - def observe_form(form_id, options = {}) - if options[:frequency] - build_observer('Form.Observer', form_id, options) - else - build_observer('Form.EventObserver', form_id, options) - end - end - - # Returns a JavaScript snippet to be used on the AJAX callbacks for starting - # visual effects. - # - # This method requires the inclusion of the script.aculo.us JavaScript library. - # - # Example: - # <%= link_to_remote "Reload", :update => "posts", - # :url => { :action => "reload" }, - # :complete => visual_effect(:highlight, "posts", :duration => 0.5 ) - # - # If no element_id is given, it assumes "element" which should be a local - # variable in the generated JavaScript execution context. This can be used - # for example with drop_receiving_element: - # - # <%= drop_receving_element (...), :loading => visual_effect(:fade) %> - # - # This would fade the element that was dropped on the drop receiving element. - # - # You can change the behaviour with various options, see - # http://script.aculo.us for more documentation. - def visual_effect(name, element_id = false, js_options = {}) - element = element_id ? "'#{element_id}'" : "element" - js_options[:queue] = "'#{js_options[:queue]}'" if js_options[:queue] - "new Effect.#{name.to_s.camelize}(#{element},#{options_for_javascript(js_options)});" - end - - # Makes the element with the DOM ID specified by +element_id+ sortable - # by drag-and-drop and make an AJAX call whenever the sort order has - # changed. By default, the action called gets the serialized sortable - # element as parameters. - # - # This method requires the inclusion of the script.aculo.us JavaScript library. - # - # Example: - # <%= sortable_element("my_list", :url => { :action => "order" }) %> - # - # In the example, the action gets a "my_list" array parameter - # containing the values of the ids of elements the sortable consists - # of, in the current order. - # - # You can change the behaviour with various options, see - # http://script.aculo.us for more documentation. - def sortable_element(element_id, options = {}) - options[:with] ||= "Sortable.serialize('#{element_id}')" - options[:onUpdate] ||= "function(){" + remote_function(options) + "}" - options.delete_if { |key, value| AJAX_OPTIONS.include?(key) } - - [:tag, :overlap, :constraint, :handle].each do |option| - options[option] = "'#{options[option]}'" if options[option] - end - - options[:containment] = array_or_string_for_javascript(options[:containment]) if options[:containment] - options[:only] = array_or_string_for_javascript(options[:only]) if options[:only] - - javascript_tag("Sortable.create('#{element_id}', #{options_for_javascript(options)})") - end - - # Makes the element with the DOM ID specified by +element_id+ draggable. - # - # This method requires the inclusion of the script.aculo.us JavaScript library. - # - # Example: - # <%= draggable_element("my_image", :revert => true) - # - # You can change the behaviour with various options, see - # http://script.aculo.us for more documentation. - def draggable_element(element_id, options = {}) - javascript_tag("new Draggable('#{element_id}', #{options_for_javascript(options)})") - end - - # Makes the element with the DOM ID specified by +element_id+ receive - # dropped draggable elements (created by draggable_element). - # and make an AJAX call By default, the action called gets the DOM ID of the - # element as parameter. - # - # This method requires the inclusion of the script.aculo.us JavaScript library. - # - # Example: - # <%= drop_receiving_element("my_cart", :url => { :controller => "cart", :action => "add" }) %> - # - # You can change the behaviour with various options, see - # http://script.aculo.us for more documentation. - def drop_receiving_element(element_id, options = {}) - options[:with] ||= "'id=' + encodeURIComponent(element.id)" - options[:onDrop] ||= "function(element){" + remote_function(options) + "}" - options.delete_if { |key, value| AJAX_OPTIONS.include?(key) } - - options[:accept] = array_or_string_for_javascript(options[:accept]) if options[:accept] - options[:hoverclass] = "'#{options[:hoverclass]}'" if options[:hoverclass] - - javascript_tag("Droppables.add('#{element_id}', #{options_for_javascript(options)})") - end - - # Escape carrier returns and single and double quotes for JavaScript segments. - def escape_javascript(javascript) - (javascript || '').gsub(/\r\n|\n|\r/, "\\n").gsub(/["']/) { |m| "\\#{m}" } - end - - # Returns a JavaScript tag with the +content+ inside. Example: - # javascript_tag "alert('All is good')" # => - def javascript_tag(content) - content_tag("script", javascript_cdata_section(content), :type => "text/javascript") - end - - def javascript_cdata_section(content) #:nodoc: - "\n//#{cdata_section("\n#{content}\n//")}\n" - end - - private - def options_for_javascript(options) - '{' + options.map {|k, v| "#{k}:#{v}"}.sort.join(', ') + '}' - end - - def array_or_string_for_javascript(option) - js_option = if option.kind_of?(Array) - "['#{option.join('\',\'')}']" - elsif !option.nil? - "'#{option}'" - end - js_option - end - - def options_for_ajax(options) - js_options = build_callbacks(options) - - js_options['asynchronous'] = options[:type] != :synchronous - js_options['method'] = method_option_to_s(options[:method]) if options[:method] - js_options['insertion'] = "Insertion.#{options[:position].to_s.camelize}" if options[:position] - js_options['evalScripts'] = options[:script].nil? || options[:script] - - if options[:form] - js_options['parameters'] = 'Form.serialize(this)' - elsif options[:submit] - js_options['parameters'] = "Form.serialize(document.getElementById('#{options[:submit]}'))" - elsif options[:with] - js_options['parameters'] = options[:with] - end - - options_for_javascript(js_options) - end - - def method_option_to_s(method) - (method.is_a?(String) and !method.index("'").nil?) ? method : "'#{method}'" - end - - def build_observer(klass, name, options = {}) - options[:with] ||= 'value' if options[:update] - callback = remote_function(options) - javascript = "new #{klass}('#{name}', " - javascript << "#{options[:frequency]}, " if options[:frequency] - javascript << "function(element, value) {" - javascript << "#{callback}})" - javascript_tag(javascript) - end - - def build_callbacks(options) - callbacks = {} - options.each do |callback, code| - if CALLBACKS.include?(callback) - name = 'on' + callback.to_s.capitalize - callbacks[name] = "function(request){#{code}}" - end - end - callbacks - end - - end - - JavascriptHelper = JavaScriptHelper unless const_defined? :JavascriptHelper - end -end diff --git a/tracks/vendor/rails/actionpack/lib/action_view/helpers/javascripts/controls.js b/tracks/vendor/rails/actionpack/lib/action_view/helpers/javascripts/controls.js deleted file mode 100644 index 9742b691..00000000 --- a/tracks/vendor/rails/actionpack/lib/action_view/helpers/javascripts/controls.js +++ /dev/null @@ -1,750 +0,0 @@ -// Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) -// (c) 2005 Ivan Krstic (http://blogs.law.harvard.edu/ivan) -// (c) 2005 Jon Tirsen (http://www.tirsen.com) -// Contributors: -// Richard Livsey -// Rahul Bhargava -// Rob Wills -// -// See scriptaculous.js for full license. - -// 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. - -var Autocompleter = {} -Autocompleter.Base = function() {}; -Autocompleter.Base.prototype = { - baseInitialize: function(element, update, options) { - this.element = $(element); - this.update = $(update); - this.hasFocus = false; - this.changed = false; - this.active = false; - this.index = 0; - this.entryCount = 0; - - 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); - - 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 && - (navigator.appVersion.indexOf('MSIE')>0) && - (navigator.userAgent.indexOf('Opera')<0) && - (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); - 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(navigator.appVersion.indexOf('AppleWebKit')>0) Event.stop(event); - return; - case Event.KEY_DOWN: - this.markNext(); - this.render(); - if(navigator.appVersion.indexOf('AppleWebKit')>0) Event.stop(event); - return; - } - else - if(event.keyCode==Event.KEY_TAB || event.keyCode==Event.KEY_RETURN) - return; - - this.changed = true; - this.hasFocus = true; - - if(this.observer) clearTimeout(this.observer); - this.observer = - setTimeout(this.onObserverEvent.bind(this), this.options.frequency*1000); - }, - - 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; - }, - - markNext: function() { - if(this.index < this.entryCount-1) this.index++ - else this.index = 0; - }, - - 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 = Element.collectTextNodesIgnoreClass(selectedElement, 'informal'); - var lastTokenPos = this.findLastToken(); - if (lastTokenPos != -1) { - var newValue = this.element.value.substr(0, lastTokenPos + 1); - var whitespace = this.element.value.substr(lastTokenPos + 1).match(/^\s+/); - if (whitespace) - newValue += whitespace[0]; - this.element.value = newValue + value; - } else { - this.element.value = 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.firstChild); - - if(this.update.firstChild && this.update.firstChild.childNodes) { - this.entryCount = - this.update.firstChild.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; - 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; - if(this.getToken().length>=this.options.minChars) { - this.startIndicator(); - this.getUpdatedChoices(); - } else { - this.active = false; - this.hide(); - } - }, - - getToken: function() { - var tokenPos = this.findLastToken(); - if (tokenPos != -1) - var ret = this.element.value.substr(tokenPos + 1).replace(/^\s+/,'').replace(/\s+$/,''); - else - var ret = this.element.value; - - return /\n/.test(ret) ? '' : ret; - }, - - findLastToken: function() { - var lastTokenPos = -1; - - for (var i=0; i lastTokenPos) - lastTokenPos = thisTokenPos; - } - return lastTokenPos; - } -} - -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() { - 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 -// -// see documentation on http://wiki.script.aculo.us/scriptaculous/show/Ajax.InPlaceEditor - -// 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(); -Ajax.InPlaceEditor.defaultHighlightColor = "#FFFF99"; -Ajax.InPlaceEditor.prototype = { - initialize: function(element, url, options) { - this.url = url; - this.element = $(element); - - this.options = Object.extend({ - okText: "ok", - cancelText: "cancel", - savingText: "Saving...", - clickToEditText: "Click to edit", - okText: "ok", - rows: 1, - onComplete: function(transport, element) { - new Effect.Highlight(element, {startcolor: this.options.highlightcolor}); - }, - onFailure: function(transport) { - alert("Error communicating with the server: " + transport.responseText.stripTags()); - }, - callback: function(form) { - return Form.serialize(form); - }, - handleLineBreaks: true, - loadingText: 'Loading...', - savingClassName: 'inplaceeditor-saving', - loadingClassName: 'inplaceeditor-loading', - formClassName: 'inplaceeditor-form', - highlightcolor: Ajax.InPlaceEditor.defaultHighlightColor, - highlightendcolor: "#FFFFFF", - externalControl: null, - ajaxOptions: {} - }, options || {}); - - if(!this.options.formId && this.element.id) { - this.options.formId = this.element.id + "-inplaceeditor"; - if ($(this.options.formId)) { - // there's already a form with that name, don't specify an id - this.options.formId = null; - } - } - - if (this.options.externalControl) { - this.options.externalControl = $(this.options.externalControl); - } - - this.originalBackground = Element.getStyle(this.element, 'background-color'); - if (!this.originalBackground) { - this.originalBackground = "transparent"; - } - - this.element.title = this.options.clickToEditText; - - this.onclickListener = this.enterEditMode.bindAsEventListener(this); - this.mouseoverListener = this.enterHover.bindAsEventListener(this); - this.mouseoutListener = this.leaveHover.bindAsEventListener(this); - Event.observe(this.element, 'click', this.onclickListener); - Event.observe(this.element, 'mouseover', this.mouseoverListener); - Event.observe(this.element, 'mouseout', this.mouseoutListener); - if (this.options.externalControl) { - Event.observe(this.options.externalControl, 'click', this.onclickListener); - Event.observe(this.options.externalControl, 'mouseover', this.mouseoverListener); - Event.observe(this.options.externalControl, 'mouseout', this.mouseoutListener); - } - }, - enterEditMode: function(evt) { - if (this.saving) return; - if (this.editing) return; - this.editing = true; - this.onEnterEditMode(); - if (this.options.externalControl) { - Element.hide(this.options.externalControl); - } - Element.hide(this.element); - this.createForm(); - this.element.parentNode.insertBefore(this.form, this.element); - Field.scrollFreeActivate(this.editField); - // stop the event to avoid a page refresh in Safari - if (evt) { - Event.stop(evt); - } - return false; - }, - createForm: function() { - this.form = document.createElement("form"); - this.form.id = this.options.formId; - Element.addClassName(this.form, this.options.formClassName) - this.form.onsubmit = this.onSubmit.bind(this); - - this.createEditField(); - - if (this.options.textarea) { - var br = document.createElement("br"); - this.form.appendChild(br); - } - - okButton = document.createElement("input"); - okButton.type = "submit"; - okButton.value = this.options.okText; - this.form.appendChild(okButton); - - cancelLink = document.createElement("a"); - cancelLink.href = "#"; - cancelLink.appendChild(document.createTextNode(this.options.cancelText)); - cancelLink.onclick = this.onclickCancel.bind(this); - this.form.appendChild(cancelLink); - }, - hasHTMLLineBreaks: function(string) { - if (!this.options.handleLineBreaks) return false; - return string.match(/
    /i); - }, - convertHTMLLineBreaks: function(string) { - return string.replace(/
    /gi, "\n").replace(//gi, "\n").replace(/<\/p>/gi, "\n").replace(/

    /gi, ""); - }, - createEditField: function() { - var text; - if(this.options.loadTextURL) { - text = this.options.loadingText; - } else { - text = this.getText(); - } - - if (this.options.rows == 1 && !this.hasHTMLLineBreaks(text)) { - this.options.textarea = false; - var textField = document.createElement("input"); - textField.type = "text"; - textField.name = "value"; - textField.value = text; - textField.style.backgroundColor = this.options.highlightcolor; - var size = this.options.size || this.options.cols || 0; - if (size != 0) textField.size = size; - this.editField = textField; - } else { - this.options.textarea = true; - var textArea = document.createElement("textarea"); - textArea.name = "value"; - textArea.value = this.convertHTMLLineBreaks(text); - textArea.rows = this.options.rows; - textArea.cols = this.options.cols || 40; - this.editField = textArea; - } - - if(this.options.loadTextURL) { - this.loadExternalText(); - } - this.form.appendChild(this.editField); - }, - getText: function() { - return this.element.innerHTML; - }, - loadExternalText: function() { - Element.addClassName(this.form, this.options.loadingClassName); - this.editField.disabled = true; - new Ajax.Request( - this.options.loadTextURL, - Object.extend({ - asynchronous: true, - onComplete: this.onLoadedExternalText.bind(this) - }, this.options.ajaxOptions) - ); - }, - onLoadedExternalText: function(transport) { - Element.removeClassName(this.form, this.options.loadingClassName); - this.editField.disabled = false; - this.editField.value = transport.responseText.stripTags(); - }, - onclickCancel: function() { - this.onComplete(); - this.leaveEditMode(); - return false; - }, - onFailure: function(transport) { - this.options.onFailure(transport); - if (this.oldInnerHTML) { - this.element.innerHTML = this.oldInnerHTML; - this.oldInnerHTML = null; - } - return false; - }, - onSubmit: function() { - // onLoading resets these so we need to save them away for the Ajax call - var form = this.form; - var value = this.editField.value; - - // do this first, sometimes the ajax call returns before we get a chance to switch on Saving... - // which means this will actually switch on Saving... *after* we've left edit mode causing Saving... - // to be displayed indefinitely - this.onLoading(); - - new Ajax.Updater( - { - success: this.element, - // don't update on failure (this could be an option) - failure: null - }, - this.url, - Object.extend({ - parameters: this.options.callback(form, value), - onComplete: this.onComplete.bind(this), - onFailure: this.onFailure.bind(this) - }, this.options.ajaxOptions) - ); - // stop the event to avoid a page refresh in Safari - if (arguments.length > 1) { - Event.stop(arguments[0]); - } - return false; - }, - onLoading: function() { - this.saving = true; - this.removeForm(); - this.leaveHover(); - this.showSaving(); - }, - showSaving: function() { - this.oldInnerHTML = this.element.innerHTML; - this.element.innerHTML = this.options.savingText; - Element.addClassName(this.element, this.options.savingClassName); - this.element.style.backgroundColor = this.originalBackground; - Element.show(this.element); - }, - removeForm: function() { - if(this.form) { - if (this.form.parentNode) Element.remove(this.form); - this.form = null; - } - }, - enterHover: function() { - if (this.saving) return; - this.element.style.backgroundColor = this.options.highlightcolor; - if (this.effect) { - this.effect.cancel(); - } - Element.addClassName(this.element, this.options.hoverClassName) - }, - leaveHover: function() { - if (this.options.backgroundColor) { - this.element.style.backgroundColor = this.oldBackground; - } - Element.removeClassName(this.element, this.options.hoverClassName) - if (this.saving) return; - this.effect = new Effect.Highlight(this.element, { - startcolor: this.options.highlightcolor, - endcolor: this.options.highlightendcolor, - restorecolor: this.originalBackground - }); - }, - leaveEditMode: function() { - Element.removeClassName(this.element, this.options.savingClassName); - this.removeForm(); - this.leaveHover(); - this.element.style.backgroundColor = this.originalBackground; - Element.show(this.element); - if (this.options.externalControl) { - Element.show(this.options.externalControl); - } - this.editing = false; - this.saving = false; - this.oldInnerHTML = null; - this.onLeaveEditMode(); - }, - onComplete: function(transport) { - this.leaveEditMode(); - this.options.onComplete.bind(this)(transport, this.element); - }, - onEnterEditMode: function() {}, - onLeaveEditMode: function() {}, - dispose: function() { - if (this.oldInnerHTML) { - this.element.innerHTML = this.oldInnerHTML; - } - this.leaveEditMode(); - Event.stopObserving(this.element, 'click', this.onclickListener); - Event.stopObserving(this.element, 'mouseover', this.mouseoverListener); - Event.stopObserving(this.element, 'mouseout', this.mouseoutListener); - if (this.options.externalControl) { - Event.stopObserving(this.options.externalControl, 'click', this.onclickListener); - Event.stopObserving(this.options.externalControl, 'mouseover', this.mouseoverListener); - Event.stopObserving(this.options.externalControl, 'mouseout', this.mouseoutListener); - } - } -}; - -// 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)); - } -}; \ No newline at end of file diff --git a/tracks/vendor/rails/actionpack/lib/action_view/helpers/javascripts/dragdrop.js b/tracks/vendor/rails/actionpack/lib/action_view/helpers/javascripts/dragdrop.js deleted file mode 100644 index 92d1f731..00000000 --- a/tracks/vendor/rails/actionpack/lib/action_view/helpers/javascripts/dragdrop.js +++ /dev/null @@ -1,584 +0,0 @@ -// Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) -// -// See scriptaculous.js for full license. - -/*--------------------------------------------------------------------------*/ - -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 - }, arguments[1] || {}); - - // cache containers - if(options.containment) { - options._containers = []; - var containment = options.containment; - if((typeof containment == 'object') && - (containment.constructor == Array)) { - 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); - }, - - isContained: function(element, drop) { - var parentNode = element.parentNode; - return drop._containers.detect(function(c) { return parentNode == 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; - - if(this.last_active) this.deactivate(this.last_active); - this.drops.each( function(drop) { - if(Droppables.isAffected(point, element, drop)) { - if(drop.onHover) - drop.onHover(element, drop.element, Position.overlap(drop.overlap, drop.element)); - if(drop.greedy) { - Droppables.activate(drop); - throw $break; - } - } - }); - }, - - 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); - }, - - 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) { - window.focus(); // allows keypress events if window isn't currently focused, fails for Safari - this.activeDraggable = draggable; - }, - - deactivate: function(draggbale) { - 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.activeDraggable) return; - this._lastPointer = null; - this.activeDraggable.endDrag(event); - }, - - 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); - }); - }, - - _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.prototype = { - initialize: function(element) { - var options = Object.extend({ - handle: false, - starteffect: function(element) { - new Effect.Opacity(element, {duration:0.2, from:1.0, to:0.7}); - }, - reverteffect: function(element, top_offset, left_offset) { - var dur = Math.sqrt(Math.abs(top_offset^2)+Math.abs(left_offset^2))*0.02; - element._revert = new Effect.MoveBy(element, -top_offset, -left_offset, {duration:dur}); - }, - endeffect: function(element) { - new Effect.Opacity(element, {duration:0.2, from:0.7, to:1.0}); - }, - zindex: 1000, - revert: false, - snap: false // false, or xy or [x,y] or function(x,y){ return [x,y] } - }, arguments[1] || {}); - - this.element = $(element); - - if(options.handle && (typeof options.handle == 'string')) - this.handle = Element.childrenWithClassName(this.element, options.handle)[0]; - if(!this.handle) this.handle = $(options.handle); - if(!this.handle) this.handle = this.element; - - Element.makePositioned(this.element); // fix IE - - this.delta = this.currentDelta(); - 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(this.element.style.left || '0'), - parseInt(this.element.style.top || '0')]); - }, - - initDrag: function(event) { - if(Event.isLeftClick(event)) { - // abort on form elements, fixes a Firefox issue - var src = Event.element(event); - if(src.tagName && ( - src.tagName=='INPUT' || - src.tagName=='SELECT' || - src.tagName=='BUTTON' || - src.tagName=='TEXTAREA')) return; - - if(this.element._revert) { - this.element._revert.cancel(); - this.element._revert = null; - } - - 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.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); - Position.absolutize(this.element); - this.element.parentNode.insertBefore(this._clone, this.element); - } - - Draggables.notify('onStart', this, event); - if(this.options.starteffect) this.options.starteffect(this.element); - }, - - updateDrag: function(event, pointer) { - if(!this.dragging) this.startDrag(event); - Position.prepare(); - Droppables.show(pointer, this.element); - Draggables.notify('onDrag', this, event); - this.draw(pointer); - if(this.options.change) this.options.change(this); - - // fix AppleWebKit rendering - if(navigator.appVersion.indexOf('AppleWebKit')>0) window.scrollBy(0,0); - Event.stop(event); - }, - - finishDrag: function(event, success) { - this.dragging = false; - - if(this.options.ghosting) { - Position.relativize(this.element); - Element.remove(this._clone); - this._clone = null; - } - - if(success) Droppables.fire(event, this.element); - Draggables.notify('onEnd', this, event); - - var revert = this.options.revert; - if(revert && typeof revert == 'function') revert = revert(this.element); - - var d = this.currentDelta(); - if(revert && this.options.reverteffect) { - 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.finishDrag(event, true); - Event.stop(event); - }, - - draw: function(point) { - var pos = Position.cumulativeOffset(this.element); - var d = this.currentDelta(); - pos[0] -= d[0]; pos[1] -= d[1]; - - var p = [0,1].map(function(i){ return (point[i]-pos[i]-this.offset[i]) }.bind(this)); - - if(this.options.snap) { - if(typeof this.options.snap == 'function') { - p = this.options.snap(p[0],p[1]); - } else { - if(this.options.snap instanceof Array) { - p = p.map( function(v, i) { - return Math.round(v/this.options.snap[i])*this.options.snap[i] }.bind(this)) - } else { - p = p.map( function(v) { - return Math.round(v/this.options.snap)*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 - } -} - -/*--------------------------------------------------------------------------*/ - -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 = { - sortables: new Array(), - - options: function(element){ - element = $(element); - return this.sortables.detect(function(s) { return s.element == element }); - }, - - destroy: function(element){ - element = $(element); - this.sortables.findAll(function(s) { return s.element == element }).each(function(s){ - Draggables.removeObserver(s.element); - s.droppables.each(function(d){ Droppables.remove(d) }); - s.draggables.invoke('destroy'); - }); - this.sortables = this.sortables.reject(function(s) { return s.element == element }); - }, - - create: function(element) { - element = $(element); - var options = Object.extend({ - element: element, - tag: 'li', // assumes li children, override with tag: 'tagname' - dropOnEmpty: false, - tree: false, // fixme: unimplemented - 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, - hoverclass: null, - ghosting: false, - format: null, - 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, - 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, - hoverclass: options.hoverclass, - onHover: Sortable.onHover, - greedy: !options.dropOnEmpty - } - - // fix for gecko engine - Element.cleanWhitespace(element); - - options.draggables = []; - options.droppables = []; - - // make it so - - // drop on empty handling - if(options.dropOnEmpty) { - Droppables.add(element, - {containment: options.containment, onHover: Sortable.onEmptyHover, greedy: false}); - options.droppables.push(element); - } - - (this.findElements(element, options) || []).each( function(e) { - // handles are per-draggable - var handle = options.handle ? - Element.childrenWithClassName(e, options.handle)[0] : e; - options.draggables.push( - new Draggable(e, Object.extend(options_for_draggable, { handle: handle }))); - Droppables.add(e, options_for_droppable); - options.droppables.push(e); - }); - - // keep reference - this.sortables.push(options); - - // for onupdate - Draggables.addObserver(new SortableObserver(element, options.onUpdate)); - - }, - - // return all suitable-for-sortable elements in a guaranteed order - findElements: function(element, options) { - if(!element.hasChildNodes()) return null; - var elements = []; - $A(element.childNodes).each( function(e) { - if(e.tagName && e.tagName.toUpperCase()==options.tag.toUpperCase() && - (!options.only || (Element.hasClassName(e, options.only)))) - elements.push(e); - if(options.tree) { - var grandchildren = this.findElements(e, options); - if(grandchildren) elements.push(grandchildren); - } - }); - - return (elements.length>0 ? elements.flatten() : null); - }, - - onHover: function(element, dropon, overlap) { - 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) { - if(element.parentNode!=dropon) { - var oldParentNode = element.parentNode; - dropon.appendChild(element); - Sortable.options(oldParentNode).onChange(element); - Sortable.options(dropon).onChange(element); - } - }, - - unmark: function() { - if(Sortable._marker) Element.hide(Sortable._marker); - }, - - 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') || document.createElement('DIV'); - Element.hide(Sortable._marker); - Element.addClassName(Sortable._marker, 'dropmarker'); - Sortable._marker.style.position = 'absolute'; - document.getElementsByTagName("body").item(0).appendChild(Sortable._marker); - } - var offsets = Position.cumulativeOffset(dropon); - Sortable._marker.style.left = offsets[0] + 'px'; - Sortable._marker.style.top = offsets[1] + 'px'; - - if(position=='after') - if(sortable.overlap == 'horizontal') - Sortable._marker.style.left = (offsets[0]+dropon.clientWidth) + 'px'; - else - Sortable._marker.style.top = (offsets[1]+dropon.clientHeight) + 'px'; - - Element.show(Sortable._marker); - }, - - serialize: function(element) { - element = $(element); - var sortableOptions = this.options(element); - var options = Object.extend({ - tag: sortableOptions.tag, - only: sortableOptions.only, - name: element.id, - format: sortableOptions.format || /^[^_]*_(.*)$/ - }, arguments[1] || {}); - return $(this.findElements(element, options) || []).map( function(item) { - return (encodeURIComponent(options.name) + "[]=" + - encodeURIComponent(item.id.match(options.format) ? item.id.match(options.format)[1] : '')); - }).join("&"); - } -} \ No newline at end of file diff --git a/tracks/vendor/rails/actionpack/lib/action_view/helpers/javascripts/effects.js b/tracks/vendor/rails/actionpack/lib/action_view/helpers/javascripts/effects.js deleted file mode 100644 index 414398ce..00000000 --- a/tracks/vendor/rails/actionpack/lib/action_view/helpers/javascripts/effects.js +++ /dev/null @@ -1,854 +0,0 @@ -// Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) -// Contributors: -// Justin Palmer (http://encytemedia.com/) -// Mark Pilgrim (http://diveintomark.org/) -// Martin Bialasinki -// -// See scriptaculous.js for full license. - -/* ------------- element ext -------------- */ - -// 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.collectTextNodesIgnoreClass = function(element, ignoreclass) { - var children = $(element).childNodes; - var text = ''; - var classtest = new RegExp('^([^ ]+ )*' + ignoreclass+ '( [^ ]+)*$','i'); - - for (var i = 0; i < children.length; i++) { - if(children[i].nodeType==3) { - text+=children[i].nodeValue; - } else { - if((!children[i].className.match(classtest)) && children[i].hasChildNodes()) - text += Element.collectTextNodesIgnoreClass(children[i], ignoreclass); - } - } - - return text; -} - -Element.setStyle = function(element, style) { - element = $(element); - for(k in style) element.style[k.camelize()] = style[k]; -} - -Element.setContentZoom = function(element, percent) { - Element.setStyle(element, {fontSize: (percent/100) + 'em'}); - if(navigator.appVersion.indexOf('AppleWebKit')>0) window.scrollBy(0,0); -} - -Element.getOpacity = function(element){ - var opacity; - if (opacity = Element.getStyle(element, 'opacity')) - return parseFloat(opacity); - if (opacity = (Element.getStyle(element, 'filter') || '').match(/alpha\(opacity=(.*)\)/)) - if(opacity[1]) return parseFloat(opacity[1]) / 100; - return 1.0; -} - -Element.setOpacity = function(element, value){ - element= $(element); - if (value == 1){ - Element.setStyle(element, { opacity: - (/Gecko/.test(navigator.userAgent) && !/Konqueror|Safari|KHTML/.test(navigator.userAgent)) ? - 0.999999 : null }); - if(/MSIE/.test(navigator.userAgent)) - Element.setStyle(element, {filter: Element.getStyle(element,'filter').replace(/alpha\([^\)]*\)/gi,'')}); - } else { - if(value < 0.00001) value = 0; - Element.setStyle(element, {opacity: value}); - if(/MSIE/.test(navigator.userAgent)) - Element.setStyle(element, - { filter: Element.getStyle(element,'filter').replace(/alpha\([^\)]*\)/gi,'') + - 'alpha(opacity='+value*100+')' }); - } -} - -Element.getInlineOpacity = function(element){ - return $(element).style.opacity || ''; -} - -Element.childrenWithClassName = function(element, className) { - return $A($(element).getElementsByTagName('*')).select( - function(c) { return Element.hasClassName(c, className) }); -} - -Array.prototype.call = function() { - var args = arguments; - this.each(function(f){ f.apply(this, args) }); -} - -/*--------------------------------------------------------------------------*/ - -var Effect = { - tagifyText: function(element) { - var tagifyStyle = 'position:relative'; - if(/MSIE/.test(navigator.userAgent)) tagifyStyle += ';zoom:1'; - element = $(element); - $A(element.childNodes).each( function(child) { - if(child.nodeType==3) { - child.nodeValue.toArray().each( function(character) { - element.insertBefore( - Builder.node('span',{style: tagifyStyle}, - character == ' ' ? String.fromCharCode(160) : character), - child); - }); - Element.remove(child); - } - }); - }, - multiple: function(element, effect) { - var elements; - if(((typeof element == 'object') || - (typeof element == 'function')) && - (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 })); - }); - } -}; - -var Effect2 = Effect; // deprecated - -/* ------------- transitions ------------- */ - -Effect.Transitions = {} - -Effect.Transitions.linear = function(pos) { - return pos; -} -Effect.Transitions.sinoidal = function(pos) { - return (-Math.cos(pos*Math.PI)/2) + 0.5; -} -Effect.Transitions.reverse = function(pos) { - return 1-pos; -} -Effect.Transitions.flicker = function(pos) { - return ((-Math.cos(pos*Math.PI)/4) + 0.75) + Math.random()/4; -} -Effect.Transitions.wobble = function(pos) { - return (-Math.cos(pos*Math.PI*(9*pos))/2) + 0.5; -} -Effect.Transitions.pulse = function(pos) { - return (Math.floor(pos*10) % 2 == 0 ? - (pos*10-Math.floor(pos*10)) : 1-(pos*10-Math.floor(pos*10))); -} -Effect.Transitions.none = function(pos) { - return 0; -} -Effect.Transitions.full = function(pos) { - return 1; -} - -/* ------------- core effects ------------- */ - -Effect.Queue = { - effects: [], - _each: function(iterator) { - this.effects._each(iterator); - }, - interval: null, - add: function(effect) { - var timestamp = new Date().getTime(); - - switch(effect.options.queue) { - 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 'end': - // start effect after last queued effect has finished - timestamp = this.effects.pluck('finishOn').max() || timestamp; - break; - } - - effect.startOn += timestamp; - effect.finishOn += timestamp; - this.effects.push(effect); - if(!this.interval) - this.interval = setInterval(this.loop.bind(this), 40); - }, - 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(); - this.effects.invoke('loop', timePos); - } -} -Object.extend(Effect.Queue, Enumerable); - -Effect.Base = function() {}; -Effect.Base.prototype = { - position: null, - setOptions: function(options) { - this.options = Object.extend({ - transition: Effect.Transitions.sinoidal, - duration: 1.0, // seconds - fps: 25.0, // max. 25fps due to Effect.Queue implementation - sync: false, // true for combining - from: 0.0, - to: 1.0, - delay: 0.0, - queue: 'parallel' - }, options || {}); - }, - start: function(options) { - this.setOptions(options || {}); - this.currentFrame = 0; - this.state = 'idle'; - this.startOn = this.options.delay*1000; - this.finishOn = this.startOn + (this.options.duration*1000); - this.event('beforeStart'); - if(!this.options.sync) Effect.Queue.add(this); - }, - loop: function(timePos) { - if(timePos >= 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.finishOn - this.startOn); - var frame = Math.round(pos * this.options.fps * this.options.duration); - if(frame > this.currentFrame) { - this.render(pos); - this.currentFrame = frame; - } - } - }, - render: function(pos) { - if(this.state == 'idle') { - this.state = 'running'; - this.event('beforeSetup'); - if(this.setup) this.setup(); - this.event('afterSetup'); - } - if(this.state == 'running') { - if(this.options.transition) pos = this.options.transition(pos); - pos *= (this.options.to-this.options.from); - pos += this.options.from; - this.position = pos; - this.event('beforeUpdate'); - if(this.update) this.update(pos); - this.event('afterUpdate'); - } - }, - cancel: function() { - if(!this.options.sync) Effect.Queue.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() { - return '#'; - } -} - -Effect.Parallel = Class.create(); -Object.extend(Object.extend(Effect.Parallel.prototype, Effect.Base.prototype), { - 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.Opacity = Class.create(); -Object.extend(Object.extend(Effect.Opacity.prototype, Effect.Base.prototype), { - initialize: function(element) { - this.element = $(element); - // make this work on IE on elements without 'layout' - if(/MSIE/.test(navigator.userAgent) && (!this.element.hasLayout)) - Element.setStyle(this.element, {zoom: 1}); - var options = Object.extend({ - from: Element.getOpacity(this.element) || 0.0, - to: 1.0 - }, arguments[1] || {}); - this.start(options); - }, - update: function(position) { - Element.setOpacity(this.element, position); - } -}); - -Effect.MoveBy = Class.create(); -Object.extend(Object.extend(Effect.MoveBy.prototype, Effect.Base.prototype), { - initialize: function(element, toTop, toLeft) { - this.element = $(element); - this.toTop = toTop; - this.toLeft = toLeft; - this.start(arguments[3]); - }, - setup: function() { - // Bug in Opera: Opera returns the "real" position of a static element or - // relative element that does not have top/left explicitly set. - // ==> Always set top and left for position relative elements in your stylesheets - // (to 0 if you do not need them) - Element.makePositioned(this.element); - this.originalTop = parseFloat(Element.getStyle(this.element,'top') || '0'); - this.originalLeft = parseFloat(Element.getStyle(this.element,'left') || '0'); - }, - update: function(position) { - Element.setStyle(this.element, { - top: this.toTop * position + this.originalTop + 'px', - left: this.toLeft * position + this.originalLeft + 'px' - }); - } -}); - -Effect.Scale = Class.create(); -Object.extend(Object.extend(Effect.Scale.prototype, Effect.Base.prototype), { - initialize: function(element, percent) { - this.element = $(element) - 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 = Element.getStyle(this.element,'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 = Element.getStyle(this.element,'font-size') || '100%'; - ['em','px','%'].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) - Element.setStyle(this.element, {fontSize: this.fontSize * currentScale + this.fontSizeType }); - this.setDimensions(this.dims[0] * currentScale, this.dims[1] * currentScale); - }, - finish: function(position) { - if (this.restoreAfterFinish) Element.setStyle(this.element, this.originalStyle); - }, - setDimensions: function(height, width) { - var d = {}; - if(this.options.scaleX) d.width = width + 'px'; - if(this.options.scaleY) d.height = height + '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'; - } - } - Element.setStyle(this.element, d); - } -}); - -Effect.Highlight = Class.create(); -Object.extend(Object.extend(Effect.Highlight.prototype, Effect.Base.prototype), { - initialize: function(element) { - this.element = $(element); - var options = Object.extend({ startcolor: '#ffff99' }, arguments[1] || {}); - this.start(options); - }, - setup: function() { - // Prevent executing on elements not in the layout flow - if(Element.getStyle(this.element, 'display')=='none') { this.cancel(); return; } - // Disable background image during the effect - this.oldStyle = { - backgroundImage: Element.getStyle(this.element, 'background-image') }; - Element.setStyle(this.element, {backgroundImage: 'none'}); - if(!this.options.endcolor) - this.options.endcolor = Element.getStyle(this.element, 'background-color').parseColor('#ffffff'); - if(!this.options.restorecolor) - this.options.restorecolor = Element.getStyle(this.element, '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) { - Element.setStyle(this.element,{backgroundColor: $R(0,2).inject('#',function(m,v,i){ - return m+(Math.round(this._base[i]+(this._delta[i]*position)).toColorPart()); }.bind(this)) }); - }, - finish: function() { - Element.setStyle(this.element, Object.extend(this.oldStyle, { - backgroundColor: this.options.restorecolor - })); - } -}); - -Effect.ScrollTo = Class.create(); -Object.extend(Object.extend(Effect.ScrollTo.prototype, Effect.Base.prototype), { - initialize: function(element) { - this.element = $(element); - this.start(arguments[1] || {}); - }, - setup: function() { - Position.prepare(); - var offsets = Position.cumulativeOffset(this.element); - if(this.options.offset) offsets[1] += this.options.offset; - var max = window.innerHeight ? - window.height - window.innerHeight : - document.body.scrollHeight - - (document.documentElement.clientHeight ? - document.documentElement.clientHeight : document.body.clientHeight); - this.scrollStart = Position.deltaY; - this.delta = (offsets[1] > max ? max : offsets[1]) - this.scrollStart; - }, - update: function(position) { - Position.prepare(); - window.scrollTo(Position.deltaX, - this.scrollStart + (position*this.delta)); - } -}); - -/* ------------- combination effects ------------- */ - -Effect.Fade = function(element) { - var oldOpacity = Element.getInlineOpacity(element); - var options = Object.extend({ - from: Element.getOpacity(element) || 1.0, - to: 0.0, - afterFinishInternal: function(effect) { with(Element) { - if(effect.options.to!=0) return; - hide(effect.element); - setStyle(effect.element, {opacity: oldOpacity}); }} - }, arguments[1] || {}); - return new Effect.Opacity(element,options); -} - -Effect.Appear = function(element) { - var options = Object.extend({ - from: (Element.getStyle(element, 'display') == 'none' ? 0.0 : Element.getOpacity(element) || 0.0), - to: 1.0, - beforeSetup: function(effect) { with(Element) { - setOpacity(effect.element, effect.options.from); - show(effect.element); }} - }, arguments[1] || {}); - return new Effect.Opacity(element,options); -} - -Effect.Puff = function(element) { - element = $(element); - var oldStyle = { opacity: Element.getInlineOpacity(element), position: Element.getStyle(element, 'position') }; - 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) { with(Element) { - setStyle(effect.effects[0].element, {position: 'absolute'}); }}, - afterFinishInternal: function(effect) { with(Element) { - hide(effect.effects[0].element); - setStyle(effect.effects[0].element, oldStyle); }} - }, arguments[1] || {}) - ); -} - -Effect.BlindUp = function(element) { - element = $(element); - Element.makeClipping(element); - return new Effect.Scale(element, 0, - Object.extend({ scaleContent: false, - scaleX: false, - restoreAfterFinish: true, - afterFinishInternal: function(effect) { with(Element) { - [hide, undoClipping].call(effect.element); }} - }, arguments[1] || {}) - ); -} - -Effect.BlindDown = function(element) { - element = $(element); - var oldHeight = Element.getStyle(element, 'height'); - var elementDimensions = Element.getDimensions(element); - 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) { with(Element) { - makeClipping(effect.element); - setStyle(effect.element, {height: '0px'}); - show(effect.element); - }}, - afterFinishInternal: function(effect) { with(Element) { - undoClipping(effect.element); - setStyle(effect.element, {height: oldHeight}); - }} - }, arguments[1] || {}) - ); -} - -Effect.SwitchOff = function(element) { - element = $(element); - var oldOpacity = Element.getInlineOpacity(element); - return new Effect.Appear(element, { - 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) { with(Element) { - [makePositioned,makeClipping].call(effect.element); - }}, - afterFinishInternal: function(effect) { with(Element) { - [hide,undoClipping,undoPositioned].call(effect.element); - setStyle(effect.element, {opacity: oldOpacity}); - }} - }) - } - }); -} - -Effect.DropOut = function(element) { - element = $(element); - var oldStyle = { - top: Element.getStyle(element, 'top'), - left: Element.getStyle(element, 'left'), - opacity: Element.getInlineOpacity(element) }; - return new Effect.Parallel( - [ new Effect.MoveBy(element, 100, 0, { sync: true }), - new Effect.Opacity(element, { sync: true, to: 0.0 }) ], - Object.extend( - { duration: 0.5, - beforeSetup: function(effect) { with(Element) { - makePositioned(effect.effects[0].element); }}, - afterFinishInternal: function(effect) { with(Element) { - [hide, undoPositioned].call(effect.effects[0].element); - setStyle(effect.effects[0].element, oldStyle); }} - }, arguments[1] || {})); -} - -Effect.Shake = function(element) { - element = $(element); - var oldStyle = { - top: Element.getStyle(element, 'top'), - left: Element.getStyle(element, 'left') }; - return new Effect.MoveBy(element, 0, 20, - { duration: 0.05, afterFinishInternal: function(effect) { - new Effect.MoveBy(effect.element, 0, -40, - { duration: 0.1, afterFinishInternal: function(effect) { - new Effect.MoveBy(effect.element, 0, 40, - { duration: 0.1, afterFinishInternal: function(effect) { - new Effect.MoveBy(effect.element, 0, -40, - { duration: 0.1, afterFinishInternal: function(effect) { - new Effect.MoveBy(effect.element, 0, 40, - { duration: 0.1, afterFinishInternal: function(effect) { - new Effect.MoveBy(effect.element, 0, -20, - { duration: 0.05, afterFinishInternal: function(effect) { with(Element) { - undoPositioned(effect.element); - setStyle(effect.element, oldStyle); - }}}) }}) }}) }}) }}) }}); -} - -Effect.SlideDown = function(element) { - element = $(element); - Element.cleanWhitespace(element); - // SlideDown need to have the content of the element wrapped in a container element with fixed height! - var oldInnerBottom = Element.getStyle(element.firstChild, 'bottom'); - var elementDimensions = Element.getDimensions(element); - 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) { with(Element) { - makePositioned(effect.element); - makePositioned(effect.element.firstChild); - if(window.opera) setStyle(effect.element, {top: ''}); - makeClipping(effect.element); - setStyle(effect.element, {height: '0px'}); - show(element); }}, - afterUpdateInternal: function(effect) { with(Element) { - setStyle(effect.element.firstChild, {bottom: - (effect.dims[0] - effect.element.clientHeight) + 'px' }); }}, - afterFinishInternal: function(effect) { with(Element) { - undoClipping(effect.element); - undoPositioned(effect.element.firstChild); - undoPositioned(effect.element); - setStyle(effect.element.firstChild, {bottom: oldInnerBottom}); }} - }, arguments[1] || {}) - ); -} - -Effect.SlideUp = function(element) { - element = $(element); - Element.cleanWhitespace(element); - var oldInnerBottom = Element.getStyle(element.firstChild, 'bottom'); - return new Effect.Scale(element, 0, - Object.extend({ scaleContent: false, - scaleX: false, - scaleMode: 'box', - scaleFrom: 100, - restoreAfterFinish: true, - beforeStartInternal: function(effect) { with(Element) { - makePositioned(effect.element); - makePositioned(effect.element.firstChild); - if(window.opera) setStyle(effect.element, {top: ''}); - makeClipping(effect.element); - show(element); }}, - afterUpdateInternal: function(effect) { with(Element) { - setStyle(effect.element.firstChild, {bottom: - (effect.dims[0] - effect.element.clientHeight) + 'px' }); }}, - afterFinishInternal: function(effect) { with(Element) { - [hide, undoClipping].call(effect.element); - undoPositioned(effect.element.firstChild); - undoPositioned(effect.element); - setStyle(effect.element.firstChild, {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) { with(Element) { - makeClipping(effect.element); }}, - afterFinishInternal: function(effect) { with(Element) { - hide(effect.element); - undoClipping(effect.element); }} - }); -} - -Effect.Grow = function(element) { - element = $(element); - var options = Object.extend({ - direction: 'center', - moveTransistion: 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(element) }; - - var dims = Element.getDimensions(element); - 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.MoveBy(element, initialMoveY, initialMoveX, { - duration: 0.01, - beforeSetup: function(effect) { with(Element) { - hide(effect.element); - makeClipping(effect.element); - makePositioned(effect.element); - }}, - afterFinishInternal: function(effect) { - new Effect.Parallel( - [ new Effect.Opacity(effect.element, { sync: true, to: 1.0, from: 0.0, transition: options.opacityTransition }), - new Effect.MoveBy(effect.element, moveY, moveX, { 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) { with(Element) { - setStyle(effect.effects[0].element, {height: '0px'}); - show(effect.effects[0].element); }}, - afterFinishInternal: function(effect) { with(Element) { - [undoClipping, undoPositioned].call(effect.effects[0].element); - setStyle(effect.effects[0].element, oldStyle); }} - }, options) - ) - } - }); -} - -Effect.Shrink = function(element) { - element = $(element); - var options = Object.extend({ - direction: 'center', - moveTransistion: 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(element) }; - - var dims = Element.getDimensions(element); - 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.MoveBy(element, moveY, moveX, { sync: true, transition: options.moveTransition }) - ], Object.extend({ - beforeStartInternal: function(effect) { with(Element) { - [makePositioned, makeClipping].call(effect.effects[0].element) }}, - afterFinishInternal: function(effect) { with(Element) { - [hide, undoClipping, undoPositioned].call(effect.effects[0].element); - setStyle(effect.effects[0].element, oldStyle); }} - }, options) - ); -} - -Effect.Pulsate = function(element) { - element = $(element); - var options = arguments[1] || {}; - var oldOpacity = Element.getInlineOpacity(element); - var transition = options.transition || Effect.Transitions.sinoidal; - var reverser = function(pos){ return transition(1-Effect.Transitions.pulse(pos)) }; - reverser.bind(transition); - return new Effect.Opacity(element, - Object.extend(Object.extend({ duration: 3.0, from: 0, - afterFinishInternal: function(effect) { Element.setStyle(effect.element, {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(element); - 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) { with(Element) { - [hide, undoClipping].call(effect.element); - setStyle(effect.element, oldStyle); - }} }); - }}, arguments[1] || {})); -} diff --git a/tracks/vendor/rails/actionpack/lib/action_view/helpers/javascripts/prototype.js b/tracks/vendor/rails/actionpack/lib/action_view/helpers/javascripts/prototype.js deleted file mode 100644 index e9ccd3c8..00000000 --- a/tracks/vendor/rails/actionpack/lib/action_view/helpers/javascripts/prototype.js +++ /dev/null @@ -1,1785 +0,0 @@ -/* Prototype JavaScript framework, version 1.4.0 - * (c) 2005 Sam Stephenson - * - * THIS FILE IS AUTOMATICALLY GENERATED. When sending patches, please diff - * against the source tree, available from the Prototype darcs repository. - * - * Prototype is freely distributable under the terms of an MIT-style license. - * - * For details, see the Prototype web site: http://prototype.conio.net/ - * -/*--------------------------------------------------------------------------*/ - -var Prototype = { - Version: '1.4.0', - ScriptFragment: '(?:)((\n|\r|.)*?)(?:<\/script>)', - - emptyFunction: function() {}, - K: function(x) {return x} -} - -var Class = { - create: function() { - return function() { - this.initialize.apply(this, arguments); - } - } -} - -var Abstract = new Object(); - -Object.extend = function(destination, source) { - for (property in source) { - destination[property] = source[property]; - } - return destination; -} - -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; - } -} - -Function.prototype.bind = function() { - var __method = this, args = $A(arguments), object = args.shift(); - return function() { - return __method.apply(object, args.concat($A(arguments))); - } -} - -Function.prototype.bindAsEventListener = function(object) { - var __method = this; - return function(event) { - return __method.call(object, event || window.event); - } -} - -Object.extend(Number.prototype, { - toColorPart: function() { - var digits = this.toString(16); - if (this < 16) return '0' + digits; - return digits; - }, - - succ: function() { - return this + 1; - }, - - times: function(iterator) { - $R(0, this, true).each(iterator); - return this; - } -}); - -var Try = { - these: function() { - var returnValue; - - for (var i = 0; i < arguments.length; i++) { - var lambda = arguments[i]; - try { - returnValue = lambda(); - break; - } catch (e) {} - } - - return returnValue; - } -} - -/*--------------------------------------------------------------------------*/ - -var PeriodicalExecuter = Class.create(); -PeriodicalExecuter.prototype = { - initialize: function(callback, frequency) { - this.callback = callback; - this.frequency = frequency; - this.currentlyExecuting = false; - - this.registerCallback(); - }, - - registerCallback: function() { - setInterval(this.onTimerEvent.bind(this), this.frequency * 1000); - }, - - onTimerEvent: function() { - if (!this.currentlyExecuting) { - try { - this.currentlyExecuting = true; - this.callback(); - } finally { - this.currentlyExecuting = false; - } - } - } -} - -/*--------------------------------------------------------------------------*/ - -function $() { - var elements = new Array(); - - for (var i = 0; i < arguments.length; i++) { - var element = arguments[i]; - if (typeof element == 'string') - element = document.getElementById(element); - - if (arguments.length == 1) - return element; - - elements.push(element); - } - - return elements; -} -Object.extend(String.prototype, { - 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(eval); - }, - - escapeHTML: function() { - var div = document.createElement('div'); - var text = document.createTextNode(this); - div.appendChild(text); - return div.innerHTML; - }, - - unescapeHTML: function() { - var div = document.createElement('div'); - div.innerHTML = this.stripTags(); - return div.childNodes[0] ? div.childNodes[0].nodeValue : ''; - }, - - toQueryParams: function() { - var pairs = this.match(/^\??(.*)$/)[1].split('&'); - return pairs.inject({}, function(params, pairString) { - var pair = pairString.split('='); - params[pair[0]] = pair[1]; - return params; - }); - }, - - toArray: function() { - return this.split(''); - }, - - camelize: function() { - var oStringList = this.split('-'); - if (oStringList.length == 1) return oStringList[0]; - - var camelizedString = this.indexOf('-') == 0 - ? oStringList[0].charAt(0).toUpperCase() + oStringList[0].substring(1) - : oStringList[0]; - - for (var i = 1, len = oStringList.length; i < len; i++) { - var s = oStringList[i]; - camelizedString += s.charAt(0).toUpperCase() + s.substring(1); - } - - return camelizedString; - }, - - inspect: function() { - return "'" + this.replace('\\', '\\\\').replace("'", '\\\'') + "'"; - } -}); - -String.prototype.parseQuery = String.prototype.toQueryParams; - -var $break = new Object(); -var $continue = new Object(); - -var Enumerable = { - each: function(iterator) { - var index = 0; - try { - this._each(function(value) { - try { - iterator(value, index++); - } catch (e) { - if (e != $continue) throw e; - } - }); - } catch (e) { - if (e != $break) throw e; - } - }, - - all: function(iterator) { - var result = true; - this.each(function(value, index) { - result = result && !!(iterator || Prototype.K)(value, index); - if (!result) throw $break; - }); - return result; - }, - - any: function(iterator) { - var result = true; - this.each(function(value, index) { - if (result = !!(iterator || Prototype.K)(value, index)) - throw $break; - }); - return result; - }, - - collect: function(iterator) { - var results = []; - this.each(function(value, index) { - results.push(iterator(value, index)); - }); - return results; - }, - - detect: function (iterator) { - var result; - this.each(function(value, index) { - if (iterator(value, index)) { - result = value; - throw $break; - } - }); - return result; - }, - - findAll: function(iterator) { - var results = []; - this.each(function(value, index) { - if (iterator(value, index)) - results.push(value); - }); - return results; - }, - - grep: function(pattern, iterator) { - var results = []; - this.each(function(value, index) { - var stringValue = value.toString(); - if (stringValue.match(pattern)) - results.push((iterator || Prototype.K)(value, index)); - }) - return results; - }, - - include: function(object) { - var found = false; - this.each(function(value) { - if (value == object) { - found = true; - throw $break; - } - }); - return found; - }, - - inject: function(memo, iterator) { - this.each(function(value, index) { - memo = iterator(memo, value, index); - }); - return memo; - }, - - invoke: function(method) { - var args = $A(arguments).slice(1); - return this.collect(function(value) { - return value[method].apply(value, args); - }); - }, - - max: function(iterator) { - var result; - this.each(function(value, index) { - value = (iterator || Prototype.K)(value, index); - if (value >= (result || value)) - result = value; - }); - return result; - }, - - min: function(iterator) { - var result; - this.each(function(value, index) { - value = (iterator || Prototype.K)(value, index); - if (value <= (result || value)) - result = value; - }); - return result; - }, - - partition: function(iterator) { - var trues = [], falses = []; - this.each(function(value, index) { - ((iterator || Prototype.K)(value, index) ? - trues : falses).push(value); - }); - return [trues, falses]; - }, - - pluck: function(property) { - var results = []; - this.each(function(value, index) { - results.push(value[property]); - }); - return results; - }, - - reject: function(iterator) { - var results = []; - this.each(function(value, index) { - if (!iterator(value, index)) - results.push(value); - }); - return results; - }, - - sortBy: function(iterator) { - return this.collect(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.collect(Prototype.K); - }, - - zip: function() { - var iterator = Prototype.K, args = $A(arguments); - if (typeof args.last() == 'function') - iterator = args.pop(); - - var collections = [this].concat(args).map($A); - return this.map(function(value, index) { - iterator(value = collections.pluck(index)); - return value; - }); - }, - - inspect: function() { - return '#'; - } -} - -Object.extend(Enumerable, { - map: Enumerable.collect, - find: Enumerable.detect, - select: Enumerable.findAll, - member: Enumerable.include, - entries: Enumerable.toArray -}); -var $A = Array.from = function(iterable) { - if (!iterable) return []; - if (iterable.toArray) { - return iterable.toArray(); - } else { - var results = []; - for (var i = 0; i < iterable.length; i++) - results.push(iterable[i]); - return results; - } -} - -Object.extend(Array.prototype, Enumerable); - -Array.prototype._reverse = Array.prototype.reverse; - -Object.extend(Array.prototype, { - _each: function(iterator) { - for (var i = 0; i < this.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 != undefined || value != null; - }); - }, - - flatten: function() { - return this.inject([], function(array, value) { - return array.concat(value.constructor == Array ? - value.flatten() : [value]); - }); - }, - - without: function() { - var values = $A(arguments); - return this.select(function(value) { - return !values.include(value); - }); - }, - - indexOf: function(object) { - for (var i = 0; i < this.length; i++) - if (this[i] == object) return i; - return -1; - }, - - reverse: function(inline) { - return (inline !== false ? this : this.toArray())._reverse(); - }, - - shift: function() { - var result = this[0]; - for (var i = 0; i < this.length - 1; i++) - this[i] = this[i + 1]; - this.length--; - return result; - }, - - inspect: function() { - return '[' + this.map(Object.inspect).join(', ') + ']'; - } -}); -var Hash = { - _each: function(iterator) { - for (key in this) { - var value = this[key]; - if (typeof value == 'function') 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'); - }, - - merge: function(hash) { - return $H(hash).inject($H(this), function(mergedHash, pair) { - mergedHash[pair.key] = pair.value; - return mergedHash; - }); - }, - - toQueryString: function() { - return this.map(function(pair) { - return pair.map(encodeURIComponent).join('='); - }).join('&'); - }, - - inspect: function() { - return '#'; - } -} - -function $H(object) { - var hash = Object.extend({}, object || {}); - Object.extend(hash, Enumerable); - Object.extend(hash, Hash); - return hash; -} -ObjectRange = Class.create(); -Object.extend(ObjectRange.prototype, Enumerable); -Object.extend(ObjectRange.prototype, { - initialize: function(start, end, exclusive) { - this.start = start; - this.end = end; - this.exclusive = exclusive; - }, - - _each: function(iterator) { - var value = this.start; - do { - iterator(value); - value = value.succ(); - } while (this.include(value)); - }, - - 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 ActiveXObject('Msxml2.XMLHTTP')}, - function() {return new ActiveXObject('Microsoft.XMLHTTP')}, - function() {return new XMLHttpRequest()} - ) || false; - }, - - activeRequestCount: 0 -} - -Ajax.Responders = { - responders: [], - - _each: function(iterator) { - this.responders._each(iterator); - }, - - register: function(responderToAdd) { - if (!this.include(responderToAdd)) - this.responders.push(responderToAdd); - }, - - unregister: function(responderToRemove) { - this.responders = this.responders.without(responderToRemove); - }, - - dispatch: function(callback, request, transport, json) { - this.each(function(responder) { - if (responder[callback] && typeof responder[callback] == 'function') { - 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 = function() {}; -Ajax.Base.prototype = { - setOptions: function(options) { - this.options = { - method: 'post', - asynchronous: true, - parameters: '' - } - Object.extend(this.options, options || {}); - }, - - responseIsSuccess: function() { - return this.transport.status == undefined - || this.transport.status == 0 - || (this.transport.status >= 200 && this.transport.status < 300); - }, - - responseIsFailure: function() { - return !this.responseIsSuccess(); - } -} - -Ajax.Request = Class.create(); -Ajax.Request.Events = - ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete']; - -Ajax.Request.prototype = Object.extend(new Ajax.Base(), { - initialize: function(url, options) { - this.transport = Ajax.getTransport(); - this.setOptions(options); - this.request(url); - }, - - request: function(url) { - var parameters = this.options.parameters || ''; - if (parameters.length > 0) parameters += '&_='; - - try { - this.url = url; - if (this.options.method == 'get' && parameters.length > 0) - this.url += (this.url.match(/\?/) ? '&' : '?') + parameters; - - Ajax.Responders.dispatch('onCreate', this, this.transport); - - this.transport.open(this.options.method, this.url, - this.options.asynchronous); - - if (this.options.asynchronous) { - this.transport.onreadystatechange = this.onStateChange.bind(this); - setTimeout((function() {this.respondToReadyState(1)}).bind(this), 10); - } - - this.setRequestHeaders(); - - var body = this.options.postBody ? this.options.postBody : parameters; - this.transport.send(this.options.method == 'post' ? body : null); - - } catch (e) { - this.dispatchException(e); - } - }, - - setRequestHeaders: function() { - var requestHeaders = - ['X-Requested-With', 'XMLHttpRequest', - 'X-Prototype-Version', Prototype.Version]; - - if (this.options.method == 'post') { - requestHeaders.push('Content-type', - 'application/x-www-form-urlencoded'); - - /* Force "Connection: close" for Mozilla browsers to work around - * a bug where XMLHttpReqeuest sends an incorrect Content-length - * header. See Mozilla Bugzilla #246651. - */ - if (this.transport.overrideMimeType) - requestHeaders.push('Connection', 'close'); - } - - if (this.options.requestHeaders) - requestHeaders.push.apply(requestHeaders, this.options.requestHeaders); - - for (var i = 0; i < requestHeaders.length; i += 2) - this.transport.setRequestHeader(requestHeaders[i], requestHeaders[i+1]); - }, - - onStateChange: function() { - var readyState = this.transport.readyState; - if (readyState != 1) - this.respondToReadyState(this.transport.readyState); - }, - - header: function(name) { - try { - return this.transport.getResponseHeader(name); - } catch (e) {} - }, - - evalJSON: function() { - try { - return eval(this.header('X-JSON')); - } catch (e) {} - }, - - evalResponse: function() { - try { - return eval(this.transport.responseText); - } catch (e) { - this.dispatchException(e); - } - }, - - respondToReadyState: function(readyState) { - var event = Ajax.Request.Events[readyState]; - var transport = this.transport, json = this.evalJSON(); - - if (event == 'Complete') { - try { - (this.options['on' + this.transport.status] - || this.options['on' + (this.responseIsSuccess() ? 'Success' : 'Failure')] - || Prototype.emptyFunction)(transport, json); - } catch (e) { - this.dispatchException(e); - } - - if ((this.header('Content-type') || '').match(/^text\/javascript/i)) - this.evalResponse(); - } - - try { - (this.options['on' + event] || Prototype.emptyFunction)(transport, json); - Ajax.Responders.dispatch('on' + event, this, transport, json); - } catch (e) { - this.dispatchException(e); - } - - /* Avoid memory leak in MSIE: clean up the oncomplete event handler */ - if (event == 'Complete') - this.transport.onreadystatechange = Prototype.emptyFunction; - }, - - dispatchException: function(exception) { - (this.options.onException || Prototype.emptyFunction)(this, exception); - Ajax.Responders.dispatch('onException', this, exception); - } -}); - -Ajax.Updater = Class.create(); - -Object.extend(Object.extend(Ajax.Updater.prototype, Ajax.Request.prototype), { - initialize: function(container, url, options) { - this.containers = { - success: container.success ? $(container.success) : $(container), - failure: container.failure ? $(container.failure) : - (container.success ? null : $(container)) - } - - this.transport = Ajax.getTransport(); - this.setOptions(options); - - var onComplete = this.options.onComplete || Prototype.emptyFunction; - this.options.onComplete = (function(transport, object) { - this.updateContent(); - onComplete(transport, object); - }).bind(this); - - this.request(url); - }, - - updateContent: function() { - var receiver = this.responseIsSuccess() ? - this.containers.success : this.containers.failure; - var response = this.transport.responseText; - - if (!this.options.evalScripts) - response = response.stripScripts(); - - if (receiver) { - if (this.options.insertion) { - new this.options.insertion(receiver, response); - } else { - Element.update(receiver, response); - } - } - - if (this.responseIsSuccess()) { - if (this.onComplete) - setTimeout(this.onComplete.bind(this), 10); - } - } -}); - -Ajax.PeriodicalUpdater = Class.create(); -Ajax.PeriodicalUpdater.prototype = Object.extend(new Ajax.Base(), { - initialize: function(container, url, options) { - this.setOptions(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.onComplete = undefined; - clearTimeout(this.timer); - (this.onComplete || Prototype.emptyFunction).apply(this, arguments); - }, - - updateComplete: function(request) { - if (this.options.decay) { - this.decay = (request.responseText == this.lastText ? - this.decay * this.options.decay : 1); - - this.lastText = request.responseText; - } - this.timer = setTimeout(this.onTimerEvent.bind(this), - this.decay * this.frequency * 1000); - }, - - onTimerEvent: function() { - this.updater = new Ajax.Updater(this.container, this.url, this.options); - } -}); -document.getElementsByClassName = function(className, parentElement) { - var children = ($(parentElement) || document.body).getElementsByTagName('*'); - return $A(children).inject([], function(elements, child) { - if (child.className.match(new RegExp("(^|\\s)" + className + "(\\s|$)"))) - elements.push(child); - return elements; - }); -} - -/*--------------------------------------------------------------------------*/ - -if (!window.Element) { - var Element = new Object(); -} - -Object.extend(Element, { - visible: function(element) { - return $(element).style.display != 'none'; - }, - - toggle: function() { - for (var i = 0; i < arguments.length; i++) { - var element = $(arguments[i]); - Element[Element.visible(element) ? 'hide' : 'show'](element); - } - }, - - hide: function() { - for (var i = 0; i < arguments.length; i++) { - var element = $(arguments[i]); - element.style.display = 'none'; - } - }, - - show: function() { - for (var i = 0; i < arguments.length; i++) { - var element = $(arguments[i]); - element.style.display = ''; - } - }, - - remove: function(element) { - element = $(element); - element.parentNode.removeChild(element); - }, - - update: function(element, html) { - $(element).innerHTML = html.stripScripts(); - setTimeout(function() {html.evalScripts()}, 10); - }, - - getHeight: function(element) { - element = $(element); - return element.offsetHeight; - }, - - classNames: function(element) { - return new Element.ClassNames(element); - }, - - hasClassName: function(element, className) { - if (!(element = $(element))) return; - return Element.classNames(element).include(className); - }, - - addClassName: function(element, className) { - if (!(element = $(element))) return; - return Element.classNames(element).add(className); - }, - - removeClassName: function(element, className) { - if (!(element = $(element))) return; - return Element.classNames(element).remove(className); - }, - - // removes whitespace-only text node children - cleanWhitespace: function(element) { - element = $(element); - for (var i = 0; i < element.childNodes.length; i++) { - var node = element.childNodes[i]; - if (node.nodeType == 3 && !/\S/.test(node.nodeValue)) - Element.remove(node); - } - }, - - empty: function(element) { - return $(element).innerHTML.match(/^\s*$/); - }, - - scrollTo: function(element) { - element = $(element); - var x = element.x ? element.x : element.offsetLeft, - y = element.y ? element.y : element.offsetTop; - window.scrollTo(x, y); - }, - - getStyle: function(element, style) { - element = $(element); - var value = element.style[style.camelize()]; - if (!value) { - if (document.defaultView && document.defaultView.getComputedStyle) { - var css = document.defaultView.getComputedStyle(element, null); - value = css ? css.getPropertyValue(style) : null; - } else if (element.currentStyle) { - value = element.currentStyle[style.camelize()]; - } - } - - if (window.opera && ['left', 'top', 'right', 'bottom'].include(style)) - if (Element.getStyle(element, 'position') == 'static') value = 'auto'; - - return value == 'auto' ? null : value; - }, - - setStyle: function(element, style) { - element = $(element); - for (name in style) - element.style[name.camelize()] = style[name]; - }, - - getDimensions: function(element) { - element = $(element); - if (Element.getStyle(element, 'display') != 'none') - 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; - els.visibility = 'hidden'; - els.position = 'absolute'; - els.display = ''; - var originalWidth = element.clientWidth; - var originalHeight = element.clientHeight; - els.display = 'none'; - 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; - } - } - }, - - 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 = ''; - } - }, - - makeClipping: function(element) { - element = $(element); - if (element._overflow) return; - element._overflow = element.style.overflow; - if ((Element.getStyle(element, 'overflow') || 'visible') != 'hidden') - element.style.overflow = 'hidden'; - }, - - undoClipping: function(element) { - element = $(element); - if (element._overflow) return; - element.style.overflow = element._overflow; - element._overflow = undefined; - } -}); - -var Toggle = new Object(); -Toggle.display = Element.toggle; - -/*--------------------------------------------------------------------------*/ - -Abstract.Insertion = function(adjacency) { - this.adjacency = adjacency; -} - -Abstract.Insertion.prototype = { - initialize: function(element, content) { - this.element = $(element); - this.content = content.stripScripts(); - - if (this.adjacency && this.element.insertAdjacentHTML) { - try { - this.element.insertAdjacentHTML(this.adjacency, this.content); - } catch (e) { - if (this.element.tagName.toLowerCase() == 'tbody') { - this.insertContent(this.contentFromAnonymousTable()); - } else { - throw e; - } - } - } else { - this.range = this.element.ownerDocument.createRange(); - if (this.initializeRange) this.initializeRange(); - this.insertContent([this.range.createContextualFragment(this.content)]); - } - - setTimeout(function() {content.evalScripts()}, 10); - }, - - contentFromAnonymousTable: function() { - var div = document.createElement('div'); - div.innerHTML = '' + this.content + '
    '; - return $A(div.childNodes[0].childNodes[0].childNodes); - } -} - -var Insertion = new Object(); - -Insertion.Before = Class.create(); -Insertion.Before.prototype = Object.extend(new Abstract.Insertion('beforeBegin'), { - initializeRange: function() { - this.range.setStartBefore(this.element); - }, - - insertContent: function(fragments) { - fragments.each((function(fragment) { - this.element.parentNode.insertBefore(fragment, this.element); - }).bind(this)); - } -}); - -Insertion.Top = Class.create(); -Insertion.Top.prototype = Object.extend(new Abstract.Insertion('afterBegin'), { - initializeRange: function() { - this.range.selectNodeContents(this.element); - this.range.collapse(true); - }, - - insertContent: function(fragments) { - fragments.reverse(false).each((function(fragment) { - this.element.insertBefore(fragment, this.element.firstChild); - }).bind(this)); - } -}); - -Insertion.Bottom = Class.create(); -Insertion.Bottom.prototype = Object.extend(new Abstract.Insertion('beforeEnd'), { - initializeRange: function() { - this.range.selectNodeContents(this.element); - this.range.collapse(this.element); - }, - - insertContent: function(fragments) { - fragments.each((function(fragment) { - this.element.appendChild(fragment); - }).bind(this)); - } -}); - -Insertion.After = Class.create(); -Insertion.After.prototype = Object.extend(new Abstract.Insertion('afterEnd'), { - initializeRange: function() { - this.range.setStartAfter(this.element); - }, - - insertContent: function(fragments) { - fragments.each((function(fragment) { - this.element.parentNode.insertBefore(fragment, - this.element.nextSibling); - }).bind(this)); - } -}); - -/*--------------------------------------------------------------------------*/ - -Element.ClassNames = Class.create(); -Element.ClassNames.prototype = { - initialize: function(element) { - this.element = $(element); - }, - - _each: function(iterator) { - this.element.className.split(/\s+/).select(function(name) { - return name.length > 0; - })._each(iterator); - }, - - set: function(className) { - this.element.className = className; - }, - - add: function(classNameToAdd) { - if (this.include(classNameToAdd)) return; - this.set(this.toArray().concat(classNameToAdd).join(' ')); - }, - - remove: function(classNameToRemove) { - if (!this.include(classNameToRemove)) return; - this.set(this.select(function(className) { - return className != classNameToRemove; - }).join(' ')); - }, - - toString: function() { - return this.toArray().join(' '); - } -} - -Object.extend(Element.ClassNames.prototype, Enumerable); -var Field = { - clear: function() { - for (var i = 0; i < arguments.length; i++) - $(arguments[i]).value = ''; - }, - - focus: function(element) { - $(element).focus(); - }, - - present: function() { - for (var i = 0; i < arguments.length; i++) - if ($(arguments[i]).value == '') return false; - return true; - }, - - select: function(element) { - $(element).select(); - }, - - activate: function(element) { - element = $(element); - element.focus(); - if (element.select) - element.select(); - } -} - -/*--------------------------------------------------------------------------*/ - -var Form = { - serialize: function(form) { - var elements = Form.getElements($(form)); - var queryComponents = new Array(); - - for (var i = 0; i < elements.length; i++) { - var queryComponent = Form.Element.serialize(elements[i]); - if (queryComponent) - queryComponents.push(queryComponent); - } - - return queryComponents.join('&'); - }, - - getElements: function(form) { - form = $(form); - var elements = new Array(); - - for (tagName in Form.Element.Serializers) { - var tagElements = form.getElementsByTagName(tagName); - for (var j = 0; j < tagElements.length; j++) - elements.push(tagElements[j]); - } - return elements; - }, - - getInputs: function(form, typeName, name) { - form = $(form); - var inputs = form.getElementsByTagName('input'); - - if (!typeName && !name) - return inputs; - - var matchingInputs = new Array(); - for (var i = 0; i < inputs.length; i++) { - var input = inputs[i]; - if ((typeName && input.type != typeName) || - (name && input.name != name)) - continue; - matchingInputs.push(input); - } - - return matchingInputs; - }, - - disable: function(form) { - var elements = Form.getElements(form); - for (var i = 0; i < elements.length; i++) { - var element = elements[i]; - element.blur(); - element.disabled = 'true'; - } - }, - - enable: function(form) { - var elements = Form.getElements(form); - for (var i = 0; i < elements.length; i++) { - var element = elements[i]; - element.disabled = ''; - } - }, - - findFirstElement: function(form) { - return Form.getElements(form).find(function(element) { - return element.type != 'hidden' && !element.disabled && - ['input', 'select', 'textarea'].include(element.tagName.toLowerCase()); - }); - }, - - focusFirstElement: function(form) { - Field.activate(Form.findFirstElement(form)); - }, - - reset: function(form) { - $(form).reset(); - } -} - -Form.Element = { - serialize: function(element) { - element = $(element); - var method = element.tagName.toLowerCase(); - var parameter = Form.Element.Serializers[method](element); - - if (parameter) { - var key = encodeURIComponent(parameter[0]); - if (key.length == 0) return; - - if (parameter[1].constructor != Array) - parameter[1] = [parameter[1]]; - - return parameter[1].map(function(value) { - return key + '=' + encodeURIComponent(value); - }).join('&'); - } - }, - - getValue: function(element) { - element = $(element); - var method = element.tagName.toLowerCase(); - var parameter = Form.Element.Serializers[method](element); - - if (parameter) - return parameter[1]; - } -} - -Form.Element.Serializers = { - input: function(element) { - switch (element.type.toLowerCase()) { - case 'submit': - case 'hidden': - case 'password': - case 'text': - return Form.Element.Serializers.textarea(element); - case 'checkbox': - case 'radio': - return Form.Element.Serializers.inputSelector(element); - } - return false; - }, - - inputSelector: function(element) { - if (element.checked) - return [element.name, element.value]; - }, - - textarea: function(element) { - return [element.name, element.value]; - }, - - select: function(element) { - return Form.Element.Serializers[element.type == 'select-one' ? - 'selectOne' : 'selectMany'](element); - }, - - selectOne: function(element) { - var value = '', opt, index = element.selectedIndex; - if (index >= 0) { - opt = element.options[index]; - value = opt.value; - if (!value && !('value' in opt)) - value = opt.text; - } - return [element.name, value]; - }, - - selectMany: function(element) { - var value = new Array(); - for (var i = 0; i < element.length; i++) { - var opt = element.options[i]; - if (opt.selected) { - var optValue = opt.value; - if (!optValue && !('value' in opt)) - optValue = opt.text; - value.push(optValue); - } - } - return [element.name, value]; - } -} - -/*--------------------------------------------------------------------------*/ - -var $F = Form.Element.getValue; - -/*--------------------------------------------------------------------------*/ - -Abstract.TimedObserver = function() {} -Abstract.TimedObserver.prototype = { - initialize: function(element, frequency, callback) { - this.frequency = frequency; - this.element = $(element); - this.callback = callback; - - this.lastValue = this.getValue(); - this.registerCallback(); - }, - - registerCallback: function() { - setInterval(this.onTimerEvent.bind(this), this.frequency * 1000); - }, - - onTimerEvent: function() { - var value = this.getValue(); - if (this.lastValue != value) { - this.callback(this.element, value); - this.lastValue = value; - } - } -} - -Form.Element.Observer = Class.create(); -Form.Element.Observer.prototype = Object.extend(new Abstract.TimedObserver(), { - getValue: function() { - return Form.Element.getValue(this.element); - } -}); - -Form.Observer = Class.create(); -Form.Observer.prototype = Object.extend(new Abstract.TimedObserver(), { - getValue: function() { - return Form.serialize(this.element); - } -}); - -/*--------------------------------------------------------------------------*/ - -Abstract.EventObserver = function() {} -Abstract.EventObserver.prototype = { - 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() { - var elements = Form.getElements(this.element); - for (var i = 0; i < elements.length; i++) - this.registerCallback(elements[i]); - }, - - registerCallback: function(element) { - if (element.type) { - switch (element.type.toLowerCase()) { - case 'checkbox': - case 'radio': - Event.observe(element, 'click', this.onElementEvent.bind(this)); - break; - case 'password': - case 'text': - case 'textarea': - case 'select-one': - case 'select-multiple': - Event.observe(element, 'change', this.onElementEvent.bind(this)); - break; - } - } - } -} - -Form.Element.EventObserver = Class.create(); -Form.Element.EventObserver.prototype = Object.extend(new Abstract.EventObserver(), { - getValue: function() { - return Form.Element.getValue(this.element); - } -}); - -Form.EventObserver = Class.create(); -Form.EventObserver.prototype = Object.extend(new Abstract.EventObserver(), { - getValue: function() { - return Form.serialize(this.element); - } -}); -if (!window.Event) { - var Event = new Object(); -} - -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, - - element: function(event) { - return event.target || event.srcElement; - }, - - isLeftClick: function(event) { - return (((event.which) && (event.which == 1)) || - ((event.button) && (event.button == 1))); - }, - - pointerX: function(event) { - return event.pageX || (event.clientX + - (document.documentElement.scrollLeft || document.body.scrollLeft)); - }, - - pointerY: function(event) { - return event.pageY || (event.clientY + - (document.documentElement.scrollTop || document.body.scrollTop)); - }, - - stop: function(event) { - if (event.preventDefault) { - event.preventDefault(); - event.stopPropagation(); - } else { - event.returnValue = false; - event.cancelBubble = true; - } - }, - - // find the first node with the given tagName, starting from the - // node the event was triggered on; traverses the DOM upwards - findElement: function(event, tagName) { - var element = Event.element(event); - while (element.parentNode && (!element.tagName || - (element.tagName.toUpperCase() != tagName.toUpperCase()))) - element = element.parentNode; - return element; - }, - - observers: false, - - _observeAndCache: function(element, name, observer, useCapture) { - if (!this.observers) this.observers = []; - if (element.addEventListener) { - this.observers.push([element, name, observer, useCapture]); - element.addEventListener(name, observer, useCapture); - } else if (element.attachEvent) { - this.observers.push([element, name, observer, useCapture]); - element.attachEvent('on' + name, observer); - } - }, - - unloadCache: function() { - if (!Event.observers) return; - for (var i = 0; i < Event.observers.length; i++) { - Event.stopObserving.apply(this, Event.observers[i]); - Event.observers[i][0] = null; - } - Event.observers = false; - }, - - observe: function(element, name, observer, useCapture) { - var element = $(element); - useCapture = useCapture || false; - - if (name == 'keypress' && - (navigator.appVersion.match(/Konqueror|Safari|KHTML/) - || element.attachEvent)) - name = 'keydown'; - - this._observeAndCache(element, name, observer, useCapture); - }, - - stopObserving: function(element, name, observer, useCapture) { - var element = $(element); - useCapture = useCapture || false; - - if (name == 'keypress' && - (navigator.appVersion.match(/Konqueror|Safari|KHTML/) - || element.detachEvent)) - name = 'keydown'; - - if (element.removeEventListener) { - element.removeEventListener(name, observer, useCapture); - } else if (element.detachEvent) { - element.detachEvent('on' + name, observer); - } - } -}); - -/* prevent memory leaks in IE */ -Event.observe(window, 'unload', Event.unloadCache, false); -var Position = { - // set to true if needed, warning: firefox performance problems - // NOT neeeded for page scrolling, only if draggable contained in - // scrollable elements - includeScrollOffsets: false, - - // must be called before calling withinIncludingScrolloffset, every time the - // page is scrolled - prepare: function() { - this.deltaX = window.pageXOffset - || document.documentElement.scrollLeft - || document.body.scrollLeft - || 0; - this.deltaY = window.pageYOffset - || document.documentElement.scrollTop - || document.body.scrollTop - || 0; - }, - - realOffset: function(element) { - var valueT = 0, valueL = 0; - do { - valueT += element.scrollTop || 0; - valueL += element.scrollLeft || 0; - element = element.parentNode; - } while (element); - return [valueL, valueT]; - }, - - cumulativeOffset: function(element) { - var valueT = 0, valueL = 0; - do { - valueT += element.offsetTop || 0; - valueL += element.offsetLeft || 0; - element = element.offsetParent; - } while (element); - return [valueL, valueT]; - }, - - positionedOffset: function(element) { - var valueT = 0, valueL = 0; - do { - valueT += element.offsetTop || 0; - valueL += element.offsetLeft || 0; - element = element.offsetParent; - if (element) { - p = Element.getStyle(element, 'position'); - if (p == 'relative' || p == 'absolute') break; - } - } while (element); - return [valueL, valueT]; - }, - - offsetParent: 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; - }, - - // caches x/y coordinate pair to use with overlap - within: function(element, x, y) { - if (this.includeScrollOffsets) - return this.withinIncludingScrolloffsets(element, x, y); - this.xcomp = x; - this.ycomp = y; - this.offset = this.cumulativeOffset(element); - - return (y >= this.offset[1] && - y < this.offset[1] + element.offsetHeight && - x >= this.offset[0] && - x < this.offset[0] + element.offsetWidth); - }, - - withinIncludingScrolloffsets: function(element, x, y) { - var offsetcache = this.realOffset(element); - - this.xcomp = x + offsetcache[0] - this.deltaX; - this.ycomp = y + offsetcache[1] - this.deltaY; - this.offset = this.cumulativeOffset(element); - - return (this.ycomp >= this.offset[1] && - this.ycomp < this.offset[1] + element.offsetHeight && - this.xcomp >= this.offset[0] && - this.xcomp < this.offset[0] + element.offsetWidth); - }, - - // within must be called directly before - overlap: function(mode, element) { - if (!mode) return 0; - if (mode == 'vertical') - return ((this.offset[1] + element.offsetHeight) - this.ycomp) / - element.offsetHeight; - if (mode == 'horizontal') - return ((this.offset[0] + element.offsetWidth) - this.xcomp) / - element.offsetWidth; - }, - - clone: function(source, target) { - source = $(source); - target = $(target); - target.style.position = 'absolute'; - var offsets = this.cumulativeOffset(source); - target.style.top = offsets[1] + 'px'; - target.style.left = offsets[0] + 'px'; - target.style.width = source.offsetWidth + 'px'; - target.style.height = source.offsetHeight + 'px'; - }, - - page: 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) - if (Element.getStyle(element,'position')=='absolute') break; - - } while (element = element.offsetParent); - - element = forElement; - do { - valueT -= element.scrollTop || 0; - valueL -= element.scrollLeft || 0; - } while (element = element.parentNode); - - return [valueL, valueT]; - }, - - clone: function(source, target) { - 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 = Position.page(source); - - // find coordinate system to use - target = $(target); - 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(target,'position') == 'absolute') { - parent = Position.offsetParent(target); - delta = Position.page(parent); - } - - // 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) target.style.left = (p[0] - delta[0] + options.offsetLeft) + 'px'; - if(options.setTop) target.style.top = (p[1] - delta[1] + options.offsetTop) + 'px'; - if(options.setWidth) target.style.width = source.offsetWidth + 'px'; - if(options.setHeight) target.style.height = source.offsetHeight + 'px'; - }, - - absolutize: function(element) { - element = $(element); - if (element.style.position == 'absolute') return; - Position.prepare(); - - var offsets = Position.positionedOffset(element); - 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';; - }, - - relativize: function(element) { - element = $(element); - if (element.style.position == 'relative') return; - Position.prepare(); - - 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; - } -} - -// Safari returns margins on body which is incorrect if the child is absolutely -// positioned. For performance reasons, redefine Position.cumulativeOffset for -// KHTML/WebKit only. -if (/Konqueror|Safari|KHTML/.test(navigator.userAgent)) { - Position.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 [valueL, valueT]; - } -} \ No newline at end of file diff --git a/tracks/vendor/rails/actionpack/lib/action_view/helpers/number_helper.rb b/tracks/vendor/rails/actionpack/lib/action_view/helpers/number_helper.rb deleted file mode 100644 index e06eb14f..00000000 --- a/tracks/vendor/rails/actionpack/lib/action_view/helpers/number_helper.rb +++ /dev/null @@ -1,109 +0,0 @@ -module ActionView - module Helpers - # Provides methods for converting a number into a formatted string that currently represents - # one of the following forms: phone number, percentage, money, or precision level. - module NumberHelper - - # Formats a +number+ into a US phone number string. The +options+ can be a hash used to customize the format of the output. - # The area code can be surrounded by parentheses by setting +:area_code+ to true; default is false - # The delimiter can be set using +:delimiter+; default is "-" - # Examples: - # number_to_phone(1235551234) => 123-555-1234 - # number_to_phone(1235551234, {:area_code => true}) => (123) 555-1234 - # number_to_phone(1235551234, {:delimiter => " "}) => 123 555 1234 - # number_to_phone(1235551234, {:area_code => true, :extension => 555}) => (123) 555-1234 x 555 - def number_to_phone(number, options = {}) - options = options.stringify_keys - area_code = options.delete("area_code") { false } - delimiter = options.delete("delimiter") { "-" } - extension = options.delete("extension") { "" } - begin - str = area_code == true ? number.to_s.gsub(/([0-9]{3})([0-9]{3})([0-9]{4})/,"(\\1) \\2#{delimiter}\\3") : number.to_s.gsub(/([0-9]{3})([0-9]{3})([0-9]{4})/,"\\1#{delimiter}\\2#{delimiter}\\3") - extension.to_s.strip.empty? ? str : "#{str} x #{extension.to_s.strip}" - rescue - number - end - end - - # Formats a +number+ into a currency string. The +options+ hash can be used to customize the format of the output. - # The +number+ can contain a level of precision using the +precision+ key; default is 2 - # The currency type can be set using the +unit+ key; default is "$" - # The unit separator can be set using the +separator+ key; default is "." - # The delimiter can be set using the +delimiter+ key; default is "," - # Examples: - # number_to_currency(1234567890.50) => $1,234,567,890.50 - # number_to_currency(1234567890.506) => $1,234,567,890.51 - # number_to_currency(1234567890.50, {:unit => "£", :separator => ",", :delimiter => ""}) => £1234567890,50 - def number_to_currency(number, options = {}) - options = options.stringify_keys - precision, unit, separator, delimiter = options.delete("precision") { 2 }, options.delete("unit") { "$" }, options.delete("separator") { "." }, options.delete("delimiter") { "," } - separator = "" unless precision > 0 - begin - parts = number_with_precision(number, precision).split('.') - unit + number_with_delimiter(parts[0], delimiter) + separator + parts[1].to_s - rescue - number - end - end - - # Formats a +number+ as into a percentage string. The +options+ hash can be used to customize the format of the output. - # The +number+ can contain a level of precision using the +precision+ key; default is 3 - # The unit separator can be set using the +separator+ key; default is "." - # Examples: - # number_to_percentage(100) => 100.000% - # number_to_percentage(100, {:precision => 0}) => 100% - # number_to_percentage(302.0574, {:precision => 2}) => 302.06% - def number_to_percentage(number, options = {}) - options = options.stringify_keys - precision, separator = options.delete("precision") { 3 }, options.delete("separator") { "." } - begin - number = number_with_precision(number, precision) - parts = number.split('.') - if parts.at(1).nil? - parts[0] + "%" - else - parts[0] + separator + parts[1].to_s + "%" - end - rescue - number - end - end - - # Formats a +number+ with a +delimiter+. - # Example: - # number_with_delimiter(12345678) => 12,345,678 - def number_with_delimiter(number, delimiter=",") - number.to_s.gsub(/(\d)(?=(\d\d\d)+(?!\d))/, "\\1#{delimiter}") - end - - # Returns a formatted-for-humans file size. - # - # Examples: - # human_size(123) => 123 Bytes - # human_size(1234) => 1.2 KB - # human_size(12345) => 12.1 KB - # human_size(1234567) => 1.2 MB - # human_size(1234567890) => 1.1 GB - def number_to_human_size(size) - begin - return "%d Bytes" % size if size < 1.kilobytes - return "%.1f KB" % (size/1.0.kilobytes) if size < 1.megabytes - return "%.1f MB" % (size/1.0.megabytes) if size < 1.gigabytes - return "%.1f GB" % (size/1.0.gigabytes) if size < 1.terabytes - return "%.1f TB" % (size/1.0.terabytes) - rescue - # just return nothing - end - end - - alias_method :human_size, :number_to_human_size # deprecated alias - - # Formats a +number+ with a level of +precision+. - # Example: - # number_with_precision(111.2345) => 111.235 - def number_with_precision(number, precision=3) - sprintf("%01.#{precision}f", number) - end - end - end -end diff --git a/tracks/vendor/rails/actionpack/lib/action_view/helpers/pagination_helper.rb b/tracks/vendor/rails/actionpack/lib/action_view/helpers/pagination_helper.rb deleted file mode 100644 index 51510599..00000000 --- a/tracks/vendor/rails/actionpack/lib/action_view/helpers/pagination_helper.rb +++ /dev/null @@ -1,86 +0,0 @@ -module ActionView - module Helpers - # Provides methods for linking to ActionController::Pagination objects. - # - # You can also build your links manually, like in this example: - # - # <%= link_to "Previous page", { :page => paginator.current.previous } if paginator.current.previous %> - # - # <%= link_to "Next page", { :page => paginator.current.next } if paginator.current.next =%> - module PaginationHelper - unless const_defined?(:DEFAULT_OPTIONS) - DEFAULT_OPTIONS = { - :name => :page, - :window_size => 2, - :always_show_anchors => true, - :link_to_current_page => false, - :params => {} - } - end - - # Creates a basic HTML link bar for the given +paginator+. - # +html_options+ are passed to +link_to+. - # - # +options+ are: - # :name:: the routing name for this paginator - # (defaults to +page+) - # :window_size:: the number of pages to show around - # the current page (defaults to +2+) - # :always_show_anchors:: whether or not the first and last - # pages should always be shown - # (defaults to +true+) - # :link_to_current_page:: whether or not the current page - # should be linked to (defaults to - # +false+) - # :params:: any additional routing parameters - # for page URLs - def pagination_links(paginator, options={}, html_options={}) - name = options[:name] || DEFAULT_OPTIONS[:name] - params = (options[:params] || DEFAULT_OPTIONS[:params]).clone - - pagination_links_each(paginator, options) do |n| - params[name] = n - link_to(n.to_s, params, html_options) - end - end - - # Iterate through the pages of a given +paginator+, invoking a - # block for each page number that needs to be rendered as a link. - def pagination_links_each(paginator, options) - options = DEFAULT_OPTIONS.merge(options) - link_to_current_page = options[:link_to_current_page] - always_show_anchors = options[:always_show_anchors] - - current_page = paginator.current_page - window_pages = current_page.window(options[:window_size]).pages - return if window_pages.length <= 1 unless link_to_current_page - - first, last = paginator.first, paginator.last - - html = '' - if always_show_anchors and not (wp_first = window_pages[0]).first? - html << yield(first.number) - html << ' ... ' if wp_first.number - first.number > 1 - html << ' ' - end - - window_pages.each do |page| - if current_page == page && !link_to_current_page - html << page.number.to_s - else - html << yield(page.number) - end - html << ' ' - end - - if always_show_anchors and not (wp_last = window_pages[-1]).last? - html << ' ... ' if last.number - wp_last.number > 1 - html << yield(last.number) - end - - html - end - - end # PaginationHelper - end # Helpers -end # ActionView diff --git a/tracks/vendor/rails/actionpack/lib/action_view/helpers/tag_helper.rb b/tracks/vendor/rails/actionpack/lib/action_view/helpers/tag_helper.rb deleted file mode 100644 index 6c71b8b7..00000000 --- a/tracks/vendor/rails/actionpack/lib/action_view/helpers/tag_helper.rb +++ /dev/null @@ -1,50 +0,0 @@ -require 'cgi' -require 'erb' - -module ActionView - module Helpers - # This is poor man's Builder for the rare cases where you need to programmatically make tags but can't use Builder. - module TagHelper - include ERB::Util - - # Examples: - # * tag("br") =>
    - # * tag("input", { "type" => "text"}) => - def tag(name, options = nil, open = false) - "<#{name}#{tag_options(options.stringify_keys) if options}" + (open ? ">" : " />") - end - - # Examples: - # * content_tag("p", "Hello world!") =>

    Hello world!

    - # * content_tag("div", content_tag("p", "Hello world!"), "class" => "strong") => - #

    Hello world!

    - def content_tag(name, content, options = nil) - "<#{name}#{tag_options(options.stringify_keys) if options}>#{content}" - end - - # Returns a CDATA section for the given +content+. CDATA sections - # are used to escape blocks of text containing characters which would - # otherwise be recognized as markup. CDATA sections begin with the string - # <![CDATA[ and end with (and may not contain) the string - # ]]>. - def cdata_section(content) - "" - end - - private - def tag_options(options) - cleaned_options = convert_booleans(options.stringify_keys.reject {|key, value| value.nil?}) - ' ' + cleaned_options.map {|key, value| %(#{key}="#{html_escape(value.to_s)}")}.sort * ' ' unless cleaned_options.empty? - end - - def convert_booleans(options) - %w( disabled readonly multiple ).each { |a| boolean_attribute(options, a) } - options - end - - def boolean_attribute(options, attribute) - options[attribute] ? options[attribute] = attribute : options.delete(attribute) - end - end - end -end diff --git a/tracks/vendor/rails/actionpack/lib/action_view/helpers/text_helper.rb b/tracks/vendor/rails/actionpack/lib/action_view/helpers/text_helper.rb deleted file mode 100644 index b3166820..00000000 --- a/tracks/vendor/rails/actionpack/lib/action_view/helpers/text_helper.rb +++ /dev/null @@ -1,368 +0,0 @@ -require File.dirname(__FILE__) + '/tag_helper' - -module ActionView - module Helpers #:nodoc: - # Provides a set of methods for working with text strings that can help unburden the level of inline Ruby code in the - # templates. In the example below we iterate over a collection of posts provided to the template and print each title - # after making sure it doesn't run longer than 20 characters: - # <% for post in @posts %> - # Title: <%= truncate(post.title, 20) %> - # <% end %> - module TextHelper - # The regular puts and print are outlawed in eRuby. It's recommended to use the <%= "hello" %> form instead of print "hello". - # If you absolutely must use a method-based output, you can use concat. It's used like this: <% concat "hello", binding %>. Notice that - # it doesn't have an equal sign in front. Using <%= concat "hello" %> would result in a double hello. - def concat(string, binding) - eval("_erbout", binding).concat(string) - end - - # Truncates +text+ to the length of +length+ and replaces the last three characters with the +truncate_string+ - # if the +text+ is longer than +length+. - def truncate(text, length = 30, truncate_string = "...") - if text.nil? then return end - - if $KCODE == "NONE" - text.length > length ? text[0..(length - 3)] + truncate_string : text - else - chars = text.split(//) - chars.length > length ? chars[0..(length-3)].join + truncate_string : text - end - end - - # Highlights the +phrase+ where it is found in the +text+ by surrounding it like - # I'm a highlight phrase. The highlighter can be specialized by - # passing +highlighter+ as single-quoted string with \1 where the phrase is supposed to be inserted. - # N.B.: The +phrase+ is sanitized to include only letters, digits, and spaces before use. - def highlight(text, phrase, highlighter = '\1') - if phrase.blank? then return text end - text.gsub(/(#{Regexp.escape(phrase)})/i, highlighter) unless text.nil? - end - - # Extracts an excerpt from the +text+ surrounding the +phrase+ with a number of characters on each side determined - # by +radius+. If the phrase isn't found, nil is returned. Ex: - # excerpt("hello my world", "my", 3) => "...lo my wo..." - def excerpt(text, phrase, radius = 100, excerpt_string = "...") - if text.nil? || phrase.nil? then return end - phrase = Regexp.escape(phrase) - - if found_pos = text =~ /(#{phrase})/i - start_pos = [ found_pos - radius, 0 ].max - end_pos = [ found_pos + phrase.length + radius, text.length ].min - - prefix = start_pos > 0 ? excerpt_string : "" - postfix = end_pos < text.length ? excerpt_string : "" - - prefix + text[start_pos..end_pos].strip + postfix - else - nil - end - end - - # Attempts to pluralize the +singular+ word unless +count+ is 1. See source for pluralization rules. - def pluralize(count, singular, plural = nil) - "#{count} " + if count == 1 - singular - elsif plural - plural - elsif Object.const_defined?("Inflector") - Inflector.pluralize(singular) - else - singular + "s" - end - end - - # Word wrap long lines to line_width. - def word_wrap(text, line_width = 80) - text.gsub(/\n/, "\n\n").gsub(/(.{1,#{line_width}})(\s+|$)/, "\\1\n").strip - end - - begin - require "redcloth" - - # Returns the text with all the Textile codes turned into HTML-tags. - # This method is only available if RedCloth can be required. - def textilize(text) - if text.blank? - "" - else - textilized = RedCloth.new(text, [ :hard_breaks ]) - textilized.hard_breaks = true if textilized.respond_to?("hard_breaks=") - textilized.to_html - end - end - - # Returns the text with all the Textile codes turned into HTML-tags, but without the regular bounding

    tag. - # This method is only available if RedCloth can be required. - def textilize_without_paragraph(text) - textiled = textilize(text) - if textiled[0..2] == "

    " then textiled = textiled[3..-1] end - if textiled[-4..-1] == "

    " then textiled = textiled[0..-5] end - return textiled - end - rescue LoadError - # We can't really help what's not there - end - - begin - require "bluecloth" - - # Returns the text with all the Markdown codes turned into HTML-tags. - # This method is only available if BlueCloth can be required. - def markdown(text) - text.blank? ? "" : BlueCloth.new(text).to_html - end - rescue LoadError - # We can't really help what's not there - end - - # Returns +text+ transformed into HTML using very simple formatting rules - # Surrounds paragraphs with <p> tags, and converts line breaks into <br /> - # Two consecutive newlines(\n\n) are considered as a paragraph, one newline (\n) is - # considered a linebreak, three or more consecutive newlines are turned into two newlines - def simple_format(text) - text.gsub!(/(\r\n|\n|\r)/, "\n") # lets make them newlines crossplatform - text.gsub!(/\n\n+/, "\n\n") # zap dupes - text.gsub!(/\n\n/, '

    \0

    ') # turn two newlines into paragraph - text.gsub!(/([^\n])(\n)([^\n])/, '\1\2
    \3') # turn single newline into
    - - content_tag("p", text) - end - - # Turns all urls and email addresses into clickable links. The +link+ parameter can limit what should be linked. - # Options are :all (default), :email_addresses, and :urls. - # - # Example: - # auto_link("Go to http://www.rubyonrails.com and say hello to david@loudthinking.com") => - # Go to http://www.rubyonrails.com and - # say hello to david@loudthinking.com - # - # If a block is given, each url and email address is yielded and the - # result is used as the link text. Example: - # auto_link(post.body, :all, :target => '_blank') do |text| - # truncate(text, 15) - # end - def auto_link(text, link = :all, href_options = {}, &block) - case link - when :all then auto_link_urls(auto_link_email_addresses(text, &block), href_options, &block) - when :email_addresses then auto_link_email_addresses(text, &block) - when :urls then auto_link_urls(text, href_options, &block) - end - end - - # Turns all links into words, like "else" to "else". - def strip_links(text) - text.gsub(/(.*)<\/a>/m, '\1') - end - - # Try to require the html-scanner library - begin - require 'html/tokenizer' - require 'html/node' - rescue LoadError - # if there isn't a copy installed, use the vendor version in - # action controller - $:.unshift File.join(File.dirname(__FILE__), "..", "..", - "action_controller", "vendor", "html-scanner") - require 'html/tokenizer' - require 'html/node' - end - - VERBOTEN_TAGS = %w(form script) unless defined?(VERBOTEN_TAGS) - VERBOTEN_ATTRS = /^on/i unless defined?(VERBOTEN_ATTRS) - - # Sanitizes the given HTML by making form and script tags into regular - # text, and removing all "onxxx" attributes (so that arbitrary Javascript - # cannot be executed). Also removes href attributes that start with - # "javascript:". - # - # Returns the sanitized text. - def sanitize(html) - # only do this if absolutely necessary - if html.index("<") - tokenizer = HTML::Tokenizer.new(html) - new_text = "" - - while token = tokenizer.next - node = HTML::Node.parse(nil, 0, 0, token, false) - new_text << case node - when HTML::Tag - if VERBOTEN_TAGS.include?(node.name) - node.to_s.gsub(/[\n]?/m, "") - else - html # already plain text - end - end - - # Returns a Cycle object whose to_s value cycles through items of an - # array every time it is called. This can be used to alternate classes - # for table rows: - # - # <%- for item in @items do -%> - # "> - # ... use item ... - # - # <%- end -%> - # - # You can use named cycles to prevent clashes in nested loops. You'll - # have to reset the inner cycle, manually: - # - # <%- for item in @items do -%> - # "row_class") - # - # <%- for value in item.values do -%> - # "colors") %>'"> - # item - # - # <%- end -%> - # <%- reset_cycle("colors") -%> - # - # - # <%- end -%> - def cycle(first_value, *values) - if (values.last.instance_of? Hash) - params = values.pop - name = params[:name] - else - name = "default" - end - values.unshift(first_value) - - cycle = get_cycle(name) - if (cycle.nil? || cycle.values != values) - cycle = set_cycle(name, Cycle.new(*values)) - end - return cycle.to_s - end - - # Resets a cycle so that it starts from the first element in the array - # the next time it is used. - def reset_cycle(name = "default") - cycle = get_cycle(name) - return if cycle.nil? - cycle.reset - end - - class Cycle #:nodoc: - attr_reader :values - - def initialize(first_value, *values) - @values = values.unshift(first_value) - reset - end - - def reset - @index = 0 - end - - def to_s - value = @values[@index].to_s - @index = (@index + 1) % @values.size - return value - end - end - - private - # The cycle helpers need to store the cycles in a place that is - # guaranteed to be reset every time a page is rendered, so it - # uses an instance variable of ActionView::Base. - def get_cycle(name) - @_cycles = Hash.new if @_cycles.nil? - return @_cycles[name] - end - - def set_cycle(name, cycle_object) - @_cycles = Hash.new if @_cycles.nil? - @_cycles[name] = cycle_object - end - - AUTO_LINK_RE = / - ( # leading text - <\w+.*?>| # leading HTML tag, or - [^=!:'"\/]| # leading punctuation, or - ^ # beginning of line - ) - ( - (?:http[s]?:\/\/)| # protocol spec, or - (?:www\.) # www.* - ) - ( - ([\w]+[=?&\/.-]?)* # url segment - \w+[\/]? # url tail - (?:\#\w*)? # trailing anchor - ) - ([[:punct:]]|\s|<|$) # trailing text - /x unless const_defined?(:AUTO_LINK_RE) - - # Turns all urls into clickable links. If a block is given, each url - # is yielded and the result is used as the link text. Example: - # auto_link_urls(post.body, :all, :target => '_blank') do |text| - # truncate(text, 15) - # end - def auto_link_urls(text, href_options = {}) - extra_options = tag_options(href_options.stringify_keys) || "" - text.gsub(AUTO_LINK_RE) do - all, a, b, c, d = $&, $1, $2, $3, $5 - if a =~ /#{text}#{d}) - end - end - end - - # Turns all email addresses into clickable links. If a block is given, - # each email is yielded and the result is used as the link text. - # Example: - # auto_link_email_addresses(post.body) do |text| - # truncate(text, 15) - # end - def auto_link_email_addresses(text) - text.gsub(/([\w\.!#\$%\-+.]+@[A-Za-z0-9\-]+(\.[A-Za-z0-9\-]+)+)/) do - text = $1 - text = yield(text) if block_given? - %{#{text}} - end - end - end - end -end diff --git a/tracks/vendor/rails/actionpack/lib/action_view/helpers/upload_progress_helper.rb b/tracks/vendor/rails/actionpack/lib/action_view/helpers/upload_progress_helper.rb deleted file mode 100644 index 00e5f25f..00000000 --- a/tracks/vendor/rails/actionpack/lib/action_view/helpers/upload_progress_helper.rb +++ /dev/null @@ -1,433 +0,0 @@ -module ActionView - module Helpers - # == THIS IS AN EXPERIMENTAL FEATURE - # - # Which means that it doesn't yet work on all systems. We're still working on full - # compatibility. It's thus not advised to use this unless you've verified it to work - # fully on all the systems that is a part of your environment. Consider this an extended - # preview. - # - # Provides a set of methods to be used in your views to help with the - # rendering of Ajax enabled status updating during a multipart upload. - # - # The basic mechanism for upload progress is that the form will post to a - # hidden ", - form_tag_with_upload_progress - ) - end - - def test_form_tag_with_upload_progress_custom - assert_dom_equal( - "

    ", - form_tag_with_upload_progress({:upload_id => 5}, {:begin => "alert('foo')", :finish => "alert('bar')", :frequency => 6, :decay => 7, :target => 'awindow'}) - ) - end -end diff --git a/tracks/vendor/rails/actionpack/test/template/url_helper_test.rb b/tracks/vendor/rails/actionpack/test/template/url_helper_test.rb deleted file mode 100644 index 78ad1855..00000000 --- a/tracks/vendor/rails/actionpack/test/template/url_helper_test.rb +++ /dev/null @@ -1,198 +0,0 @@ -require File.dirname(__FILE__) + '/../abstract_unit' - -require File.dirname(__FILE__) + '/../../lib/action_view/helpers/url_helper' -require File.dirname(__FILE__) + '/../../lib/action_view/helpers/asset_tag_helper' -require File.dirname(__FILE__) + '/../../lib/action_view/helpers/tag_helper' - -RequestMock = Struct.new("Request", :request_uri) - -class UrlHelperTest < Test::Unit::TestCase - include ActionView::Helpers::AssetTagHelper - include ActionView::Helpers::UrlHelper - include ActionView::Helpers::TagHelper - - def setup - @controller = Class.new do - def url_for(options, *parameters_for_method_reference) - "http://www.example.com" - end - end - @controller = @controller.new - end - - # todo: missing test cases - def test_button_to_with_straight_url - assert_dom_equal "
    ", button_to("Hello", "http://www.example.com") - end - - def test_button_to_with_query - assert_dom_equal "
    ", button_to("Hello", "http://www.example.com/q1=v1&q2=v2") - end - - def test_button_to_with_query_and_no_name - assert_dom_equal "
    ", button_to(nil, "http://www.example.com?q1=v1&q2=v2") - end - - def test_button_to_with_javascript_confirm - assert_dom_equal( - "
    ", - button_to("Hello", "http://www.example.com", :confirm => "Are you sure?") - ) - end - - def test_button_to_enabled_disabled - assert_dom_equal( - "
    ", - button_to("Hello", "http://www.example.com", :disabled => false) - ) - assert_dom_equal( - "
    ", - button_to("Hello", "http://www.example.com", :disabled => true) - ) - end - - def test_link_tag_with_straight_url - assert_dom_equal "Hello", link_to("Hello", "http://www.example.com") - end - - def test_link_tag_with_query - assert_dom_equal "Hello", link_to("Hello", "http://www.example.com?q1=v1&q2=v2") - end - - def test_link_tag_with_query_and_no_name - assert_dom_equal "http://www.example.com?q1=v1&q2=v2", link_to(nil, "http://www.example.com?q1=v1&q2=v2") - end - - def test_link_tag_with_custom_onclick - assert_dom_equal "Hello", link_to("Hello", "http://www.example.com", :onclick => "alert('yay!')") - end - - def test_link_tag_with_javascript_confirm - assert_dom_equal( - "Hello", - link_to("Hello", "http://www.example.com", :confirm => "Are you sure?") - ) - assert_dom_equal( - "Hello", - link_to("Hello", "http://www.example.com", :confirm => "You can't possibly be sure, can you?") - ) - assert_dom_equal( - "Hello", - link_to("Hello", "http://www.example.com", :confirm => "You can't possibly be sure,\n can you?") - ) - end - - def test_link_tag_with_popup - assert_dom_equal( - "Hello", - link_to("Hello", "http://www.example.com", :popup => true) - ) - assert_dom_equal( - "Hello", - link_to("Hello", "http://www.example.com", :popup => 'true') - ) - assert_dom_equal( - "Hello", - link_to("Hello", "http://www.example.com", :popup => ['window_name', 'width=300,height=300']) - ) - end - - def test_link_tag_with_popup_and_javascript_confirm - assert_dom_equal( - "Hello", - link_to("Hello", "http://www.example.com", { :popup => true, :confirm => "Fo' sho'?" }) - ) - assert_dom_equal( - "Hello", - link_to("Hello", "http://www.example.com", { :popup => ['window_name', 'width=300,height=300'], :confirm => "Are you serious?" }) - ) - end - - def test_link_tag_using_post_javascript - assert_dom_equal( - "Hello", - link_to("Hello", "http://www.example.com", :post => true) - ) - end - - def test_link_tag_using_post_javascript_and_confirm - assert_dom_equal( - "Hello", - link_to("Hello", "http://www.example.com", :post => true, :confirm => "Are you serious?") - ) - end - - def test_link_tag_using_post_javascript_and_popup - assert_raises(ActionView::ActionViewError) { link_to("Hello", "http://www.example.com", :popup => true, :post => true, :confirm => "Are you serious?") } - end - - def test_link_to_unless - assert_equal "Showing", link_to_unless(true, "Showing", :action => "show", :controller => "weblog") - assert_dom_equal "Listing", link_to_unless(false, "Listing", :action => "list", :controller => "weblog") - assert_equal "Showing", link_to_unless(true, "Showing", :action => "show", :controller => "weblog", :id => 1) - assert_equal "Showing", link_to_unless(true, "Showing", :action => "show", :controller => "weblog", :id => 1) { |name, options, html_options, *parameters_for_method_reference| - "#{name}" - } - assert_equal "Showing", link_to_unless(true, "Showing", :action => "show", :controller => "weblog", :id => 1) { |name| - "#{name}" - } - assert_equal "test", link_to_unless(true, "Showing", :action => "show", :controller => "weblog", :id => 1) { - "test" - } - end - - def test_link_to_if - assert_equal "Showing", link_to_if(false, "Showing", :action => "show", :controller => "weblog") - assert_dom_equal "Listing", link_to_if(true, "Listing", :action => "list", :controller => "weblog") - assert_equal "Showing", link_to_if(false, "Showing", :action => "show", :controller => "weblog", :id => 1) - end - - - def xtest_link_unless_current - @request = RequestMock.new("http://www.example.com") - assert_equal "Showing", link_to_unless_current("Showing", :action => "show", :controller => "weblog") - @request = RequestMock.new("http://www.example.org") - assert "Listing", link_to_unless_current("Listing", :action => "list", :controller => "weblog") - - @request = RequestMock.new("http://www.example.com") - assert_equal "Showing", link_to_unless_current("Showing", :action => "show", :controller => "weblog", :id => 1) - end - - def test_mail_to - assert_dom_equal "david@loudthinking.com", mail_to("david@loudthinking.com") - assert_dom_equal "David Heinemeier Hansson", mail_to("david@loudthinking.com", "David Heinemeier Hansson") - assert_dom_equal( - "David Heinemeier Hansson", - mail_to("david@loudthinking.com", "David Heinemeier Hansson", "class" => "admin") - ) - assert_equal mail_to("david@loudthinking.com", "David Heinemeier Hansson", "class" => "admin"), - mail_to("david@loudthinking.com", "David Heinemeier Hansson", :class => "admin") - end - - def test_mail_to_with_javascript - assert_dom_equal "", mail_to("me@domain.com", "My email", :encode => "javascript") - end - - def test_mail_with_options - assert_dom_equal( - %(My email), - mail_to("me@example.com", "My email", :cc => "ccaddress@example.com", :bcc => "bccaddress@example.com", :subject => "This is an example email", :body => "This is the body of the message.") - ) - end - - def test_mail_to_with_hex - assert_dom_equal "My email", mail_to("me@domain.com", "My email", :encode => "hex") - end - - def test_mail_to_with_replace_options - assert_dom_equal "wolfgang(at)stufenlos(dot)net", mail_to("wolfgang@stufenlos.net", nil, :replace_at => "(at)", :replace_dot => "(dot)") - assert_dom_equal "me(at)domain.com", mail_to("me@domain.com", nil, :encode => "hex", :replace_at => "(at)") - assert_dom_equal "My email", mail_to("me@domain.com", "My email", :encode => "hex", :replace_at => "(at)") - assert_dom_equal "me(at)domain(dot)com", mail_to("me@domain.com", nil, :encode => "hex", :replace_at => "(at)", :replace_dot => "(dot)") - assert_dom_equal "", mail_to("me@domain.com", "My email", :encode => "javascript", :replace_at => "(at)", :replace_dot => "(dot)") - end - - def test_link_with_nil_html_options - assert_dom_equal "Hello", link_to("Hello", {:action => 'myaction'}, nil) - end -end diff --git a/tracks/vendor/rails/actionpack/test/testing_sandbox.rb b/tracks/vendor/rails/actionpack/test/testing_sandbox.rb deleted file mode 100644 index b21f4117..00000000 --- a/tracks/vendor/rails/actionpack/test/testing_sandbox.rb +++ /dev/null @@ -1,26 +0,0 @@ -module TestingSandbox - - # This whole thing *could* be much simpler, but I don't think Tempfile, - # popen and others exist on all platforms (like Windows). - def execute_in_sandbox(code) - test_name = "#{File.dirname(__FILE__)}/test.#{$$}.rb" - res_name = "#{File.dirname(__FILE__)}/test.#{$$}.out" - - File.open(test_name, "w+") do |file| - file.write(<<-CODE) - $:.unshift "../lib" - block = Proc.new do - #{code} - end - print block.call - CODE - end - - system("ruby #{test_name} > #{res_name}") or raise "could not run test in sandbox" - File.read(res_name) - ensure - File.delete(test_name) rescue nil - File.delete(res_name) rescue nil - end - -end diff --git a/tracks/vendor/rails/actionwebservice/CHANGELOG b/tracks/vendor/rails/actionwebservice/CHANGELOG deleted file mode 100644 index 977e2da9..00000000 --- a/tracks/vendor/rails/actionwebservice/CHANGELOG +++ /dev/null @@ -1,194 +0,0 @@ -*1.0.0* (December 13th, 2005) - -* Become part of Rails 1.0 - - -*0.9.4* (December 7th, 2005) - -* Update from LGPL to MIT license as per Minero Aoki's permission. [Marcel Molina Jr.] - -* Rename Version constant to VERSION. #2802 [Marcel Molina Jr.] - -* Fix that XML-RPC date/time values did not have well-defined behaviour (#2516, #2534). This fix has one caveat, in that we can't support pre-1970 dates from XML-RPC clients. - - -*0.9.3* (November 7th, 2005) - -* Upgraded to Action Pack 1.11.0 and Active Record 1.13.0 - - -*0.9.2* (October 26th, 2005) - -* Upgraded to Action Pack 1.10.2 and Active Record 1.12.2 - - -*0.9.1* (October 19th, 2005) - -* Upgraded to Action Pack 1.10.1 and Active Record 1.12.1 - - -*0.9.0* (October 16th, 2005) - -* Fix invalid XML request generation bug in test_invoke [Ken Barker] - -* Add XML-RPC 'system.multicall' support #1941 [jbonnar] - -* Fix duplicate XSD entries for custom types shared across delegated/layered services #1729 [Tyler Kovacs] - -* Allow multiple invocations in the same test method #1720 [dkhawk] - -* Added ActionWebService::API::Base.soap_client and ActionWebService::API::Base.xmlrpc_client helper methods to create the internal clients for an API, useful for testing from ./script/console - -* ActionWebService now always returns UTF-8 responses. - - -*0.8.1* (11 July, 2005) - -* Fix scaffolding for Action Pack controller changes - - -*0.8.0* (6 July, 2005) - -* Fix WSDL generation by aliasing #inherited instead of trying to overwrite it, or the WSDL action may end up not being defined in the controller - -* Add ActionController::Base.wsdl_namespace option, to allow overriding of the namespace used in generated WSDL and SOAP messages. This is equivalent to the [WebService(Namespace = "Value")] attribute in .NET. - -* Add workaround for Ruby 1.8.3's SOAP4R changing the return value of SOAP::Mapping::Registry#find_mapped_soap_class #1414 [Shugo Maeda] - -* Fix moduled controller URLs in WSDL, and add unit test to verify the generated URL #1428 - -* Fix scaffolding template paths, it was broken on Win32 - -* Fix that functional testing of :layered controllers failed when using the SOAP protocol - -* Allow invocation filters in :direct controllers as well, as they have access to more information regarding the web service request than ActionPack filters - -* Add support for a :base64 signature type #1272 [Shugo Maeda] - -* Fix that boolean fields were not rendered correctly in scaffolding - -* Fix that scaffolding was not working for :delegated dispatching - -* Add support for structured types as input parameters to scaffolding, this should let one test the blogging APIs using scaffolding as well - -* Fix that generated WSDL was not using relative_url_root for base URI #1210 [Shugo Maeda] - -* Use UTF-8 encoding by default for SOAP responses, but if an encoding is supplied by caller, use that for the response #1211 [Shugo Maeda, NAKAMURA Hiroshi] - -* If the WSDL was retrieved over HTTPS, use HTTPS URLs in the WSDL too - -* Fix that casting change in 0.7.0 would convert nil values to the default value for the type instead of leaving it as nil - - -*0.7.1* (20th April, 2005) - -* Depend on Active Record 1.10.1 and Action Pack 1.8.1 - - -*0.7.0* (19th April, 2005) - -* When casting structured types, don't try to send obj.name= unless obj responds to it, causes casting to be less likely to fail for XML-RPC - -* Add scaffolding via ActionController::Base.web_service_scaffold for quick testing using a web browser - -* ActionWebService::API::Base#api_methods now returns a hash containing ActionWebService::API::Method objects instead of hashes. However, ActionWebService::API::Method defines a #[]() backwards compatibility method so any existing code utilizing this will still work. - -* The :layered dispatching mode can now be used with SOAP as well, allowing you to support SOAP and XML-RPC clients for APIs like the metaWeblog API - -* Remove ActiveRecordSoapMarshallable workaround, see #912 for details - -* Generalize casting code to be used by both SOAP and XML-RPC (previously, it was only XML-RPC) - -* Ensure return value is properly cast as well, fixes XML-RPC interoperability with Ecto and possibly other clients - -* Include backtraces in 500 error responses for failed request parsing, and remove "rescue nil" statements obscuring real errors for XML-RPC - -* Perform casting of struct members even if the structure is already of the correct type, so that the type we specify for the struct member is always the type of the value seen by the API implementation - - -*0.6.2* (27th March, 2005) - -* Allow method declarations for direct dispatching to declare parameters as well. We treat an arity of < 0 or > 0 as an indication that we should send through parameters. Closes #939. - - -*0.6.1* (22th March, 2005) - -* Fix that method response QNames mismatched with that declared in the WSDL, makes SOAP::WSDLDriverFactory work against AWS again - -* Fix that @request.env was being modified, instead, dup the value gotten from env - -* Fix XML-RPC example to use :layered mode, so it works again - -* Support casting '0' or 0 into false, and '1' or 1 into true, when expecting a boolean value - -* Fix that SOAP fault response fault code values were not QName's #804 - - -*0.6.0* (7th March, 2005) - -* Add action_controller/test_invoke, used for integrating AWS with the Rails testing infrastructure - -* Allow passing through options to the SOAP RPC driver for the SOAP client - -* Make the SOAP WS marshaler use #columns to decide which fields to marshal as well, avoids providing attributes brought in by associations - -* Add ActionWebService::API::Base.allow_active_record_expects option, with a default of false. Setting this to true will allow specifying ActiveRecord::Base model classes in :expects. API writers should take care to validate the received ActiveRecord model objects when turning it on, and/or have an authentication mechanism in place to reduce the security risk. - -* Improve error message reporting. Bugs in either AWS or the web service itself will send back a protocol-specific error report message if possible, otherwise, provide as much detail as possible. - -* Removed type checking of received parameters, and perform casting for XML-RPC if possible, but fallback to the received parameters if casting fails, closes #677 - -* Refactored SOAP and XML-RPC marshaling and encoding into a small library devoted exclusively to protocol specifics, also cleaned up the SOAP marshaling approach, so that array and custom type marshaling should be a bit faster. - -* Add namespaced XML-RPC method name support, closes #678 - -* Replace '::' with '..' in fully qualified type names for marshaling and WSDL. This improves interoperability with .NET, and closes #676. - - -*0.5.0* (24th February, 2005) - - * lib/action_service/dispatcher*: replace "router" fragments with - one file for Action Controllers, moves dispatching work out of - the container - * lib/*,test/*,examples/*: rename project to - ActionWebService. prefix all generic "service" type names with web_. - update all using code as well as the RDoc. - * lib/action_service/router/wsdl.rb: ensure that #wsdl is - defined in the final container class, or the new ActionPack - filtering will exclude it - * lib/action_service/struct.rb,test/struct_test.rb: create a - default #initialize on inherit that accepts a Hash containing - the default member values - * lib/action_service/api/action_controller.rb: add support and - tests for #client_api in controller - * test/router_wsdl_test.rb: add tests to ensure declared - service names don't contain ':', as ':' causes interoperability - issues - * lib/*, test/*: rename "interface" concept to "api", and change all - related uses to reflect this change. update all uses of Inflector - to call the method on String instead. - * test/api_test.rb: add test to ensure API definition not - instantiatable - * lib/action_service/invocation.rb: change @invocation_params to - @method_params - * lib/*: update RDoc - * lib/action_service/struct.rb: update to support base types - * lib/action_service/support/signature.rb: support the notion of - "base types" in signatures, with well-known unambiguous names such as :int, - :bool, etc, which map to the correct Ruby class. accept the same names - used by ActiveRecord as well as longer versions of each, as aliases. - * examples/*: update for seperate API definition updates - * lib/action_service/*, test/*: extensive refactoring: define API methods in - a seperate class, and specify it wherever used with 'service_api'. - this makes writing a client API for accessing defined API methods - with ActionWebService really easy. - * lib/action_service/container.rb: fix a bug in default call - handling for direct dispatching, and add ActionController filter - support for direct dispatching. - * test/router_action_controller_test.rb: add tests to ensure - ActionController filters are actually called. - * test/protocol_soap_test.rb: add more tests for direct dispatching. - -0.3.0 - - * First public release diff --git a/tracks/vendor/rails/actionwebservice/MIT-LICENSE b/tracks/vendor/rails/actionwebservice/MIT-LICENSE deleted file mode 100644 index 528941e8..00000000 --- a/tracks/vendor/rails/actionwebservice/MIT-LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -Copyright (C) 2005 Leon Breedt - -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 --git a/tracks/vendor/rails/actionwebservice/README b/tracks/vendor/rails/actionwebservice/README deleted file mode 100644 index 78b91f08..00000000 --- a/tracks/vendor/rails/actionwebservice/README +++ /dev/null @@ -1,364 +0,0 @@ -= Action Web Service -- Serving APIs on rails - -Action Web Service provides a way to publish interoperable web service APIs with -Rails without spending a lot of time delving into protocol details. - - -== Features - -* SOAP RPC protocol support -* Dynamic WSDL generation for APIs -* XML-RPC protocol support -* Clients that use the same API definitions as the server for - easy interoperability with other Action Web Service based applications -* Type signature hints to improve interoperability with static languages -* Active Record model class support in signatures - - -== Defining your APIs - -You specify the methods you want to make available as API methods in an -ActionWebService::API::Base derivative, and then specify this API -definition class wherever you want to use that API. - -The implementation of the methods is done separately from the API -specification. - - -==== Method name inflection - -Action Web Service will camelcase the method names according to Rails Inflector -rules for the API visible to public callers. What this means, for example, -is that the method names in generated WSDL will be camelcased, and callers will -have to supply the camelcased name in their requests for the request to -succeed. - -If you do not desire this behaviour, you can turn it off with the -ActionWebService::API::Base +inflect_names+ option. - - -==== Inflection examples - - :add => Add - :find_all => FindAll - - -==== Disabling inflection - - class PersonAPI < ActionWebService::API::Base - inflect_names false - end - - -==== API definition example - - class PersonAPI < ActionWebService::API::Base - api_method :add, :expects => [:string, :string, :bool], :returns => [:int] - api_method :remove, :expects => [:int], :returns => [:bool] - end - -==== API usage example - - class PersonController < ActionController::Base - web_service_api PersonAPI - - def add - end - - def remove - end - end - - -== Publishing your APIs - -Action Web Service uses Action Pack to process protocol requests. There are two -modes of dispatching protocol requests, _Direct_, and _Delegated_. - - -=== Direct dispatching - -This is the default mode. In this mode, public controller instance methods -implement the API methods, and parameters are passed through to the methods in -accordance with the API specification. - -The return value of the method is sent back as the return value to the -caller. - -In this mode, a special api action is generated in the target -controller to unwrap the protocol request, forward it on to the relevant method -and send back the wrapped return value. This action must not be -overridden. - -==== Direct dispatching example - - class PersonController < ApplicationController - web_service_api PersonAPI - - def add - end - - def remove - end - end - - class PersonAPI < ActionWebService::API::Base - ... - end - - -For this example, protocol requests for +Add+ and +Remove+ methods sent to -/person/api will be routed to the controller methods +add+ and +remove+. - - -=== Delegated dispatching - -This mode can be turned on by setting the +web_service_dispatching_mode+ option -in a controller to :delegated. - -In this mode, the controller contains one or more web service objects (objects -that implement an ActionWebService::API::Base definition). These web service -objects are each mapped onto one controller action only. - -==== Delegated dispatching example - - class ApiController < ApplicationController - web_service_dispatching_mode :delegated - - web_service :person, PersonService.new - end - - class PersonService < ActionWebService::Base - web_service_api PersonAPI - - def add - end - - def remove - end - end - - class PersonAPI < ActionWebService::API::Base - ... - end - - -For this example, all protocol requests for +PersonService+ are -sent to the /api/person action. - -The /api/person action is generated when the +web_service+ -method is called. This action must not be overridden. - -Other controller actions (actions that aren't the target of a +web_service+ call) -are ignored for ActionWebService purposes, and can do normal action tasks. - - -=== Layered dispatching - -This mode can be turned on by setting the +web_service_dispatching_mode+ option -in a controller to :layered. - -This mode is similar to _delegated_ mode, in that multiple web service objects -can be attached to one controller, however, all protocol requests are sent to a -single endpoint. - -Use this mode when you want to share code between XML-RPC and SOAP clients, -for APIs where the XML-RPC method names have prefixes. An example of such -a method name would be blogger.newPost. - - -==== Layered dispatching example - - - class ApiController < ApplicationController - web_service_dispatching_mode :layered - - web_service :mt, MovableTypeService.new - web_service :blogger, BloggerService.new - web_service :metaWeblog, MetaWeblogService.new - end - - class MovableTypeService < ActionWebService::Base - ... - end - - class BloggerService < ActionWebService::Base - ... - end - - class MetaWeblogService < ActionWebService::API::Base - ... - end - - -For this example, an XML-RPC call for a method with a name like -mt.getCategories will be sent to the getCategories -method on the :mt service. - - -== Customizing WSDL generation - -You can customize the names used for the SOAP bindings in the generated -WSDL by using the wsdl_service_name option in a controller: - - class WsController < ApplicationController - wsdl_service_name 'MyApp' - end - -You can also customize the namespace used in the generated WSDL for -custom types and message definition types: - - class WsController < ApplicationController - wsdl_namespace 'http://my.company.com/app/wsapi' - end - -The default namespace used is 'urn:ActionWebService', if you don't supply -one. - - -== ActionWebService and UTF-8 - -If you're going to be sending back strings containing non-ASCII UTF-8 -characters using the :string data type, you need to make sure that -Ruby is using UTF-8 as the default encoding for its strings. - -The default in Ruby is to use US-ASCII encoding for strings, which causes a string -validation check in the Ruby SOAP library to fail and your string to be sent -back as a Base-64 value, which may confuse clients that expected strings -because of the WSDL. - -Two ways of setting the default string encoding are: - -* Start Ruby using the -Ku command-line option to the Ruby executable -* Set the $KCODE flag in config/environment.rb to the - string 'UTF8' - - -== Testing your APIs - - -=== Functional testing - -You can perform testing of your APIs by creating a functional test for the -controller dispatching the API, and calling #invoke in the test case to -perform the invocation. - -Example: - - class PersonApiControllerTest < Test::Unit::TestCase - def setup - @controller = PersonController.new - @request = ActionController::TestRequest.new - @response = ActionController::TestResponse.new - end - - def test_add - result = invoke :remove, 1 - assert_equal true, result - end - end - -This example invokes the API method test, defined on -the PersonController, and returns the result. - - -=== Scaffolding - -You can also test your APIs with a web browser by attaching scaffolding -to the controller. - -Example: - - class PersonController - web_service_scaffold :invocation - end - -This creates an action named invocation on the PersonController. - -Navigating to this action lets you select the method to invoke, supply the parameters, -and view the result of the invocation. - - -== Using the client support - -Action Web Service includes client classes that can use the same API -definition as the server. The advantage of this approach is that your client -will have the same support for Active Record and structured types as the -server, and can just use them directly, and rely on the marshaling to Do The -Right Thing. - -*Note*: The client support is intended for communication between Ruby on Rails -applications that both use Action Web Service. It may work with other servers, but -that is not its intended use, and interoperability can't be guaranteed, especially -not for .NET web services. - -Web services protocol specifications are complex, and Action Web Service client -support can only be guaranteed to work with a subset. - - -==== Factory created client example - - class BlogManagerController < ApplicationController - web_client_api :blogger, :xmlrpc, 'http://url/to/blog/api/RPC2', :handler_name => 'blogger' - end - - class SearchingController < ApplicationController - web_client_api :google, :soap, 'http://url/to/blog/api/beta', :service_name => 'GoogleSearch' - end - -See ActionWebService::API::ActionController::ClassMethods for more details. - -==== Manually created client example - - class PersonAPI < ActionWebService::API::Base - api_method :find_all, :returns => [[Person]] - end - - soap_client = ActionWebService::Client::Soap.new(PersonAPI, "http://...") - persons = soap_client.find_all - - class BloggerAPI < ActionWebService::API::Base - inflect_names false - api_method :getRecentPosts, :returns => [[Blog::Post]] - end - - blog = ActionWebService::Client::XmlRpc.new(BloggerAPI, "http://.../xmlrpc", :handler_name => "blogger") - posts = blog.getRecentPosts - - -See ActionWebService::Client::Soap and ActionWebService::Client::XmlRpc for more details. - -== Dependencies - -Action Web Service requires that the Action Pack and Active Record are either -available to be required immediately or are accessible as GEMs. - -It also requires a version of Ruby that includes SOAP support in the standard -library. At least version 1.8.2 final (2004-12-25) of Ruby is recommended; this -is the version tested against. - - -== Download - -The latest Action Web Service version can be downloaded from -http://rubyforge.org/projects/actionservice - - -== Installation - -You can install Action Web Service with the following command. - - % [sudo] ruby setup.rb - - -== License - -Action Web Service is released under the MIT license. - - -== Support - -The Ruby on Rails mailing list - -Or, to contact the author, send mail to bitserf@gmail.com - diff --git a/tracks/vendor/rails/actionwebservice/Rakefile b/tracks/vendor/rails/actionwebservice/Rakefile deleted file mode 100644 index 50c6f25a..00000000 --- a/tracks/vendor/rails/actionwebservice/Rakefile +++ /dev/null @@ -1,267 +0,0 @@ -require 'rubygems' -require 'rake' -require 'rake/testtask' -require 'rake/rdoctask' -require 'rake/packagetask' -require 'rake/gempackagetask' -require 'rake/contrib/rubyforgepublisher' -require 'fileutils' -require File.join(File.dirname(__FILE__), 'lib', 'action_web_service', 'version') - -PKG_BUILD = ENV['PKG_BUILD'] ? '.' + ENV['PKG_BUILD'] : '' -PKG_NAME = 'actionwebservice' -PKG_VERSION = ActionWebService::VERSION::STRING + PKG_BUILD -PKG_FILE_NAME = "#{PKG_NAME}-#{PKG_VERSION}" -PKG_DESTINATION = ENV["RAILS_PKG_DESTINATION"] || "../#{PKG_NAME}" - -RELEASE_NAME = "REL #{PKG_VERSION}" - -RUBY_FORGE_PROJECT = "aws" -RUBY_FORGE_USER = "webster132" - -desc "Default Task" -task :default => [ :test ] - - -# Run the unit tests -Rake::TestTask.new { |t| - t.libs << "test" - t.test_files = Dir['test/*_test.rb'] - t.verbose = true -} - - -# Generate the RDoc documentation -Rake::RDocTask.new { |rdoc| - rdoc.rdoc_dir = 'doc' - rdoc.title = "Action Web Service -- Web services for Action Pack" - rdoc.options << '--line-numbers --inline-source --main README --accessor class_inheritable_option=RW' - rdoc.template = "#{ENV['template']}.rb" if ENV['template'] - rdoc.rdoc_files.include('README') - rdoc.rdoc_files.include('CHANGELOG') - rdoc.rdoc_files.include('lib/action_web_service.rb') - rdoc.rdoc_files.include('lib/action_web_service/*.rb') - rdoc.rdoc_files.include('lib/action_web_service/api/*.rb') - rdoc.rdoc_files.include('lib/action_web_service/client/*.rb') - rdoc.rdoc_files.include('lib/action_web_service/container/*.rb') - rdoc.rdoc_files.include('lib/action_web_service/dispatcher/*.rb') - rdoc.rdoc_files.include('lib/action_web_service/protocol/*.rb') - rdoc.rdoc_files.include('lib/action_web_service/support/*.rb') -} - - -# Create compressed packages -spec = Gem::Specification.new do |s| - s.platform = Gem::Platform::RUBY - s.name = PKG_NAME - s.summary = "Web service support for Action Pack." - s.description = %q{Adds WSDL/SOAP and XML-RPC web service support to Action Pack} - s.version = PKG_VERSION - - s.author = "Leon Breedt" - s.email = "bitserf@gmail.com" - s.rubyforge_project = "aws" - s.homepage = "http://www.rubyonrails.org" - - s.add_dependency('actionpack', '= 1.11.2' + PKG_BUILD) - s.add_dependency('activerecord', '= 1.13.2' + PKG_BUILD) - - s.has_rdoc = true - s.requirements << 'none' - s.require_path = 'lib' - s.autorequire = 'action_web_service' - - s.files = [ "Rakefile", "setup.rb", "README", "TODO", "CHANGELOG", "MIT-LICENSE" ] - s.files = s.files + Dir.glob( "examples/**/*" ).delete_if { |item| item.include?( "\.svn" ) } - s.files = s.files + Dir.glob( "lib/**/*" ).delete_if { |item| item.include?( "\.svn" ) } - s.files = s.files + Dir.glob( "test/**/*" ).delete_if { |item| item.include?( "\.svn" ) } -end -Rake::GemPackageTask.new(spec) do |p| - p.gem_spec = spec - p.need_tar = true - p.need_zip = true -end - - -# Publish beta gem -desc "Publish the API documentation" -task :pgem => [:package] do - Rake::SshFilePublisher.new("davidhh@wrath.rubyonrails.org", "public_html/gems/gems", "pkg", "#{PKG_FILE_NAME}.gem").upload - `ssh davidhh@wrath.rubyonrails.org './gemupdate.sh'` -end - -# Publish documentation -desc "Publish the API documentation" -task :pdoc => [:rdoc] do - Rake::SshDirPublisher.new("davidhh@wrath.rubyonrails.org", "public_html/aws", "doc").upload -end - - -def each_source_file(*args) - prefix, includes, excludes, open_file = args - prefix ||= File.dirname(__FILE__) - open_file = true if open_file.nil? - includes ||= %w[lib\/action_web_service\.rb$ lib\/action_web_service\/.*\.rb$] - excludes ||= %w[lib\/action_web_service\/vendor] - Find.find(prefix) do |file_name| - next if file_name =~ /\.svn/ - file_name.gsub!(/^\.\//, '') - continue = false - includes.each do |inc| - if file_name.match(/#{inc}/) - continue = true - break - end - end - next unless continue - excludes.each do |exc| - if file_name.match(/#{exc}/) - continue = false - break - end - end - next unless continue - if open_file - File.open(file_name) do |f| - yield file_name, f - end - else - yield file_name - end - end -end - -desc "Count lines of the AWS source code" -task :lines do - total_lines = total_loc = 0 - puts "Per File:" - each_source_file do |file_name, f| - file_lines = file_loc = 0 - while line = f.gets - file_lines += 1 - next if line =~ /^\s*$/ - next if line =~ /^\s*#/ - file_loc += 1 - end - puts " #{file_name}: Lines #{file_lines}, LOC #{file_loc}" - total_lines += file_lines - total_loc += file_loc - end - puts "Total:" - puts " Lines #{total_lines}, LOC #{total_loc}" -end - -desc "Publish the release files to RubyForge." -task :release => [:package] do - files = ["gem", "tgz", "zip"].map { |ext| "pkg/#{PKG_FILE_NAME}.#{ext}" } - - if RUBY_FORGE_PROJECT then - require 'net/http' - require 'open-uri' - - project_uri = "http://rubyforge.org/projects/#{RUBY_FORGE_PROJECT}/" - project_data = open(project_uri) { |data| data.read } - group_id = project_data[/[?&]group_id=(\d+)/, 1] - raise "Couldn't get group id" unless group_id - - # This echos password to shell which is a bit sucky - if ENV["RUBY_FORGE_PASSWORD"] - password = ENV["RUBY_FORGE_PASSWORD"] - else - print "#{RUBY_FORGE_USER}@rubyforge.org's password: " - password = STDIN.gets.chomp - end - - login_response = Net::HTTP.start("rubyforge.org", 80) do |http| - data = [ - "login=1", - "form_loginname=#{RUBY_FORGE_USER}", - "form_pw=#{password}" - ].join("&") - http.post("/account/login.php", data) - end - - cookie = login_response["set-cookie"] - raise "Login failed" unless cookie - headers = { "Cookie" => cookie } - - release_uri = "http://rubyforge.org/frs/admin/?group_id=#{group_id}" - release_data = open(release_uri, headers) { |data| data.read } - package_id = release_data[/[?&]package_id=(\d+)/, 1] - raise "Couldn't get package id" unless package_id - - first_file = true - release_id = "" - - files.each do |filename| - basename = File.basename(filename) - file_ext = File.extname(filename) - file_data = File.open(filename, "rb") { |file| file.read } - - puts "Releasing #{basename}..." - - release_response = Net::HTTP.start("rubyforge.org", 80) do |http| - release_date = Time.now.strftime("%Y-%m-%d %H:%M") - type_map = { - ".zip" => "3000", - ".tgz" => "3110", - ".gz" => "3110", - ".gem" => "1400" - }; type_map.default = "9999" - type = type_map[file_ext] - boundary = "rubyqMY6QN9bp6e4kS21H4y0zxcvoor" - - query_hash = if first_file then - { - "group_id" => group_id, - "package_id" => package_id, - "release_name" => RELEASE_NAME, - "release_date" => release_date, - "type_id" => type, - "processor_id" => "8000", # Any - "release_notes" => "", - "release_changes" => "", - "preformatted" => "1", - "submit" => "1" - } - else - { - "group_id" => group_id, - "release_id" => release_id, - "package_id" => package_id, - "step2" => "1", - "type_id" => type, - "processor_id" => "8000", # Any - "submit" => "Add This File" - } - end - - query = "?" + query_hash.map do |(name, value)| - [name, URI.encode(value)].join("=") - end.join("&") - - data = [ - "--" + boundary, - "Content-Disposition: form-data; name=\"userfile\"; filename=\"#{basename}\"", - "Content-Type: application/octet-stream", - "Content-Transfer-Encoding: binary", - "", file_data, "" - ].join("\x0D\x0A") - - release_headers = headers.merge( - "Content-Type" => "multipart/form-data; boundary=#{boundary}" - ) - - target = first_file ? "/frs/admin/qrs.php" : "/frs/admin/editrelease.php" - http.post(target + query, data, release_headers) - end - - if first_file then - release_id = release_response.body[/release_id=(\d+)/, 1] - raise("Couldn't get release id") unless release_id - end - - first_file = false - end - end -end diff --git a/tracks/vendor/rails/actionwebservice/TODO b/tracks/vendor/rails/actionwebservice/TODO deleted file mode 100644 index 7c022c14..00000000 --- a/tracks/vendor/rails/actionwebservice/TODO +++ /dev/null @@ -1,32 +0,0 @@ -= Post-1.0 - - Document/Literal SOAP support - - URL-based dispatching, URL identifies method - - - Add :rest dispatching mode, a.l.a. Backpack API. Clean up dispatching - in general. Support vanilla XML-format as a "Rails" protocol? - XML::Simple deserialization into params? - - web_service_dispatching_mode :rest - - def method1(params) - end - - def method2(params) - end - - - /ws/method1 - - /ws/method2 - - - - Allow locking down a controller to only accept messages for a particular - protocol. This will allow us to generate fully conformant error messages - in cases where we currently fudge it if we don't know the protocol. - - - Allow AWS user to participate in typecasting, so they can centralize - workarounds for buggy input in one place - -= Refactoring - - Don't have clean way to go from SOAP Class object to the xsd:NAME type - string -- NaHi possibly looking at remedying this situation diff --git a/tracks/vendor/rails/actionwebservice/examples/googlesearch/README b/tracks/vendor/rails/actionwebservice/examples/googlesearch/README deleted file mode 100644 index 25ccbd23..00000000 --- a/tracks/vendor/rails/actionwebservice/examples/googlesearch/README +++ /dev/null @@ -1,143 +0,0 @@ -= Google Service example - -This example shows how one would implement an API like Google -Search that uses lots of structured types. - -There are examples for "Direct" and "Delegated" dispatching -modes. - -There is also an example for API definition file autoloading. - - -= Running the examples - - 1. Add the files to an Action Web Service enabled Rails project. - - "Direct" example: - - * Copy direct/search_controller.rb to "app/controllers" - in a Rails project. - * Copy direct/google_search_api.rb to "app/apis" - in a Rails project - - "Delegated" example: - - * Copy delegated/search_controller.rb to "app/controllers" - in a Rails project. - * Copy delegated/google_search_service.rb to "lib" - in a Rails project. - - "Autoloading" example: - - * Copy autoloading/google_search_api.rb to "app/apis" (create the directory - if it doesn't exist) in a Rails project. - - * Copy autoloading/google_search_controller.rb "app/controllers" - in a Rails project. - - - 2. Go to the WSDL url in a browser, and check that it looks correct. - - "Direct" and "Delegated" examples: - http://url_to_project/search/wsdl - - "Autoloading" example: - http://url_to_project/google_search/wsdl - - You can compare it to Google's hand-coded WSDL at http://api.google.com/GoogleSearch.wsdl - and see how close (or not) the generated version is. - - Note that I used GoogleSearch as the canonical "best practice" - interoperable example when implementing WSDL/SOAP support, which might - explain extreme similarities :) - - - 3. Test that it works with .NET (Mono in this example): - - $ wget WSDL_URL - $ mv wsdl GoogleSearch.wsdl - $ wsdl -out:GoogleSearch.cs GoogleSearch.wsdl - - Add these lines to the GoogleSearchService class body (be mindful of the - wrapping): - - public static void Main(string[] args) - { - GoogleSearchResult result; - GoogleSearchService service; - - service = new GoogleSearchService(); - result = service.doGoogleSearch("myApiKey", "my query", 10, 30, true, "restrict", false, "lr", "ie", "oe"); - System.Console.WriteLine("documentFiltering: {0}", result.documentFiltering); - System.Console.WriteLine("searchComments: {0}", result.searchComments); - System.Console.WriteLine("estimatedTotalResultsCount: {0}", result.estimatedTotalResultsCount); - System.Console.WriteLine("estimateIsExact: {0}", result.estimateIsExact); - System.Console.WriteLine("resultElements:"); - foreach (ResultElement element in result.resultElements) { - System.Console.WriteLine("\tsummary: {0}", element.summary); - System.Console.WriteLine("\tURL: {0}", element.URL); - System.Console.WriteLine("\tsnippet: {0}", element.snippet); - System.Console.WriteLine("\ttitle: {0}", element.title); - System.Console.WriteLine("\tcachedSize: {0}", element.cachedSize); - System.Console.WriteLine("\trelatedInformationPresent: {0}", element.relatedInformationPresent); - System.Console.WriteLine("\thostName: {0}", element.hostName); - System.Console.WriteLine("\tdirectoryCategory: {0}", element.directoryCategory.fullViewableName); - System.Console.WriteLine("\tdirectoryTitle: {0}", element.directoryTitle); - } - System.Console.WriteLine("searchQuery: {0}", result.searchQuery); - System.Console.WriteLine("startIndex: {0}", result.startIndex); - System.Console.WriteLine("endIndex: {0}", result.endIndex); - System.Console.WriteLine("searchTips: {0}", result.searchTips); - System.Console.WriteLine("directoryCategories:"); - foreach (DirectoryCategory cat in result.directoryCategories) { - System.Console.WriteLine("\t{0} ({1})", cat.fullViewableName, cat.specialEncoding); - } - System.Console.WriteLine("searchTime: {0}", result.searchTime); - } - - Now compile and run: - - $ mcs -reference:System.Web.Services GoogleSearch.cs - $ mono GoogleSearch.exe - - - If you had the application running (on the same host you got - the WSDL from), you should see something like this: - - - documentFiltering: True - searchComments: - estimatedTotalResultsCount: 322000 - estimateIsExact: False - resultElements: - summary: ONlamp.com: Rolling with Ruby on Rails - URL: http://www.onlamp.com/pub/a/onlamp/2005/01/20/rails.html - snippet: Curt Hibbs shows off Ruby on Rails by building a simple ... - title: Teh Railz0r - cachedSize: Almost no lines of code! - relatedInformationPresent: True - hostName: rubyonrails.com - directoryCategory: Web Development - directoryTitle: - searchQuery: http://www.google.com/search?q=ruby+on+rails - startIndex: 10 - endIndex: 40 - searchTips: "on" is a very common word and was not included in your search [details] - directoryCategories: - Web Development (UTF-8) - Programming (US-ASCII) - searchTime: 1E-06 - - - Also, if an API method throws an exception, it will be sent back to the - caller in the protocol's exception format, so they should get an exception - thrown on their side with a meaningful error message. - - If you don't like this behaviour, you can do: - - class MyController < ActionController::Base - web_service_exception_reporting false - end - - 4. Crack open a beer. Publishing APIs for working with the same model as - your Rails web app should be easy from now on :) diff --git a/tracks/vendor/rails/actionwebservice/examples/googlesearch/autoloading/google_search_api.rb b/tracks/vendor/rails/actionwebservice/examples/googlesearch/autoloading/google_search_api.rb deleted file mode 100644 index ed69fed7..00000000 --- a/tracks/vendor/rails/actionwebservice/examples/googlesearch/autoloading/google_search_api.rb +++ /dev/null @@ -1,50 +0,0 @@ -class DirectoryCategory < ActionWebService::Struct - member :fullViewableName, :string - member :specialEncoding, :string -end - -class ResultElement < ActionWebService::Struct - member :summary, :string - member :URL, :string - member :snippet, :string - member :title, :string - member :cachedSize, :string - member :relatedInformationPresent, :bool - member :hostName, :string - member :directoryCategory, DirectoryCategory - member :directoryTitle, :string -end - -class GoogleSearchResult < ActionWebService::Struct - member :documentFiltering, :bool - member :searchComments, :string - member :estimatedTotalResultsCount, :int - member :estimateIsExact, :bool - member :resultElements, [ResultElement] - member :searchQuery, :string - member :startIndex, :int - member :endIndex, :int - member :searchTips, :string - member :directoryCategories, [DirectoryCategory] - member :searchTime, :float -end - -class GoogleSearchAPI < ActionWebService::API::Base - inflect_names false - - api_method :doGetCachedPage, :returns => [:string], :expects => [{:key=>:string}, {:url=>:string}] - api_method :doGetSpellingSuggestion, :returns => [:string], :expects => [{:key=>:string}, {:phrase=>:string}] - - api_method :doGoogleSearch, :returns => [GoogleSearchResult], :expects => [ - {:key=>:string}, - {:q=>:string}, - {:start=>:int}, - {:maxResults=>:int}, - {:filter=>:bool}, - {:restrict=>:string}, - {:safeSearch=>:bool}, - {:lr=>:string}, - {:ie=>:string}, - {:oe=>:string} - ] -end diff --git a/tracks/vendor/rails/actionwebservice/examples/googlesearch/autoloading/google_search_controller.rb b/tracks/vendor/rails/actionwebservice/examples/googlesearch/autoloading/google_search_controller.rb deleted file mode 100644 index c62e869d..00000000 --- a/tracks/vendor/rails/actionwebservice/examples/googlesearch/autoloading/google_search_controller.rb +++ /dev/null @@ -1,57 +0,0 @@ -class GoogleSearchController < ApplicationController - wsdl_service_name 'GoogleSearch' - - def doGetCachedPage - "i am a cached page. my key was %s, url was %s" % [@params['key'], @params['url']] - end - - def doSpellingSuggestion - "%s: Did you mean '%s'?" % [@params['key'], @params['phrase']] - end - - def doGoogleSearch - resultElement = ResultElement.new - resultElement.summary = "ONlamp.com: Rolling with Ruby on Rails" - resultElement.URL = "http://www.onlamp.com/pub/a/onlamp/2005/01/20/rails.html" - resultElement.snippet = "Curt Hibbs shows off Ruby on Rails by building a simple application that requires " + - "almost no Ruby experience. ... Rolling with Ruby on Rails. ..." - resultElement.title = "Teh Railz0r" - resultElement.cachedSize = "Almost no lines of code!" - resultElement.relatedInformationPresent = true - resultElement.hostName = "rubyonrails.com" - resultElement.directoryCategory = category("Web Development", "UTF-8") - - result = GoogleSearchResult.new - result.documentFiltering = @params['filter'] - result.searchComments = "" - result.estimatedTotalResultsCount = 322000 - result.estimateIsExact = false - result.resultElements = [resultElement] - result.searchQuery = "http://www.google.com/search?q=ruby+on+rails" - result.startIndex = @params['start'] - result.endIndex = @params['start'] + @params['maxResults'] - result.searchTips = "\"on\" is a very common word and was not included in your search [details]" - result.searchTime = 0.000001 - - # For Mono, we have to clone objects if they're referenced by more than one place, otherwise - # the Ruby SOAP collapses them into one instance and uses references all over the - # place, confusing Mono. - # - # This has recently been fixed: - # http://bugzilla.ximian.com/show_bug.cgi?id=72265 - result.directoryCategories = [ - category("Web Development", "UTF-8"), - category("Programming", "US-ASCII"), - ] - - result - end - - private - def category(name, encoding) - cat = DirectoryCategory.new - cat.fullViewableName = name.dup - cat.specialEncoding = encoding.dup - cat - end -end diff --git a/tracks/vendor/rails/actionwebservice/examples/googlesearch/delegated/google_search_service.rb b/tracks/vendor/rails/actionwebservice/examples/googlesearch/delegated/google_search_service.rb deleted file mode 100644 index ade354d8..00000000 --- a/tracks/vendor/rails/actionwebservice/examples/googlesearch/delegated/google_search_service.rb +++ /dev/null @@ -1,108 +0,0 @@ -class DirectoryCategory < ActionWebService::Struct - member :fullViewableName, :string - member :specialEncoding, :string -end - -class ResultElement < ActionWebService::Struct - member :summary, :string - member :URL, :string - member :snippet, :string - member :title, :string - member :cachedSize, :string - member :relatedInformationPresent, :bool - member :hostName, :string - member :directoryCategory, DirectoryCategory - member :directoryTitle, :string -end - -class GoogleSearchResult < ActionWebService::Struct - member :documentFiltering, :bool - member :searchComments, :string - member :estimatedTotalResultsCount, :int - member :estimateIsExact, :bool - member :resultElements, [ResultElement] - member :searchQuery, :string - member :startIndex, :int - member :endIndex, :int - member :searchTips, :string - member :directoryCategories, [DirectoryCategory] - member :searchTime, :float -end - -class GoogleSearchAPI < ActionWebService::API::Base - inflect_names false - - api_method :doGetCachedPage, :returns => [:string], :expects => [{:key=>:string}, {:url=>:string}] - api_method :doGetSpellingSuggestion, :returns => [:string], :expects => [{:key=>:string}, {:phrase=>:string}] - - api_method :doGoogleSearch, :returns => [GoogleSearchResult], :expects => [ - {:key=>:string}, - {:q=>:string}, - {:start=>:int}, - {:maxResults=>:int}, - {:filter=>:bool}, - {:restrict=>:string}, - {:safeSearch=>:bool}, - {:lr=>:string}, - {:ie=>:string}, - {:oe=>:string} - ] -end - -class GoogleSearchService < ActionWebService::Base - web_service_api GoogleSearchAPI - - def doGetCachedPage(key, url) - "i am a cached page" - end - - def doSpellingSuggestion(key, phrase) - "Did you mean 'teh'?" - end - - def doGoogleSearch(key, q, start, maxResults, filter, restrict, safeSearch, lr, ie, oe) - resultElement = ResultElement.new - resultElement.summary = "ONlamp.com: Rolling with Ruby on Rails" - resultElement.URL = "http://www.onlamp.com/pub/a/onlamp/2005/01/20/rails.html" - resultElement.snippet = "Curt Hibbs shows off Ruby on Rails by building a simple application that requires " + - "almost no Ruby experience. ... Rolling with Ruby on Rails. ..." - resultElement.title = "Teh Railz0r" - resultElement.cachedSize = "Almost no lines of code!" - resultElement.relatedInformationPresent = true - resultElement.hostName = "rubyonrails.com" - resultElement.directoryCategory = category("Web Development", "UTF-8") - - result = GoogleSearchResult.new - result.documentFiltering = filter - result.searchComments = "" - result.estimatedTotalResultsCount = 322000 - result.estimateIsExact = false - result.resultElements = [resultElement] - result.searchQuery = "http://www.google.com/search?q=ruby+on+rails" - result.startIndex = start - result.endIndex = start + maxResults - result.searchTips = "\"on\" is a very common word and was not included in your search [details]" - result.searchTime = 0.000001 - - # For Mono, we have to clone objects if they're referenced by more than one place, otherwise - # the Ruby SOAP collapses them into one instance and uses references all over the - # place, confusing Mono. - # - # This has recently been fixed: - # http://bugzilla.ximian.com/show_bug.cgi?id=72265 - result.directoryCategories = [ - category("Web Development", "UTF-8"), - category("Programming", "US-ASCII"), - ] - - result - end - - private - def category(name, encoding) - cat = DirectoryCategory.new - cat.fullViewableName = name.dup - cat.specialEncoding = encoding.dup - cat - end -end diff --git a/tracks/vendor/rails/actionwebservice/examples/googlesearch/delegated/search_controller.rb b/tracks/vendor/rails/actionwebservice/examples/googlesearch/delegated/search_controller.rb deleted file mode 100644 index 6525921b..00000000 --- a/tracks/vendor/rails/actionwebservice/examples/googlesearch/delegated/search_controller.rb +++ /dev/null @@ -1,7 +0,0 @@ -require 'google_search_service' - -class SearchController < ApplicationController - wsdl_service_name 'GoogleSearch' - web_service_dispatching_mode :delegated - web_service :beta3, GoogleSearchService.new -end diff --git a/tracks/vendor/rails/actionwebservice/examples/googlesearch/direct/google_search_api.rb b/tracks/vendor/rails/actionwebservice/examples/googlesearch/direct/google_search_api.rb deleted file mode 100644 index ed69fed7..00000000 --- a/tracks/vendor/rails/actionwebservice/examples/googlesearch/direct/google_search_api.rb +++ /dev/null @@ -1,50 +0,0 @@ -class DirectoryCategory < ActionWebService::Struct - member :fullViewableName, :string - member :specialEncoding, :string -end - -class ResultElement < ActionWebService::Struct - member :summary, :string - member :URL, :string - member :snippet, :string - member :title, :string - member :cachedSize, :string - member :relatedInformationPresent, :bool - member :hostName, :string - member :directoryCategory, DirectoryCategory - member :directoryTitle, :string -end - -class GoogleSearchResult < ActionWebService::Struct - member :documentFiltering, :bool - member :searchComments, :string - member :estimatedTotalResultsCount, :int - member :estimateIsExact, :bool - member :resultElements, [ResultElement] - member :searchQuery, :string - member :startIndex, :int - member :endIndex, :int - member :searchTips, :string - member :directoryCategories, [DirectoryCategory] - member :searchTime, :float -end - -class GoogleSearchAPI < ActionWebService::API::Base - inflect_names false - - api_method :doGetCachedPage, :returns => [:string], :expects => [{:key=>:string}, {:url=>:string}] - api_method :doGetSpellingSuggestion, :returns => [:string], :expects => [{:key=>:string}, {:phrase=>:string}] - - api_method :doGoogleSearch, :returns => [GoogleSearchResult], :expects => [ - {:key=>:string}, - {:q=>:string}, - {:start=>:int}, - {:maxResults=>:int}, - {:filter=>:bool}, - {:restrict=>:string}, - {:safeSearch=>:bool}, - {:lr=>:string}, - {:ie=>:string}, - {:oe=>:string} - ] -end diff --git a/tracks/vendor/rails/actionwebservice/examples/googlesearch/direct/search_controller.rb b/tracks/vendor/rails/actionwebservice/examples/googlesearch/direct/search_controller.rb deleted file mode 100644 index 7c69f022..00000000 --- a/tracks/vendor/rails/actionwebservice/examples/googlesearch/direct/search_controller.rb +++ /dev/null @@ -1,58 +0,0 @@ -class SearchController < ApplicationController - web_service_api :google_search - wsdl_service_name 'GoogleSearch' - - def doGetCachedPage - "i am a cached page. my key was %s, url was %s" % [@params['key'], @params['url']] - end - - def doSpellingSuggestion - "%s: Did you mean '%s'?" % [@params['key'], @params['phrase']] - end - - def doGoogleSearch - resultElement = ResultElement.new - resultElement.summary = "ONlamp.com: Rolling with Ruby on Rails" - resultElement.URL = "http://www.onlamp.com/pub/a/onlamp/2005/01/20/rails.html" - resultElement.snippet = "Curt Hibbs shows off Ruby on Rails by building a simple application that requires " + - "almost no Ruby experience. ... Rolling with Ruby on Rails. ..." - resultElement.title = "Teh Railz0r" - resultElement.cachedSize = "Almost no lines of code!" - resultElement.relatedInformationPresent = true - resultElement.hostName = "rubyonrails.com" - resultElement.directoryCategory = category("Web Development", "UTF-8") - - result = GoogleSearchResult.new - result.documentFiltering = @params['filter'] - result.searchComments = "" - result.estimatedTotalResultsCount = 322000 - result.estimateIsExact = false - result.resultElements = [resultElement] - result.searchQuery = "http://www.google.com/search?q=ruby+on+rails" - result.startIndex = @params['start'] - result.endIndex = @params['start'] + @params['maxResults'] - result.searchTips = "\"on\" is a very common word and was not included in your search [details]" - result.searchTime = 0.000001 - - # For Mono, we have to clone objects if they're referenced by more than one place, otherwise - # the Ruby SOAP collapses them into one instance and uses references all over the - # place, confusing Mono. - # - # This has recently been fixed: - # http://bugzilla.ximian.com/show_bug.cgi?id=72265 - result.directoryCategories = [ - category("Web Development", "UTF-8"), - category("Programming", "US-ASCII"), - ] - - result - end - - private - def category(name, encoding) - cat = DirectoryCategory.new - cat.fullViewableName = name.dup - cat.specialEncoding = encoding.dup - cat - end -end diff --git a/tracks/vendor/rails/actionwebservice/examples/metaWeblog/README b/tracks/vendor/rails/actionwebservice/examples/metaWeblog/README deleted file mode 100644 index f66f5677..00000000 --- a/tracks/vendor/rails/actionwebservice/examples/metaWeblog/README +++ /dev/null @@ -1,17 +0,0 @@ -= metaWeblog example - -This example shows how one might begin to go about adding metaWeblog -(http://www.xmlrpc.com/metaWeblogApi) API support to a Rails-based -blogging application. - -The example APIs are more verbose than you may want to make them, for documentation -reasons. - -= Running - - 1. Copy the "apis" directory and its files into "app" in a Rails project. - - 2. Copy the "controllers" directory and its files into "app" in a Rails project - - 3. Fire up a desktop blogging application (such as w.bloggar, MarsEdit, or BloGTK), - point it at http://localhost:3000/xmlrpc/api, and try creating or editing blog posts. diff --git a/tracks/vendor/rails/actionwebservice/examples/metaWeblog/apis/blogger_api.rb b/tracks/vendor/rails/actionwebservice/examples/metaWeblog/apis/blogger_api.rb deleted file mode 100644 index 9f85a239..00000000 --- a/tracks/vendor/rails/actionwebservice/examples/metaWeblog/apis/blogger_api.rb +++ /dev/null @@ -1,60 +0,0 @@ -# -# see the blogger API spec at http://www.blogger.com/developers/api/1_docs/ -# note that the method signatures are subtly different to metaWeblog, they -# are not identical. take care to ensure you handle the different semantics -# properly if you want to support blogger API too, to get maximum compatibility. -# - -module Blog - class Blog < ActionWebService::Struct - member :url, :string - member :blogid, :string - member :blogName, :string - end - - class User < ActionWebService::Struct - member :nickname, :string - member :userid, :string - member :url, :string - member :email, :string - member :lastname, :string - member :firstname, :string - end -end - -# -# blogger -# -class BloggerAPI < ActionWebService::API::Base - inflect_names false - - api_method :newPost, :returns => [:string], :expects => [ - {:appkey=>:string}, - {:blogid=>:string}, - {:username=>:string}, - {:password=>:string}, - {:content=>:string}, - {:publish=>:bool} - ] - - api_method :editPost, :returns => [:bool], :expects => [ - {:appkey=>:string}, - {:postid=>:string}, - {:username=>:string}, - {:password=>:string}, - {:content=>:string}, - {:publish=>:bool} - ] - - api_method :getUsersBlogs, :returns => [[Blog::Blog]], :expects => [ - {:appkey=>:string}, - {:username=>:string}, - {:password=>:string} - ] - - api_method :getUserInfo, :returns => [Blog::User], :expects => [ - {:appkey=>:string}, - {:username=>:string}, - {:password=>:string} - ] -end diff --git a/tracks/vendor/rails/actionwebservice/examples/metaWeblog/apis/blogger_service.rb b/tracks/vendor/rails/actionwebservice/examples/metaWeblog/apis/blogger_service.rb deleted file mode 100644 index b79b53e6..00000000 --- a/tracks/vendor/rails/actionwebservice/examples/metaWeblog/apis/blogger_service.rb +++ /dev/null @@ -1,34 +0,0 @@ -require 'blogger_api' - -class BloggerService < ActionWebService::Base - web_service_api BloggerAPI - - def initialize - @postid = 0 - end - - def newPost(key, id, user, pw, content, publish) - $stderr.puts "id=#{id} user=#{user} pw=#{pw}, content=#{content.inspect} [#{publish}]" - (@postid += 1).to_s - end - - def editPost(key, post_id, user, pw, content, publish) - $stderr.puts "id=#{post_id} user=#{user} pw=#{pw} content=#{content.inspect} [#{publish}]" - true - end - - def getUsersBlogs(key, user, pw) - $stderr.puts "getting blogs for #{user}" - blog = Blog::Blog.new( - :url =>'http://blog', - :blogid => 'myblog', - :blogName => 'My Blog' - ) - [blog] - end - - def getUserInfo(key, user, pw) - $stderr.puts "getting user info for #{user}" - Blog::User.new(:nickname => 'user', :email => 'user@test.com') - end -end diff --git a/tracks/vendor/rails/actionwebservice/examples/metaWeblog/apis/meta_weblog_api.rb b/tracks/vendor/rails/actionwebservice/examples/metaWeblog/apis/meta_weblog_api.rb deleted file mode 100644 index adef12a2..00000000 --- a/tracks/vendor/rails/actionwebservice/examples/metaWeblog/apis/meta_weblog_api.rb +++ /dev/null @@ -1,67 +0,0 @@ -# -# here lie structures, cousins of those on http://www.xmlrpc.com/metaWeblog -# but they don't necessarily the real world reflect -# so if you do, find that your client complains: -# please tell, of problems you suffered through -# - -module Blog - class Post < ActionWebService::Struct - member :title, :string - member :link, :string - member :description, :string - member :author, :string - member :category, :string - member :comments, :string - member :guid, :string - member :pubDate, :string - end - - class Category < ActionWebService::Struct - member :description, :string - member :htmlUrl, :string - member :rssUrl, :string - end -end - -# -# metaWeblog -# -class MetaWeblogAPI < ActionWebService::API::Base - inflect_names false - - api_method :newPost, :returns => [:string], :expects => [ - {:blogid=>:string}, - {:username=>:string}, - {:password=>:string}, - {:struct=>Blog::Post}, - {:publish=>:bool} - ] - - api_method :editPost, :returns => [:bool], :expects => [ - {:postid=>:string}, - {:username=>:string}, - {:password=>:string}, - {:struct=>Blog::Post}, - {:publish=>:bool}, - ] - - api_method :getPost, :returns => [Blog::Post], :expects => [ - {:postid=>:string}, - {:username=>:string}, - {:password=>:string}, - ] - - api_method :getCategories, :returns => [[Blog::Category]], :expects => [ - {:blogid=>:string}, - {:username=>:string}, - {:password=>:string}, - ] - - api_method :getRecentPosts, :returns => [[Blog::Post]], :expects => [ - {:blogid=>:string}, - {:username=>:string}, - {:password=>:string}, - {:numberOfPosts=>:int}, - ] -end diff --git a/tracks/vendor/rails/actionwebservice/examples/metaWeblog/apis/meta_weblog_service.rb b/tracks/vendor/rails/actionwebservice/examples/metaWeblog/apis/meta_weblog_service.rb deleted file mode 100644 index 9c66558f..00000000 --- a/tracks/vendor/rails/actionwebservice/examples/metaWeblog/apis/meta_weblog_service.rb +++ /dev/null @@ -1,48 +0,0 @@ -require 'meta_weblog_api' - -class MetaWeblogService < ActionWebService::Base - web_service_api MetaWeblogAPI - - def initialize - @postid = 0 - end - - def newPost(id, user, pw, struct, publish) - $stderr.puts "id=#{id} user=#{user} pw=#{pw}, struct=#{struct.inspect} [#{publish}]" - (@postid += 1).to_s - end - - def editPost(post_id, user, pw, struct, publish) - $stderr.puts "id=#{post_id} user=#{user} pw=#{pw} struct=#{struct.inspect} [#{publish}]" - true - end - - def getPost(post_id, user, pw) - $stderr.puts "get post #{post_id}" - Blog::Post.new(:title => 'hello world', :description => 'first post!') - end - - def getCategories(id, user, pw) - $stderr.puts "categories for #{user}" - cat = Blog::Category.new( - :description => 'Tech', - :htmlUrl => 'http://blog/tech', - :rssUrl => 'http://blog/tech.rss') - [cat] - end - - def getRecentPosts(id, user, pw, num) - $stderr.puts "recent #{num} posts for #{user} on blog #{id}" - post1 = Blog::Post.new( - :title => 'first post!', - :link => 'http://blog.xeraph.org/testOne.html', - :description => 'this is the first post' - ) - post2 = Blog::Post.new( - :title => 'second post!', - :link => 'http://blog.xeraph.org/testTwo.html', - :description => 'this is the second post' - ) - [post1, post2] - end -end diff --git a/tracks/vendor/rails/actionwebservice/examples/metaWeblog/controllers/xmlrpc_controller.rb b/tracks/vendor/rails/actionwebservice/examples/metaWeblog/controllers/xmlrpc_controller.rb deleted file mode 100644 index 7486402d..00000000 --- a/tracks/vendor/rails/actionwebservice/examples/metaWeblog/controllers/xmlrpc_controller.rb +++ /dev/null @@ -1,16 +0,0 @@ -# -# example controller implementing both blogger and metaWeblog APIs -# in a way that should be compatible with clients supporting both/either. -# -# test by pointing your client at http://URL/xmlrpc/api -# - -require 'meta_weblog_service' -require 'blogger_service' - -class XmlrpcController < ApplicationController - web_service_dispatching_mode :layered - - web_service :metaWeblog, MetaWeblogService.new - web_service :blogger, BloggerService.new -end diff --git a/tracks/vendor/rails/actionwebservice/lib/action_web_service.rb b/tracks/vendor/rails/actionwebservice/lib/action_web_service.rb deleted file mode 100644 index 874518e0..00000000 --- a/tracks/vendor/rails/actionwebservice/lib/action_web_service.rb +++ /dev/null @@ -1,66 +0,0 @@ -#-- -# Copyright (C) 2005 Leon Breedt -# -# 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. -#++ - -begin - require 'active_support' - require 'action_controller' - require 'active_record' -rescue LoadError - require 'rubygems' - require_gem 'activesupport', '>= 1.0.2' - require_gem 'actionpack', '>= 1.6.0' - require_gem 'activerecord', '>= 1.9.0' -end - -$:.unshift(File.dirname(__FILE__) + "/action_web_service/vendor/") - -require 'action_web_service/support/class_inheritable_options' -require 'action_web_service/support/signature_types' -require 'action_web_service/base' -require 'action_web_service/client' -require 'action_web_service/invocation' -require 'action_web_service/api' -require 'action_web_service/casting' -require 'action_web_service/struct' -require 'action_web_service/container' -require 'action_web_service/protocol' -require 'action_web_service/dispatcher' -require 'action_web_service/scaffolding' - -ActionWebService::Base.class_eval do - include ActionWebService::Container::Direct - include ActionWebService::Invocation -end - -ActionController::Base.class_eval do - include ActionWebService::Protocol::Discovery - include ActionWebService::Protocol::Soap - include ActionWebService::Protocol::XmlRpc - include ActionWebService::Container::Direct - include ActionWebService::Container::Delegated - include ActionWebService::Container::ActionController - include ActionWebService::Invocation - include ActionWebService::Dispatcher - include ActionWebService::Dispatcher::ActionController - include ActionWebService::Scaffolding -end diff --git a/tracks/vendor/rails/actionwebservice/lib/action_web_service/api.rb b/tracks/vendor/rails/actionwebservice/lib/action_web_service/api.rb deleted file mode 100644 index a0d0af62..00000000 --- a/tracks/vendor/rails/actionwebservice/lib/action_web_service/api.rb +++ /dev/null @@ -1,245 +0,0 @@ -module ActionWebService # :nodoc: - module API # :nodoc: - # A web service API class specifies the methods that will be available for - # invocation for an API. It also contains metadata such as the method type - # signature hints. - # - # It is not intended to be instantiated. - # - # It is attached to web service implementation classes like - # ActionWebService::Base and ActionController::Base derivatives by using - # container.web_service_api, where container is an - # ActionController::Base or a ActionWebService::Base. - # - # See ActionWebService::Container::Direct::ClassMethods for an example - # of use. - class Base - # Whether to transform the public API method names into camel-cased names - class_inheritable_option :inflect_names, true - - # Whether to allow ActiveRecord::Base models in :expects. - # The default is +false+; you should be aware of the security implications - # of allowing this, and ensure that you don't allow remote callers to - # easily overwrite data they should not have access to. - class_inheritable_option :allow_active_record_expects, false - - # If present, the name of a method to call when the remote caller - # tried to call a nonexistent method. Semantically equivalent to - # +method_missing+. - class_inheritable_option :default_api_method - - # Disallow instantiation - private_class_method :new, :allocate - - class << self - include ActionWebService::SignatureTypes - - # API methods have a +name+, which must be the Ruby method name to use when - # performing the invocation on the web service object. - # - # The signatures for the method input parameters and return value can - # by specified in +options+. - # - # A signature is an array of one or more parameter specifiers. - # A parameter specifier can be one of the following: - # - # * A symbol or string representing one of the Action Web Service base types. - # See ActionWebService::SignatureTypes for a canonical list of the base types. - # * The Class object of the parameter type - # * A single-element Array containing one of the two preceding items. This - # will cause Action Web Service to treat the parameter at that position - # as an array containing only values of the given type. - # * A Hash containing as key the name of the parameter, and as value - # one of the three preceding items - # - # If no method input parameter or method return value signatures are given, - # the method is assumed to take no parameters and/or return no values of - # interest, and any values that are received by the server will be - # discarded and ignored. - # - # Valid options: - # [:expects] Signature for the method input parameters - # [:returns] Signature for the method return value - # [:expects_and_returns] Signature for both input parameters and return value - def api_method(name, options={}) - unless options.is_a?(Hash) - raise(ActionWebServiceError, "Expected a Hash for options") - end - validate_options([:expects, :returns, :expects_and_returns], options.keys) - if options[:expects_and_returns] - expects = options[:expects_and_returns] - returns = options[:expects_and_returns] - else - expects = options[:expects] - returns = options[:returns] - end - expects = canonical_signature(expects) - returns = canonical_signature(returns) - if expects - expects.each do |type| - type = type.element_type if type.is_a?(ArrayType) - if type.type_class.ancestors.include?(ActiveRecord::Base) && !allow_active_record_expects - raise(ActionWebServiceError, "ActiveRecord model classes not allowed in :expects") - end - end - end - name = name.to_sym - public_name = public_api_method_name(name) - method = Method.new(name, public_name, expects, returns) - write_inheritable_hash("api_methods", name => method) - write_inheritable_hash("api_public_method_names", public_name => name) - end - - # Whether the given method name is a service method on this API - def has_api_method?(name) - api_methods.has_key?(name) - end - - # Whether the given public method name has a corresponding service method - # on this API - def has_public_api_method?(public_name) - api_public_method_names.has_key?(public_name) - end - - # The corresponding public method name for the given service method name - def public_api_method_name(name) - if inflect_names - name.to_s.camelize - else - name.to_s - end - end - - # The corresponding service method name for the given public method name - def api_method_name(public_name) - api_public_method_names[public_name] - end - - # A Hash containing all service methods on this API, and their - # associated metadata. - def api_methods - read_inheritable_attribute("api_methods") || {} - end - - # The Method instance for the given public API method name, if any - def public_api_method_instance(public_method_name) - api_method_instance(api_method_name(public_method_name)) - end - - # The Method instance for the given API method name, if any - def api_method_instance(method_name) - api_methods[method_name] - end - - # The Method instance for the default API method, if any - def default_api_method_instance - return nil unless name = default_api_method - instance = read_inheritable_attribute("default_api_method_instance") - if instance && instance.name == name - return instance - end - instance = Method.new(name, public_api_method_name(name), nil, nil) - write_inheritable_attribute("default_api_method_instance", instance) - instance - end - - private - def api_public_method_names - read_inheritable_attribute("api_public_method_names") || {} - end - - def validate_options(valid_option_keys, supplied_option_keys) - unknown_option_keys = supplied_option_keys - valid_option_keys - unless unknown_option_keys.empty? - raise(ActionWebServiceError, "Unknown options: #{unknown_option_keys}") - end - end - end - end - - # Represents an API method and its associated metadata, and provides functionality - # to assist in commonly performed API method tasks. - class Method - attr :name - attr :public_name - attr :expects - attr :returns - - def initialize(name, public_name, expects, returns) - @name = name - @public_name = public_name - @expects = expects - @returns = returns - @caster = ActionWebService::Casting::BaseCaster.new(self) - end - - # The list of parameter names for this method - def param_names - return [] unless @expects - @expects.map{ |type| type.name } - end - - # Casts a set of Ruby values into the expected Ruby values - def cast_expects(params) - @caster.cast_expects(params) - end - - # Cast a Ruby return value into the expected Ruby value - def cast_returns(return_value) - @caster.cast_returns(return_value) - end - - # Returns the index of the first expected parameter - # with the given name - def expects_index_of(param_name) - return -1 if @expects.nil? - (0..(@expects.length-1)).each do |i| - return i if @expects[i].name.to_s == param_name.to_s - end - -1 - end - - # Returns a hash keyed by parameter name for the given - # parameter list - def expects_to_hash(params) - return {} if @expects.nil? - h = {} - @expects.zip(params){ |type, param| h[type.name] = param } - h - end - - # Backwards compatibility with previous API - def [](sig_type) - case sig_type - when :expects - @expects.map{|x| compat_signature_entry(x)} - when :returns - @returns.map{|x| compat_signature_entry(x)} - end - end - - # String representation of this method - def to_s - fqn = "" - fqn << (@returns ? (@returns[0].human_name(false) + " ") : "void ") - fqn << "#{@public_name}(" - fqn << @expects.map{ |p| p.human_name }.join(", ") if @expects - fqn << ")" - fqn - end - - private - def compat_signature_entry(entry) - if entry.array? - [compat_signature_entry(entry.element_type)] - else - if entry.spec.is_a?(Hash) - {entry.spec.keys.first => entry.type_class} - else - entry.type_class - end - end - end - end - end -end diff --git a/tracks/vendor/rails/actionwebservice/lib/action_web_service/base.rb b/tracks/vendor/rails/actionwebservice/lib/action_web_service/base.rb deleted file mode 100644 index 16e4d87f..00000000 --- a/tracks/vendor/rails/actionwebservice/lib/action_web_service/base.rb +++ /dev/null @@ -1,38 +0,0 @@ -module ActionWebService # :nodoc: - class ActionWebServiceError < StandardError # :nodoc: - end - - # An Action Web Service object implements a specified API. - # - # Used by controllers operating in _Delegated_ dispatching mode. - # - # ==== Example - # - # class PersonService < ActionWebService::Base - # web_service_api PersonAPI - # - # def find_person(criteria) - # Person.find_all [...] - # end - # - # def delete_person(id) - # Person.find_by_id(id).destroy - # end - # end - # - # class PersonAPI < ActionWebService::API::Base - # api_method :find_person, :expects => [SearchCriteria], :returns => [[Person]] - # api_method :delete_person, :expects => [:int] - # end - # - # class SearchCriteria < ActionStruct::Base - # member :firstname, :string - # member :lastname, :string - # member :email, :string - # end - class Base - # Whether to report exceptions back to the caller in the protocol's exception - # format - class_inheritable_option :web_service_exception_reporting, true - end -end diff --git a/tracks/vendor/rails/actionwebservice/lib/action_web_service/casting.rb b/tracks/vendor/rails/actionwebservice/lib/action_web_service/casting.rb deleted file mode 100644 index 3c0afbe9..00000000 --- a/tracks/vendor/rails/actionwebservice/lib/action_web_service/casting.rb +++ /dev/null @@ -1,126 +0,0 @@ -require 'time' -require 'date' -require 'xmlrpc/datetime' - -module ActionWebService # :nodoc: - module Casting # :nodoc: - class CastingError < ActionWebServiceError # :nodoc: - end - - # Performs casting of arbitrary values into the correct types for the signature - class BaseCaster # :nodoc: - def initialize(api_method) - @api_method = api_method - end - - # Coerces the parameters in +params+ (an Enumerable) into the types - # this method expects - def cast_expects(params) - self.class.cast_expects(@api_method, params) - end - - # Coerces the given +return_value+ into the type returned by this - # method - def cast_returns(return_value) - self.class.cast_returns(@api_method, return_value) - end - - class << self - include ActionWebService::SignatureTypes - - def cast_expects(api_method, params) # :nodoc: - return [] if api_method.expects.nil? - api_method.expects.zip(params).map{ |type, param| cast(param, type) } - end - - def cast_returns(api_method, return_value) # :nodoc: - return nil if api_method.returns.nil? - cast(return_value, api_method.returns[0]) - end - - def cast(value, signature_type) # :nodoc: - return value if signature_type.nil? # signature.length != params.length - return nil if value.nil? - unless signature_type.array? || signature_type.structured? - return value if canonical_type(value.class) == signature_type.type - end - if signature_type.array? - unless value.respond_to?(:entries) && !value.is_a?(String) - raise CastingError, "Don't know how to cast #{value.class} into #{signature_type.type.inspect}" - end - value.entries.map do |entry| - cast(entry, signature_type.element_type) - end - elsif signature_type.structured? - cast_to_structured_type(value, signature_type) - elsif !signature_type.custom? - cast_base_type(value, signature_type) - end - end - - def cast_base_type(value, signature_type) # :nodoc: - # This is a work-around for the fact that XML-RPC special-cases DateTime values into its own DateTime type - # in order to support iso8601 dates. This doesn't work too well for us, so we'll convert it into a Time, - # with the caveat that we won't be able to handle pre-1970 dates that are sent to us. - # - # See http://dev.rubyonrails.com/ticket/2516 - value = value.to_time if value.is_a?(XMLRPC::DateTime) - - case signature_type.type - when :int - Integer(value) - when :string - value.to_s - when :base64 - if value.is_a?(ActionWebService::Base64) - value - else - ActionWebService::Base64.new(value.to_s) - end - when :bool - return false if value.nil? - return value if value == true || value == false - case value.to_s.downcase - when '1', 'true', 'y', 'yes' - true - when '0', 'false', 'n', 'no' - false - else - raise CastingError, "Don't know how to cast #{value.class} into Boolean" - end - when :float - Float(value) - when :time - Time.parse(value.to_s) - when :date - Date.parse(value.to_s) - when :datetime - DateTime.parse(value.to_s) - end - end - - def cast_to_structured_type(value, signature_type) # :nodoc: - obj = nil - obj = value if canonical_type(value.class) == canonical_type(signature_type.type) - obj ||= signature_type.type_class.new - if value.respond_to?(:each_pair) - klass = signature_type.type_class - value.each_pair do |name, val| - type = klass.respond_to?(:member_type) ? klass.member_type(name) : nil - val = cast(val, type) if type - obj.__send__("#{name}=", val) if obj.respond_to?(name) - end - elsif value.respond_to?(:attributes) - signature_type.each_member do |name, type| - val = value.__send__(name) - obj.__send__("#{name}=", cast(val, type)) if obj.respond_to?(name) - end - else - raise CastingError, "Don't know how to cast #{value.class} to #{signature_type.type_class}" - end - obj - end - end - end - end -end diff --git a/tracks/vendor/rails/actionwebservice/lib/action_web_service/client.rb b/tracks/vendor/rails/actionwebservice/lib/action_web_service/client.rb deleted file mode 100644 index 2a1e3305..00000000 --- a/tracks/vendor/rails/actionwebservice/lib/action_web_service/client.rb +++ /dev/null @@ -1,3 +0,0 @@ -require 'action_web_service/client/base' -require 'action_web_service/client/soap_client' -require 'action_web_service/client/xmlrpc_client' diff --git a/tracks/vendor/rails/actionwebservice/lib/action_web_service/client/base.rb b/tracks/vendor/rails/actionwebservice/lib/action_web_service/client/base.rb deleted file mode 100644 index 9dada7bf..00000000 --- a/tracks/vendor/rails/actionwebservice/lib/action_web_service/client/base.rb +++ /dev/null @@ -1,28 +0,0 @@ -module ActionWebService # :nodoc: - module Client # :nodoc: - class ClientError < StandardError # :nodoc: - end - - class Base # :nodoc: - def initialize(api, endpoint_uri) - @api = api - @endpoint_uri = endpoint_uri - end - - def method_missing(name, *args) # :nodoc: - call_name = method_name(name) - return super(name, *args) if call_name.nil? - self.perform_invocation(call_name, args) - end - - private - def method_name(name) - if @api.has_api_method?(name.to_sym) - name.to_s - elsif @api.has_public_api_method?(name.to_s) - @api.api_method_name(name.to_s).to_s - end - end - end - end -end diff --git a/tracks/vendor/rails/actionwebservice/lib/action_web_service/client/soap_client.rb b/tracks/vendor/rails/actionwebservice/lib/action_web_service/client/soap_client.rb deleted file mode 100644 index f5ebe162..00000000 --- a/tracks/vendor/rails/actionwebservice/lib/action_web_service/client/soap_client.rb +++ /dev/null @@ -1,103 +0,0 @@ -require 'soap/rpc/driver' -require 'uri' - -module ActionWebService # :nodoc: - module Client # :nodoc: - - # Implements SOAP client support (using RPC encoding for the messages). - # - # ==== Example Usage - # - # class PersonAPI < ActionWebService::API::Base - # api_method :find_all, :returns => [[Person]] - # end - # - # soap_client = ActionWebService::Client::Soap.new(PersonAPI, "http://...") - # persons = soap_client.find_all - # - class Soap < Base - - # Creates a new web service client using the SOAP RPC protocol. - # - # +api+ must be an ActionWebService::API::Base derivative, and - # +endpoint_uri+ must point at the relevant URL to which protocol requests - # will be sent with HTTP POST. - # - # Valid options: - # [:namespace] If the remote server has used a custom namespace to - # declare its custom types, you can specify it here. This would - # be the namespace declared with a [WebService(Namespace = "http://namespace")] attribute - # in .NET, for example. - # [:driver_options] If you want to supply any custom SOAP RPC driver - # options, you can provide them as a Hash here - # - # The :driver_options option can be used to configure the backend SOAP - # RPC driver. An example of configuring the SOAP backend to do - # client-certificate authenticated SSL connections to the server: - # - # opts = {} - # opts['protocol.http.ssl_config.verify_mode'] = 'OpenSSL::SSL::VERIFY_PEER' - # opts['protocol.http.ssl_config.client_cert'] = client_cert_file_path - # opts['protocol.http.ssl_config.client_key'] = client_key_file_path - # opts['protocol.http.ssl_config.ca_file'] = ca_cert_file_path - # client = ActionWebService::Client::Soap.new(api, 'https://some/service', :driver_options => opts) - def initialize(api, endpoint_uri, options={}) - super(api, endpoint_uri) - @namespace = options[:namespace] || 'urn:ActionWebService' - @driver_options = options[:driver_options] || {} - @protocol = ActionWebService::Protocol::Soap::SoapProtocol.new @namespace - @soap_action_base = options[:soap_action_base] - @soap_action_base ||= URI.parse(endpoint_uri).path - @driver = create_soap_rpc_driver(api, endpoint_uri) - @driver_options.each do |name, value| - @driver.options[name.to_s] = value.to_s - end - end - - protected - def perform_invocation(method_name, args) - method = @api.api_methods[method_name.to_sym] - args = method.cast_expects(args.dup) rescue args - return_value = @driver.send(method_name, *args) - method.cast_returns(return_value.dup) rescue return_value - end - - def soap_action(method_name) - "#{@soap_action_base}/#{method_name}" - end - - private - def create_soap_rpc_driver(api, endpoint_uri) - @protocol.register_api(api) - driver = SoapDriver.new(endpoint_uri, nil) - driver.mapping_registry = @protocol.marshaler.registry - api.api_methods.each do |name, method| - qname = XSD::QName.new(@namespace, method.public_name) - action = soap_action(method.public_name) - expects = method.expects - returns = method.returns - param_def = [] - if expects - expects.each do |type| - type_binding = @protocol.marshaler.lookup_type(type) - param_def << ['in', type.name, type_binding.mapping] - end - end - if returns - type_binding = @protocol.marshaler.lookup_type(returns[0]) - param_def << ['retval', 'return', type_binding.mapping] - end - driver.add_method(qname, action, method.name.to_s, param_def) - end - driver - end - - class SoapDriver < SOAP::RPC::Driver # :nodoc: - def add_method(qname, soapaction, name, param_def) - @proxy.add_rpc_method(qname, soapaction, name, param_def) - add_rpc_method_interface(name, param_def) - end - end - end - end -end diff --git a/tracks/vendor/rails/actionwebservice/lib/action_web_service/client/xmlrpc_client.rb b/tracks/vendor/rails/actionwebservice/lib/action_web_service/client/xmlrpc_client.rb deleted file mode 100644 index 42b5c5d4..00000000 --- a/tracks/vendor/rails/actionwebservice/lib/action_web_service/client/xmlrpc_client.rb +++ /dev/null @@ -1,58 +0,0 @@ -require 'uri' -require 'xmlrpc/client' - -module ActionWebService # :nodoc: - module Client # :nodoc: - - # Implements XML-RPC client support - # - # ==== Example Usage - # - # class BloggerAPI < ActionWebService::API::Base - # inflect_names false - # api_method :getRecentPosts, :returns => [[Blog::Post]] - # end - # - # blog = ActionWebService::Client::XmlRpc.new(BloggerAPI, "http://.../RPC", :handler_name => "blogger") - # posts = blog.getRecentPosts - class XmlRpc < Base - - # Creates a new web service client using the XML-RPC protocol. - # - # +api+ must be an ActionWebService::API::Base derivative, and - # +endpoint_uri+ must point at the relevant URL to which protocol requests - # will be sent with HTTP POST. - # - # Valid options: - # [:handler_name] If the remote server defines its services inside special - # handler (the Blogger API uses a "blogger" handler name for example), - # provide it here, or your method calls will fail - def initialize(api, endpoint_uri, options={}) - @api = api - @handler_name = options[:handler_name] - @protocol = ActionWebService::Protocol::XmlRpc::XmlRpcProtocol.new - @client = XMLRPC::Client.new2(endpoint_uri, options[:proxy], options[:timeout]) - end - - protected - def perform_invocation(method_name, args) - method = @api.api_methods[method_name.to_sym] - if method.expects && method.expects.length != args.length - raise(ArgumentError, "#{method.public_name}: wrong number of arguments (#{args.length} for #{method.expects.length})") - end - args = method.cast_expects(args.dup) rescue args - if method.expects - method.expects.each_with_index{ |type, i| args[i] = @protocol.value_to_xmlrpc_wire_format(args[i], type) } - end - ok, return_value = @client.call2(public_name(method_name), *args) - return (method.cast_returns(return_value.dup) rescue return_value) if ok - raise(ClientError, "#{return_value.faultCode}: #{return_value.faultString}") - end - - def public_name(method_name) - public_name = @api.public_api_method_name(method_name) - @handler_name ? "#{@handler_name}.#{public_name}" : public_name - end - end - end -end diff --git a/tracks/vendor/rails/actionwebservice/lib/action_web_service/container.rb b/tracks/vendor/rails/actionwebservice/lib/action_web_service/container.rb deleted file mode 100644 index 13d9d8ab..00000000 --- a/tracks/vendor/rails/actionwebservice/lib/action_web_service/container.rb +++ /dev/null @@ -1,3 +0,0 @@ -require 'action_web_service/container/direct_container' -require 'action_web_service/container/delegated_container' -require 'action_web_service/container/action_controller_container' diff --git a/tracks/vendor/rails/actionwebservice/lib/action_web_service/container/action_controller_container.rb b/tracks/vendor/rails/actionwebservice/lib/action_web_service/container/action_controller_container.rb deleted file mode 100644 index b74b5ba6..00000000 --- a/tracks/vendor/rails/actionwebservice/lib/action_web_service/container/action_controller_container.rb +++ /dev/null @@ -1,95 +0,0 @@ -module ActionWebService # :nodoc: - module Container # :nodoc: - module ActionController # :nodoc: - def self.append_features(base) # :nodoc: - class << base - include ClassMethods - alias_method :inherited_without_api, :inherited - alias_method :inherited, :inherited_with_api - alias_method :web_service_api_without_require, :web_service_api - alias_method :web_service_api, :web_service_api_with_require - end - end - - module ClassMethods - # Creates a client for accessing remote web services, using the - # given +protocol+ to communicate with the +endpoint_uri+. - # - # ==== Example - # - # class MyController < ActionController::Base - # web_client_api :blogger, :xmlrpc, "http://blogger.com/myblog/api/RPC2", :handler_name => 'blogger' - # end - # - # In this example, a protected method named blogger will - # now exist on the controller, and calling it will return the - # XML-RPC client object for working with that remote service. - # - # +options+ is the set of protocol client specific options (see - # a protocol client class for details). - # - # If your API definition does not exist on the load path with the - # correct rules for it to be found using +name+, you can pass in - # the API definition class via +options+, using a key of :api - def web_client_api(name, protocol, endpoint_uri, options={}) - unless method_defined?(name) - api_klass = options.delete(:api) || require_web_service_api(name) - class_eval do - define_method(name) do - create_web_service_client(api_klass, protocol, endpoint_uri, options) - end - protected name - end - end - end - - def web_service_api_with_require(definition=nil) # :nodoc: - return web_service_api_without_require if definition.nil? - case definition - when String, Symbol - klass = require_web_service_api(definition) - else - klass = definition - end - web_service_api_without_require(klass) - end - - def require_web_service_api(name) # :nodoc: - case name - when String, Symbol - file_name = name.to_s.underscore + "_api" - class_name = file_name.camelize - class_names = [class_name, class_name.sub(/Api$/, 'API')] - begin - require_dependency(file_name) - rescue LoadError => load_error - requiree = / -- (.*?)(\.rb)?$/.match(load_error).to_a[1] - msg = requiree == file_name ? "Missing API definition file in apis/#{file_name}.rb" : "Can't load file: #{requiree}" - raise LoadError.new(msg).copy_blame!(load_error) - end - klass = nil - class_names.each do |name| - klass = name.constantize rescue nil - break unless klass.nil? - end - unless klass - raise(NameError, "neither #{class_names[0]} or #{class_names[1]} found") - end - klass - else - raise(ArgumentError, "expected String or Symbol argument") - end - end - - private - def inherited_with_api(child) - inherited_without_api(child) - begin child.web_service_api(child.controller_path) - rescue MissingSourceFile => e - raise unless e.is_missing?("apis/#{child.controller_path}_api") - end - end - end - end - end -end diff --git a/tracks/vendor/rails/actionwebservice/lib/action_web_service/container/delegated_container.rb b/tracks/vendor/rails/actionwebservice/lib/action_web_service/container/delegated_container.rb deleted file mode 100644 index 12a857e4..00000000 --- a/tracks/vendor/rails/actionwebservice/lib/action_web_service/container/delegated_container.rb +++ /dev/null @@ -1,87 +0,0 @@ -module ActionWebService # :nodoc: - module Container # :nodoc: - module Delegated # :nodoc: - class ContainerError < ActionWebServiceError # :nodoc: - end - - def self.append_features(base) # :nodoc: - super - base.extend(ClassMethods) - base.send(:include, ActionWebService::Container::Delegated::InstanceMethods) - end - - module ClassMethods - # Declares a web service that will provide access to the API of the given - # +object+. +object+ must be an ActionWebService::Base derivative. - # - # Web service object creation can either be _immediate_, where the object - # instance is given at class definition time, or _deferred_, where - # object instantiation is delayed until request time. - # - # ==== Immediate web service object example - # - # class ApiController < ApplicationController - # web_service_dispatching_mode :delegated - # - # web_service :person, PersonService.new - # end - # - # For deferred instantiation, a block should be given instead of an - # object instance. This block will be executed in controller instance - # context, so it can rely on controller instance variables being present. - # - # ==== Deferred web service object example - # - # class ApiController < ApplicationController - # web_service_dispatching_mode :delegated - # - # web_service(:person) { PersonService.new(request.env) } - # end - def web_service(name, object=nil, &block) - if (object && block_given?) || (object.nil? && block.nil?) - raise(ContainerError, "either service, or a block must be given") - end - name = name.to_sym - if block_given? - info = { name => { :block => block } } - else - info = { name => { :object => object } } - end - write_inheritable_hash("web_services", info) - call_web_service_definition_callbacks(self, name, info) - end - - # Whether this service contains a service with the given +name+ - def has_web_service?(name) - web_services.has_key?(name.to_sym) - end - - def web_services # :nodoc: - read_inheritable_attribute("web_services") || {} - end - - def add_web_service_definition_callback(&block) # :nodoc: - write_inheritable_array("web_service_definition_callbacks", [block]) - end - - private - def call_web_service_definition_callbacks(container_class, web_service_name, service_info) - (read_inheritable_attribute("web_service_definition_callbacks") || []).each do |block| - block.call(container_class, web_service_name, service_info) - end - end - end - - module InstanceMethods # :nodoc: - def web_service_object(web_service_name) - info = self.class.web_services[web_service_name.to_sym] - unless info - raise(ContainerError, "no such web service '#{web_service_name}'") - end - service = info[:block] - service ? self.instance_eval(&service) : info[:object] - end - end - end - end -end diff --git a/tracks/vendor/rails/actionwebservice/lib/action_web_service/container/direct_container.rb b/tracks/vendor/rails/actionwebservice/lib/action_web_service/container/direct_container.rb deleted file mode 100644 index b53c542f..00000000 --- a/tracks/vendor/rails/actionwebservice/lib/action_web_service/container/direct_container.rb +++ /dev/null @@ -1,70 +0,0 @@ -module ActionWebService # :nodoc: - module Container # :nodoc: - module Direct # :nodoc: - class ContainerError < ActionWebServiceError # :nodoc: - end - - def self.append_features(base) # :nodoc: - super - base.extend(ClassMethods) - end - - module ClassMethods - # Attaches ActionWebService API +definition+ to the calling class. - # - # Action Controllers can have a default associated API, removing the need - # to call this method if you follow the Action Web Service naming conventions. - # - # A controller with a class name of GoogleSearchController will - # implicitly load app/apis/google_search_api.rb, and expect the - # API definition class to be named GoogleSearchAPI or - # GoogleSearchApi. - # - # ==== Service class example - # - # class MyService < ActionWebService::Base - # web_service_api MyAPI - # end - # - # class MyAPI < ActionWebService::API::Base - # ... - # end - # - # ==== Controller class example - # - # class MyController < ActionController::Base - # web_service_api MyAPI - # end - # - # class MyAPI < ActionWebService::API::Base - # ... - # end - def web_service_api(definition=nil) - if definition.nil? - read_inheritable_attribute("web_service_api") - else - if definition.is_a?(Symbol) - raise(ContainerError, "symbols can only be used for #web_service_api inside of a controller") - end - unless definition.respond_to?(:ancestors) && definition.ancestors.include?(ActionWebService::API::Base) - raise(ContainerError, "#{definition.to_s} is not a valid API definition") - end - write_inheritable_attribute("web_service_api", definition) - call_web_service_api_callbacks(self, definition) - end - end - - def add_web_service_api_callback(&block) # :nodoc: - write_inheritable_array("web_service_api_callbacks", [block]) - end - - private - def call_web_service_api_callbacks(container_class, definition) - (read_inheritable_attribute("web_service_api_callbacks") || []).each do |block| - block.call(container_class, definition) - end - end - end - end - end -end diff --git a/tracks/vendor/rails/actionwebservice/lib/action_web_service/dispatcher.rb b/tracks/vendor/rails/actionwebservice/lib/action_web_service/dispatcher.rb deleted file mode 100644 index 601d8313..00000000 --- a/tracks/vendor/rails/actionwebservice/lib/action_web_service/dispatcher.rb +++ /dev/null @@ -1,2 +0,0 @@ -require 'action_web_service/dispatcher/abstract' -require 'action_web_service/dispatcher/action_controller_dispatcher' diff --git a/tracks/vendor/rails/actionwebservice/lib/action_web_service/dispatcher/abstract.rb b/tracks/vendor/rails/actionwebservice/lib/action_web_service/dispatcher/abstract.rb deleted file mode 100644 index cf3af538..00000000 --- a/tracks/vendor/rails/actionwebservice/lib/action_web_service/dispatcher/abstract.rb +++ /dev/null @@ -1,201 +0,0 @@ -require 'benchmark' - -module ActionWebService # :nodoc: - module Dispatcher # :nodoc: - class DispatcherError < ActionWebService::ActionWebServiceError # :nodoc: - end - - def self.append_features(base) # :nodoc: - super - base.class_inheritable_option(:web_service_dispatching_mode, :direct) - base.class_inheritable_option(:web_service_exception_reporting, true) - base.send(:include, ActionWebService::Dispatcher::InstanceMethods) - end - - module InstanceMethods # :nodoc: - private - def invoke_web_service_request(protocol_request) - invocation = web_service_invocation(protocol_request) - if invocation.is_a?(Array) && protocol_request.protocol.is_a?(Protocol::XmlRpc::XmlRpcProtocol) - xmlrpc_multicall_invoke(invocation) - else - web_service_invoke(invocation) - end - end - - def web_service_direct_invoke(invocation) - @method_params = invocation.method_ordered_params - arity = method(invocation.api_method.name).arity rescue 0 - if arity < 0 || arity > 0 - params = @method_params - else - params = [] - end - web_service_filtered_invoke(invocation, params) - end - - def web_service_delegated_invoke(invocation) - web_service_filtered_invoke(invocation, invocation.method_ordered_params) - end - - def web_service_filtered_invoke(invocation, params) - cancellation_reason = nil - return_value = invocation.service.perform_invocation(invocation.api_method.name, params) do |x| - cancellation_reason = x - end - if cancellation_reason - raise(DispatcherError, "request canceled: #{cancellation_reason}") - end - return_value - end - - def web_service_invoke(invocation) - case web_service_dispatching_mode - when :direct - return_value = web_service_direct_invoke(invocation) - when :delegated, :layered - return_value = web_service_delegated_invoke(invocation) - end - web_service_create_response(invocation.protocol, invocation.protocol_options, invocation.api, invocation.api_method, return_value) - end - - def xmlrpc_multicall_invoke(invocations) - responses = [] - invocations.each do |invocation| - if invocation.is_a?(Hash) - responses << invocation - next - end - begin - case web_service_dispatching_mode - when :direct - return_value = web_service_direct_invoke(invocation) - when :delegated, :layered - return_value = web_service_delegated_invoke(invocation) - end - api_method = invocation.api_method - if invocation.api.has_api_method?(api_method.name) - return_value = api_method.cast_returns(return_value) - end - responses << [return_value] - rescue Exception => e - responses << { 'faultCode' => 3, 'faultString' => e.message } - end - end - invocation = invocations[0] - invocation.protocol.encode_response('system.multicall', responses, nil, invocation.protocol_options) - end - - def web_service_invocation(request, level = 0) - public_method_name = request.method_name - invocation = Invocation.new - invocation.protocol = request.protocol - invocation.protocol_options = request.protocol_options - invocation.service_name = request.service_name - if web_service_dispatching_mode == :layered - case invocation.protocol - when Protocol::Soap::SoapProtocol - soap_action = request.protocol_options[:soap_action] - if soap_action && soap_action =~ /^\/\w+\/(\w+)\// - invocation.service_name = $1 - end - when Protocol::XmlRpc::XmlRpcProtocol - if request.method_name =~ /^([^\.]+)\.(.*)$/ - public_method_name = $2 - invocation.service_name = $1 - end - end - end - if invocation.protocol.is_a? Protocol::XmlRpc::XmlRpcProtocol - if public_method_name == 'multicall' && invocation.service_name == 'system' - if level > 0 - raise(DispatcherError, "Recursive system.multicall invocations not allowed") - end - multicall = request.method_params.dup - unless multicall.is_a?(Array) && multicall[0].is_a?(Array) - raise(DispatcherError, "Malformed multicall (expected array of Hash elements)") - end - multicall = multicall[0] - return multicall.map do |item| - raise(DispatcherError, "Multicall elements must be Hash") unless item.is_a?(Hash) - raise(DispatcherError, "Multicall elements must contain a 'methodName' key") unless item.has_key?('methodName') - method_name = item['methodName'] - params = item.has_key?('params') ? item['params'] : [] - multicall_request = request.dup - multicall_request.method_name = method_name - multicall_request.method_params = params - begin - web_service_invocation(multicall_request, level + 1) - rescue Exception => e - {'faultCode' => 4, 'faultMessage' => e.message} - end - end - end - end - case web_service_dispatching_mode - when :direct - invocation.api = self.class.web_service_api - invocation.service = self - when :delegated, :layered - invocation.service = web_service_object(invocation.service_name) - invocation.api = invocation.service.class.web_service_api - end - if invocation.api.nil? - raise(DispatcherError, "no API attached to #{invocation.service.class}") - end - invocation.protocol.register_api(invocation.api) - request.api = invocation.api - if invocation.api.has_public_api_method?(public_method_name) - invocation.api_method = invocation.api.public_api_method_instance(public_method_name) - else - if invocation.api.default_api_method.nil? - raise(DispatcherError, "no such method '#{public_method_name}' on API #{invocation.api}") - else - invocation.api_method = invocation.api.default_api_method_instance - end - end - if invocation.service.nil? - raise(DispatcherError, "no service available for service name #{invocation.service_name}") - end - unless invocation.service.respond_to?(invocation.api_method.name) - raise(DispatcherError, "no such method '#{public_method_name}' on API #{invocation.api} (#{invocation.api_method.name})") - end - request.api_method = invocation.api_method - begin - invocation.method_ordered_params = invocation.api_method.cast_expects(request.method_params.dup) - rescue - logger.warn "Casting of method parameters failed" unless logger.nil? - invocation.method_ordered_params = request.method_params - end - request.method_params = invocation.method_ordered_params - invocation.method_named_params = {} - invocation.api_method.param_names.inject(0) do |m, n| - invocation.method_named_params[n] = invocation.method_ordered_params[m] - m + 1 - end - invocation - end - - def web_service_create_response(protocol, protocol_options, api, api_method, return_value) - if api.has_api_method?(api_method.name) - return_type = api_method.returns ? api_method.returns[0] : nil - return_value = api_method.cast_returns(return_value) - else - return_type = ActionWebService::SignatureTypes.canonical_signature_entry(return_value.class, 0) - end - protocol.encode_response(api_method.public_name + 'Response', return_value, return_type, protocol_options) - end - - class Invocation # :nodoc: - attr_accessor :protocol - attr_accessor :protocol_options - attr_accessor :service_name - attr_accessor :api - attr_accessor :api_method - attr_accessor :method_ordered_params - attr_accessor :method_named_params - attr_accessor :service - end - end - end -end diff --git a/tracks/vendor/rails/actionwebservice/lib/action_web_service/dispatcher/action_controller_dispatcher.rb b/tracks/vendor/rails/actionwebservice/lib/action_web_service/dispatcher/action_controller_dispatcher.rb deleted file mode 100644 index 8f04ed29..00000000 --- a/tracks/vendor/rails/actionwebservice/lib/action_web_service/dispatcher/action_controller_dispatcher.rb +++ /dev/null @@ -1,380 +0,0 @@ -require 'benchmark' -require 'builder/xmlmarkup' - -module ActionWebService # :nodoc: - module Dispatcher # :nodoc: - module ActionController # :nodoc: - def self.append_features(base) # :nodoc: - super - class << base - include ClassMethods - alias_method :inherited_without_action_controller, :inherited - alias_method :inherited, :inherited_with_action_controller - end - base.class_eval do - alias_method :web_service_direct_invoke_without_controller, :web_service_direct_invoke - end - base.add_web_service_api_callback do |klass, api| - if klass.web_service_dispatching_mode == :direct - klass.class_eval 'def api; dispatch_web_service_request; end' - end - end - base.add_web_service_definition_callback do |klass, name, info| - if klass.web_service_dispatching_mode == :delegated - klass.class_eval "def #{name}; dispatch_web_service_request; end" - elsif klass.web_service_dispatching_mode == :layered - klass.class_eval 'def api; dispatch_web_service_request; end' - end - end - base.send(:include, ActionWebService::Dispatcher::ActionController::InstanceMethods) - end - - module ClassMethods # :nodoc: - def inherited_with_action_controller(child) - inherited_without_action_controller(child) - child.send(:include, ActionWebService::Dispatcher::ActionController::WsdlAction) - end - end - - module InstanceMethods # :nodoc: - private - def dispatch_web_service_request - exception = nil - begin - ws_request = discover_web_service_request(request) - rescue Exception => e - exception = e - end - if ws_request - ws_response = nil - exception = nil - bm = Benchmark.measure do - begin - ws_response = invoke_web_service_request(ws_request) - rescue Exception => e - exception = e - end - end - log_request(ws_request, request.raw_post) - if exception - log_error(exception) unless logger.nil? - send_web_service_error_response(ws_request, exception) - else - send_web_service_response(ws_response, bm.real) - end - else - exception ||= DispatcherError.new("Malformed SOAP or XML-RPC protocol message") - log_error(exception) unless logger.nil? - send_web_service_error_response(ws_request, exception) - end - rescue Exception => e - log_error(e) unless logger.nil? - send_web_service_error_response(ws_request, e) - end - - def send_web_service_response(ws_response, elapsed=nil) - log_response(ws_response, elapsed) - options = { :type => ws_response.content_type, :disposition => 'inline' } - send_data(ws_response.body, options) - end - - def send_web_service_error_response(ws_request, exception) - if ws_request - unless self.class.web_service_exception_reporting - exception = DispatcherError.new("Internal server error (exception raised)") - end - api_method = ws_request.api_method - public_method_name = api_method ? api_method.public_name : ws_request.method_name - return_type = ActionWebService::SignatureTypes.canonical_signature_entry(Exception, 0) - ws_response = ws_request.protocol.encode_response(public_method_name + 'Response', exception, return_type, ws_request.protocol_options) - send_web_service_response(ws_response) - else - if self.class.web_service_exception_reporting - message = exception.message - backtrace = "\nBacktrace:\n#{exception.backtrace.join("\n")}" - else - message = "Exception raised" - backtrace = "" - end - render_text("Internal protocol error: #{message}#{backtrace}", "500 Internal Protocol Error") - end - end - - def web_service_direct_invoke(invocation) - invocation.method_named_params.each do |name, value| - params[name] = value - end - params['action'] = invocation.api_method.name.to_s - if before_action == false - raise(DispatcherError, "Method filtered") - end - return_value = web_service_direct_invoke_without_controller(invocation) - after_action - return_value - end - - def log_request(ws_request, body) - unless logger.nil? - name = ws_request.method_name - api_method = ws_request.api_method - params = ws_request.method_params - if api_method && api_method.expects - params = api_method.expects.zip(params).map{ |type, param| "#{type.name}=>#{param.inspect}" } - else - params = params.map{ |param| param.inspect } - end - service = ws_request.service_name - logger.debug("\nWeb Service Request: #{name}(#{params.join(", ")}) Entrypoint: #{service}") - logger.debug(indent(body)) - end - end - - def log_response(ws_response, elapsed=nil) - unless logger.nil? - elapsed = (elapsed ? " (%f):" % elapsed : ":") - logger.debug("\nWeb Service Response" + elapsed + " => #{ws_response.return_value.inspect}") - logger.debug(indent(ws_response.body)) - end - end - - def indent(body) - body.split(/\n/).map{|x| " #{x}"}.join("\n") - end - end - - module WsdlAction # :nodoc: - XsdNs = 'http://www.w3.org/2001/XMLSchema' - WsdlNs = 'http://schemas.xmlsoap.org/wsdl/' - SoapNs = 'http://schemas.xmlsoap.org/wsdl/soap/' - SoapEncodingNs = 'http://schemas.xmlsoap.org/soap/encoding/' - SoapHttpTransport = 'http://schemas.xmlsoap.org/soap/http' - - def wsdl - case request.method - when :get - begin - options = { :type => 'text/xml', :disposition => 'inline' } - send_data(to_wsdl, options) - rescue Exception => e - log_error(e) unless logger.nil? - end - when :post - render_text('POST not supported', '500 POST not supported') - end - end - - private - def base_uri - host = request.env['HTTP_HOST'] || request.env['SERVER_NAME'] || 'localhost' - relative_url_root = request.relative_url_root - scheme = request.ssl? ? 'https' : 'http' - '%s://%s%s/%s/' % [scheme, host, relative_url_root, self.class.controller_path] - end - - def to_wsdl - xml = '' - dispatching_mode = web_service_dispatching_mode - global_service_name = wsdl_service_name - namespace = wsdl_namespace || 'urn:ActionWebService' - soap_action_base = "/#{controller_name}" - - marshaler = ActionWebService::Protocol::Soap::SoapMarshaler.new(namespace) - apis = {} - case dispatching_mode - when :direct - api = self.class.web_service_api - web_service_name = controller_class_name.sub(/Controller$/, '').underscore - apis[web_service_name] = [api, register_api(api, marshaler)] - when :delegated, :layered - self.class.web_services.each do |web_service_name, info| - service = web_service_object(web_service_name) - api = service.class.web_service_api - apis[web_service_name] = [api, register_api(api, marshaler)] - end - end - custom_types = [] - apis.values.each do |api, bindings| - bindings.each do |b| - custom_types << b unless custom_types.include?(b) - end - end - - xm = Builder::XmlMarkup.new(:target => xml, :indent => 2) - xm.instruct! - xm.definitions('name' => wsdl_service_name, - 'targetNamespace' => namespace, - 'xmlns:typens' => namespace, - 'xmlns:xsd' => XsdNs, - 'xmlns:soap' => SoapNs, - 'xmlns:soapenc' => SoapEncodingNs, - 'xmlns:wsdl' => WsdlNs, - 'xmlns' => WsdlNs) do - # Generate XSD - if custom_types.size > 0 - xm.types do - xm.xsd(:schema, 'xmlns' => XsdNs, 'targetNamespace' => namespace) do - custom_types.each do |binding| - case - when binding.type.array? - xm.xsd(:complexType, 'name' => binding.type_name) do - xm.xsd(:complexContent) do - xm.xsd(:restriction, 'base' => 'soapenc:Array') do - xm.xsd(:attribute, 'ref' => 'soapenc:arrayType', - 'wsdl:arrayType' => binding.element_binding.qualified_type_name('typens') + '[]') - end - end - end - when binding.type.structured? - xm.xsd(:complexType, 'name' => binding.type_name) do - xm.xsd(:all) do - binding.type.each_member do |name, type| - b = marshaler.register_type(type) - xm.xsd(:element, 'name' => name, 'type' => b.qualified_type_name('typens')) - end - end - end - end - end - end - end - end - - # APIs - apis.each do |api_name, values| - api = values[0] - api.api_methods.each do |name, method| - gen = lambda do |msg_name, direction| - xm.message('name' => message_name_for(api_name, msg_name)) do - sym = nil - if direction == :out - returns = method.returns - if returns - binding = marshaler.register_type(returns[0]) - xm.part('name' => 'return', 'type' => binding.qualified_type_name('typens')) - end - else - expects = method.expects - expects.each do |type| - binding = marshaler.register_type(type) - xm.part('name' => type.name, 'type' => binding.qualified_type_name('typens')) - end if expects - end - end - end - public_name = method.public_name - gen.call(public_name, :in) - gen.call("#{public_name}Response", :out) - end - - # Port - port_name = port_name_for(global_service_name, api_name) - xm.portType('name' => port_name) do - api.api_methods.each do |name, method| - xm.operation('name' => method.public_name) do - xm.input('message' => "typens:" + message_name_for(api_name, method.public_name)) - xm.output('message' => "typens:" + message_name_for(api_name, "#{method.public_name}Response")) - end - end - end - - # Bind it - binding_name = binding_name_for(global_service_name, api_name) - xm.binding('name' => binding_name, 'type' => "typens:#{port_name}") do - xm.soap(:binding, 'style' => 'rpc', 'transport' => SoapHttpTransport) - api.api_methods.each do |name, method| - xm.operation('name' => method.public_name) do - case web_service_dispatching_mode - when :direct - soap_action = soap_action_base + "/api/" + method.public_name - when :delegated, :layered - soap_action = soap_action_base \ - + "/" + api_name.to_s \ - + "/" + method.public_name - end - xm.soap(:operation, 'soapAction' => soap_action) - xm.input do - xm.soap(:body, - 'use' => 'encoded', - 'namespace' => namespace, - 'encodingStyle' => SoapEncodingNs) - end - xm.output do - xm.soap(:body, - 'use' => 'encoded', - 'namespace' => namespace, - 'encodingStyle' => SoapEncodingNs) - end - end - end - end - end - - # Define it - xm.service('name' => "#{global_service_name}Service") do - apis.each do |api_name, values| - port_name = port_name_for(global_service_name, api_name) - binding_name = binding_name_for(global_service_name, api_name) - case web_service_dispatching_mode - when :direct, :layered - binding_target = 'api' - when :delegated - binding_target = api_name.to_s - end - xm.port('name' => port_name, 'binding' => "typens:#{binding_name}") do - xm.soap(:address, 'location' => "#{base_uri}#{binding_target}") - end - end - end - end - end - - def port_name_for(global_service, service) - "#{global_service}#{service.to_s.camelize}Port" - end - - def binding_name_for(global_service, service) - "#{global_service}#{service.to_s.camelize}Binding" - end - - def message_name_for(api_name, message_name) - mode = web_service_dispatching_mode - if mode == :layered || mode == :delegated - api_name.to_s + '-' + message_name - else - message_name - end - end - - def register_api(api, marshaler) - bindings = {} - traverse_custom_types(api, marshaler, bindings) do |binding| - bindings[binding] = nil unless bindings.has_key?(binding) - element_binding = binding.element_binding - bindings[element_binding] = nil if element_binding && !bindings.has_key?(element_binding) - end - bindings.keys - end - - def traverse_custom_types(api, marshaler, bindings, &block) - api.api_methods.each do |name, method| - expects, returns = method.expects, method.returns - expects.each{ |type| traverse_type(marshaler, type, bindings, &block) if type.custom? } if expects - returns.each{ |type| traverse_type(marshaler, type, bindings, &block) if type.custom? } if returns - end - end - - def traverse_type(marshaler, type, bindings, &block) - binding = marshaler.register_type(type) - return if bindings.has_key?(binding) - bindings[binding] = nil - yield binding - if type.array? - yield marshaler.register_type(type.element_type) - type = type.element_type - end - type.each_member{ |name, type| traverse_type(marshaler, type, bindings, &block) } if type.structured? - end - end - end - end -end diff --git a/tracks/vendor/rails/actionwebservice/lib/action_web_service/invocation.rb b/tracks/vendor/rails/actionwebservice/lib/action_web_service/invocation.rb deleted file mode 100644 index 62f38b8e..00000000 --- a/tracks/vendor/rails/actionwebservice/lib/action_web_service/invocation.rb +++ /dev/null @@ -1,205 +0,0 @@ -module ActionWebService # :nodoc: - module Invocation # :nodoc: - class InvocationError < ActionWebService::ActionWebServiceError # :nodoc: - end - - def self.append_features(base) # :nodoc: - super - base.extend(ClassMethods) - base.send(:include, ActionWebService::Invocation::InstanceMethods) - end - - # Invocation interceptors provide a means to execute custom code before - # and after method invocations on ActionWebService::Base objects. - # - # When running in _Direct_ dispatching mode, ActionController filters - # should be used for this functionality instead. - # - # The semantics of invocation interceptors are the same as ActionController - # filters, and accept the same parameters and options. - # - # A _before_ interceptor can also cancel execution by returning +false+, - # or returning a [false, "cancel reason"] array if it wishes to supply - # a reason for canceling the request. - # - # === Example - # - # class CustomService < ActionWebService::Base - # before_invocation :intercept_add, :only => [:add] - # - # def add(a, b) - # a + b - # end - # - # private - # def intercept_add - # return [false, "permission denied"] # cancel it - # end - # end - # - # Options: - # [:except] A list of methods for which the interceptor will NOT be called - # [:only] A list of methods for which the interceptor WILL be called - module ClassMethods - # Appends the given +interceptors+ to be called - # _before_ method invocation. - def append_before_invocation(*interceptors, &block) - conditions = extract_conditions!(interceptors) - interceptors << block if block_given? - add_interception_conditions(interceptors, conditions) - append_interceptors_to_chain("before", interceptors) - end - - # Prepends the given +interceptors+ to be called - # _before_ method invocation. - def prepend_before_invocation(*interceptors, &block) - conditions = extract_conditions!(interceptors) - interceptors << block if block_given? - add_interception_conditions(interceptors, conditions) - prepend_interceptors_to_chain("before", interceptors) - end - - alias :before_invocation :append_before_invocation - - # Appends the given +interceptors+ to be called - # _after_ method invocation. - def append_after_invocation(*interceptors, &block) - conditions = extract_conditions!(interceptors) - interceptors << block if block_given? - add_interception_conditions(interceptors, conditions) - append_interceptors_to_chain("after", interceptors) - end - - # Prepends the given +interceptors+ to be called - # _after_ method invocation. - def prepend_after_invocation(*interceptors, &block) - conditions = extract_conditions!(interceptors) - interceptors << block if block_given? - add_interception_conditions(interceptors, conditions) - prepend_interceptors_to_chain("after", interceptors) - end - - alias :after_invocation :append_after_invocation - - def before_invocation_interceptors # :nodoc: - read_inheritable_attribute("before_invocation_interceptors") - end - - def after_invocation_interceptors # :nodoc: - read_inheritable_attribute("after_invocation_interceptors") - end - - def included_intercepted_methods # :nodoc: - read_inheritable_attribute("included_intercepted_methods") || {} - end - - def excluded_intercepted_methods # :nodoc: - read_inheritable_attribute("excluded_intercepted_methods") || {} - end - - private - def append_interceptors_to_chain(condition, interceptors) - write_inheritable_array("#{condition}_invocation_interceptors", interceptors) - end - - def prepend_interceptors_to_chain(condition, interceptors) - interceptors = interceptors + read_inheritable_attribute("#{condition}_invocation_interceptors") - write_inheritable_attribute("#{condition}_invocation_interceptors", interceptors) - end - - def extract_conditions!(interceptors) - return nil unless interceptors.last.is_a? Hash - interceptors.pop - end - - def add_interception_conditions(interceptors, conditions) - return unless conditions - included, excluded = conditions[:only], conditions[:except] - write_inheritable_hash("included_intercepted_methods", condition_hash(interceptors, included)) && return if included - write_inheritable_hash("excluded_intercepted_methods", condition_hash(interceptors, excluded)) if excluded - end - - def condition_hash(interceptors, *methods) - interceptors.inject({}) {|hash, interceptor| hash.merge(interceptor => methods.flatten.map {|method| method.to_s})} - end - end - - module InstanceMethods # :nodoc: - def self.append_features(base) - super - base.class_eval do - alias_method :perform_invocation_without_interception, :perform_invocation - alias_method :perform_invocation, :perform_invocation_with_interception - end - end - - def perform_invocation_with_interception(method_name, params, &block) - return if before_invocation(method_name, params, &block) == false - return_value = perform_invocation_without_interception(method_name, params) - after_invocation(method_name, params, return_value) - return_value - end - - def perform_invocation(method_name, params) - send(method_name, *params) - end - - def before_invocation(name, args, &block) - call_interceptors(self.class.before_invocation_interceptors, [name, args], &block) - end - - def after_invocation(name, args, result) - call_interceptors(self.class.after_invocation_interceptors, [name, args, result]) - end - - private - - def call_interceptors(interceptors, interceptor_args, &block) - if interceptors and not interceptors.empty? - interceptors.each do |interceptor| - next if method_exempted?(interceptor, interceptor_args[0].to_s) - result = case - when interceptor.is_a?(Symbol) - self.send(interceptor, *interceptor_args) - when interceptor_block?(interceptor) - interceptor.call(self, *interceptor_args) - when interceptor_class?(interceptor) - interceptor.intercept(self, *interceptor_args) - else - raise( - InvocationError, - "Interceptors need to be either a symbol, proc/method, or a class implementing a static intercept method" - ) - end - reason = nil - if result.is_a?(Array) - reason = result[1] if result[1] - result = result[0] - end - if result == false - block.call(reason) if block && reason - return false - end - end - end - end - - def interceptor_block?(interceptor) - interceptor.respond_to?("call") && (interceptor.arity == 3 || interceptor.arity == -1) - end - - def interceptor_class?(interceptor) - interceptor.respond_to?("intercept") - end - - def method_exempted?(interceptor, method_name) - case - when self.class.included_intercepted_methods[interceptor] - !self.class.included_intercepted_methods[interceptor].include?(method_name) - when self.class.excluded_intercepted_methods[interceptor] - self.class.excluded_intercepted_methods[interceptor].include?(method_name) - end - end - end - end -end diff --git a/tracks/vendor/rails/actionwebservice/lib/action_web_service/protocol.rb b/tracks/vendor/rails/actionwebservice/lib/action_web_service/protocol.rb deleted file mode 100644 index 053e9cb4..00000000 --- a/tracks/vendor/rails/actionwebservice/lib/action_web_service/protocol.rb +++ /dev/null @@ -1,4 +0,0 @@ -require 'action_web_service/protocol/abstract' -require 'action_web_service/protocol/discovery' -require 'action_web_service/protocol/soap_protocol' -require 'action_web_service/protocol/xmlrpc_protocol' diff --git a/tracks/vendor/rails/actionwebservice/lib/action_web_service/protocol/abstract.rb b/tracks/vendor/rails/actionwebservice/lib/action_web_service/protocol/abstract.rb deleted file mode 100644 index fff5f622..00000000 --- a/tracks/vendor/rails/actionwebservice/lib/action_web_service/protocol/abstract.rb +++ /dev/null @@ -1,112 +0,0 @@ -module ActionWebService # :nodoc: - module Protocol # :nodoc: - class ProtocolError < ActionWebServiceError # :nodoc: - end - - class AbstractProtocol # :nodoc: - def setup(controller) - end - - def decode_action_pack_request(action_pack_request) - end - - def encode_action_pack_request(service_name, public_method_name, raw_body, options={}) - klass = options[:request_class] || SimpleActionPackRequest - request = klass.new - request.request_parameters['action'] = service_name.to_s - request.env['RAW_POST_DATA'] = raw_body - request.env['REQUEST_METHOD'] = 'POST' - request.env['HTTP_CONTENT_TYPE'] = 'text/xml' - request - end - - def decode_request(raw_request, service_name, protocol_options={}) - end - - def encode_request(method_name, params, param_types) - end - - def decode_response(raw_response) - end - - def encode_response(method_name, return_value, return_type, protocol_options={}) - end - - def protocol_client(api, protocol_name, endpoint_uri, options) - end - - def register_api(api) - end - end - - class Request # :nodoc: - attr :protocol - attr_accessor :method_name - attr_accessor :method_params - attr :service_name - attr_accessor :api - attr_accessor :api_method - attr :protocol_options - - def initialize(protocol, method_name, method_params, service_name, api=nil, api_method=nil, protocol_options=nil) - @protocol = protocol - @method_name = method_name - @method_params = method_params - @service_name = service_name - @api = api - @api_method = api_method - @protocol_options = protocol_options || {} - end - end - - class Response # :nodoc: - attr :body - attr :content_type - attr :return_value - - def initialize(body, content_type, return_value) - @body = body - @content_type = content_type - @return_value = return_value - end - end - - class SimpleActionPackRequest < ActionController::AbstractRequest # :nodoc: - def initialize - @env = {} - @qparams = {} - @rparams = {} - @cookies = {} - reset_session - end - - def query_parameters - @qparams - end - - def request_parameters - @rparams - end - - def env - @env - end - - def host - '' - end - - def cookies - @cookies - end - - def session - @session - end - - def reset_session - @session = {} - end - end - end -end diff --git a/tracks/vendor/rails/actionwebservice/lib/action_web_service/protocol/discovery.rb b/tracks/vendor/rails/actionwebservice/lib/action_web_service/protocol/discovery.rb deleted file mode 100644 index 3d4e0818..00000000 --- a/tracks/vendor/rails/actionwebservice/lib/action_web_service/protocol/discovery.rb +++ /dev/null @@ -1,37 +0,0 @@ -module ActionWebService # :nodoc: - module Protocol # :nodoc: - module Discovery # :nodoc: - def self.included(base) - base.extend(ClassMethods) - base.send(:include, ActionWebService::Protocol::Discovery::InstanceMethods) - end - - module ClassMethods # :nodoc: - def register_protocol(klass) - write_inheritable_array("web_service_protocols", [klass]) - end - end - - module InstanceMethods # :nodoc: - private - def discover_web_service_request(action_pack_request) - (self.class.read_inheritable_attribute("web_service_protocols") || []).each do |protocol| - protocol = protocol.create(self) - request = protocol.decode_action_pack_request(action_pack_request) - return request unless request.nil? - end - nil - end - - def create_web_service_client(api, protocol_name, endpoint_uri, options) - (self.class.read_inheritable_attribute("web_service_protocols") || []).each do |protocol| - protocol = protocol.create(self) - client = protocol.protocol_client(api, protocol_name, endpoint_uri, options) - return client unless client.nil? - end - nil - end - end - end - end -end diff --git a/tracks/vendor/rails/actionwebservice/lib/action_web_service/protocol/soap_protocol.rb b/tracks/vendor/rails/actionwebservice/lib/action_web_service/protocol/soap_protocol.rb deleted file mode 100644 index 1bce496a..00000000 --- a/tracks/vendor/rails/actionwebservice/lib/action_web_service/protocol/soap_protocol.rb +++ /dev/null @@ -1,176 +0,0 @@ -require 'action_web_service/protocol/soap_protocol/marshaler' -require 'soap/streamHandler' -require 'action_web_service/client/soap_client' - -module ActionWebService # :nodoc: - module API # :nodoc: - class Base # :nodoc: - def self.soap_client(endpoint_uri, options={}) - ActionWebService::Client::Soap.new self, endpoint_uri, options - end - end - end - - module Protocol # :nodoc: - module Soap # :nodoc: - def self.included(base) - base.register_protocol(SoapProtocol) - base.class_inheritable_option(:wsdl_service_name) - base.class_inheritable_option(:wsdl_namespace) - end - - class SoapProtocol < AbstractProtocol # :nodoc: - AWSEncoding = 'UTF-8' - XSDEncoding = 'UTF8' - - attr :marshaler - - def initialize(namespace=nil) - namespace ||= 'urn:ActionWebService' - @marshaler = SoapMarshaler.new namespace - end - - def self.create(controller) - SoapProtocol.new(controller.wsdl_namespace) - end - - def decode_action_pack_request(action_pack_request) - return nil unless soap_action = has_valid_soap_action?(action_pack_request) - service_name = action_pack_request.parameters['action'] - input_encoding = parse_charset(action_pack_request.env['HTTP_CONTENT_TYPE']) - protocol_options = { - :soap_action => soap_action, - :charset => input_encoding - } - decode_request(action_pack_request.raw_post, service_name, protocol_options) - end - - def encode_action_pack_request(service_name, public_method_name, raw_body, options={}) - request = super - request.env['HTTP_SOAPACTION'] = '/soap/%s/%s' % [service_name, public_method_name] - request - end - - def decode_request(raw_request, service_name, protocol_options={}) - envelope = SOAP::Processor.unmarshal(raw_request, :charset => protocol_options[:charset]) - unless envelope - raise ProtocolError, "Failed to parse SOAP request message" - end - request = envelope.body.request - method_name = request.elename.name - params = request.collect{ |k, v| marshaler.soap_to_ruby(request[k]) } - Request.new(self, method_name, params, service_name, nil, nil, protocol_options) - end - - def encode_request(method_name, params, param_types) - param_types.each{ |type| marshaler.register_type(type) } if param_types - qname = XSD::QName.new(marshaler.namespace, method_name) - param_def = [] - if param_types - params = param_types.zip(params).map do |type, param| - param_def << ['in', type.name, marshaler.lookup_type(type).mapping] - [type.name, marshaler.ruby_to_soap(param)] - end - else - params = [] - end - request = SOAP::RPC::SOAPMethodRequest.new(qname, param_def) - request.set_param(params) - envelope = create_soap_envelope(request) - SOAP::Processor.marshal(envelope) - end - - def decode_response(raw_response) - envelope = SOAP::Processor.unmarshal(raw_response) - unless envelope - raise ProtocolError, "Failed to parse SOAP request message" - end - method_name = envelope.body.request.elename.name - return_value = envelope.body.response - return_value = marshaler.soap_to_ruby(return_value) unless return_value.nil? - [method_name, return_value] - end - - def encode_response(method_name, return_value, return_type, protocol_options={}) - if return_type - return_binding = marshaler.register_type(return_type) - marshaler.annotate_arrays(return_binding, return_value) - end - qname = XSD::QName.new(marshaler.namespace, method_name) - if return_value.nil? - response = SOAP::RPC::SOAPMethodResponse.new(qname, nil) - else - if return_value.is_a?(Exception) - detail = SOAP::Mapping::SOAPException.new(return_value) - response = SOAP::SOAPFault.new( - SOAP::SOAPQName.new('%s:%s' % [SOAP::SOAPNamespaceTag, 'Server']), - SOAP::SOAPString.new(return_value.to_s), - SOAP::SOAPString.new(self.class.name), - marshaler.ruby_to_soap(detail)) - else - if return_type - param_def = [['retval', 'return', marshaler.lookup_type(return_type).mapping]] - response = SOAP::RPC::SOAPMethodResponse.new(qname, param_def) - response.retval = marshaler.ruby_to_soap(return_value) - else - response = SOAP::RPC::SOAPMethodResponse.new(qname, nil) - end - end - end - envelope = create_soap_envelope(response) - - # FIXME: This is not thread-safe, but StringFactory_ in SOAP4R only - # reads target encoding from the XSD::Charset.encoding variable. - # This is required to ensure $KCODE strings are converted - # correctly to UTF-8 for any values of $KCODE. - previous_encoding = XSD::Charset.encoding - XSD::Charset.encoding = XSDEncoding - response_body = SOAP::Processor.marshal(envelope, :charset => AWSEncoding) - XSD::Charset.encoding = previous_encoding - - Response.new(response_body, "text/xml; charset=#{AWSEncoding}", return_value) - end - - def protocol_client(api, protocol_name, endpoint_uri, options={}) - return nil unless protocol_name == :soap - ActionWebService::Client::Soap.new(api, endpoint_uri, options) - end - - def register_api(api) - api.api_methods.each do |name, method| - method.expects.each{ |type| marshaler.register_type(type) } if method.expects - method.returns.each{ |type| marshaler.register_type(type) } if method.returns - end - end - - private - def has_valid_soap_action?(request) - return nil unless request.method == :post - soap_action = request.env['HTTP_SOAPACTION'] - return nil unless soap_action - soap_action = soap_action.dup - soap_action.gsub!(/^"/, '') - soap_action.gsub!(/"$/, '') - soap_action.strip! - return nil if soap_action.empty? - soap_action - end - - def create_soap_envelope(body) - header = SOAP::SOAPHeader.new - body = SOAP::SOAPBody.new(body) - SOAP::SOAPEnvelope.new(header, body) - end - - def parse_charset(content_type) - return AWSEncoding if content_type.nil? - if /^text\/xml(?:\s*;\s*charset=([^"]+|"[^"]+"))$/i =~ content_type - $1 - else - AWSEncoding - end - end - end - end - end -end diff --git a/tracks/vendor/rails/actionwebservice/lib/action_web_service/protocol/soap_protocol/marshaler.rb b/tracks/vendor/rails/actionwebservice/lib/action_web_service/protocol/soap_protocol/marshaler.rb deleted file mode 100644 index b36e0296..00000000 --- a/tracks/vendor/rails/actionwebservice/lib/action_web_service/protocol/soap_protocol/marshaler.rb +++ /dev/null @@ -1,237 +0,0 @@ -require 'soap/mapping' - -module ActionWebService - module Protocol - module Soap - # Workaround for SOAP4R return values changing - class Registry < SOAP::Mapping::Registry - if SOAP::Version >= "1.5.4" - def find_mapped_soap_class(obj_class) - return @map.instance_eval { @obj2soap[obj_class][0] } - end - - def find_mapped_obj_class(soap_class) - return @map.instance_eval { @soap2obj[soap_class][0] } - end - end - end - - class SoapMarshaler - attr :namespace - attr :registry - - def initialize(namespace=nil) - @namespace = namespace || 'urn:ActionWebService' - @registry = Registry.new - @type2binding = {} - register_static_factories - end - - def soap_to_ruby(obj) - SOAP::Mapping.soap2obj(obj, @registry) - end - - def ruby_to_soap(obj) - SOAP::Mapping.obj2soap(obj, @registry) - end - - def register_type(type) - return @type2binding[type] if @type2binding.has_key?(type) - - type_class = type.array?? type.element_type.type_class : type.type_class - type_type = type.array?? type.element_type : type - type_binding = nil - if (mapping = @registry.find_mapped_soap_class(type_class) rescue nil) - qname = mapping[2] ? mapping[2][:type] : nil - qname ||= soap_base_type_name(mapping[0]) - type_binding = SoapBinding.new(self, qname, type_type, mapping) - else - qname = XSD::QName.new(@namespace, soap_type_name(type_class.name)) - @registry.add(type_class, - SOAP::SOAPStruct, - typed_struct_factory(type_class), - { :type => qname }) - mapping = @registry.find_mapped_soap_class(type_class) - type_binding = SoapBinding.new(self, qname, type_type, mapping) - end - - array_binding = nil - if type.array? - array_mapping = @registry.find_mapped_soap_class(Array) - qname = XSD::QName.new(@namespace, soap_type_name(type.element_type.type_class.name) + 'Array') - array_binding = SoapBinding.new(self, qname, type, array_mapping, type_binding) - end - - @type2binding[type] = array_binding ? array_binding : type_binding - @type2binding[type] - end - alias :lookup_type :register_type - - def annotate_arrays(binding, value) - if binding.type.array? - mark_typed_array(value, binding.element_binding.qname) - if binding.element_binding.type.custom? - value.each do |element| - annotate_arrays(binding.element_binding, element) - end - end - elsif binding.type.structured? - binding.type.each_member do |name, type| - member_binding = register_type(type) - member_value = value.respond_to?('[]') ? value[name] : value.send(name) - annotate_arrays(member_binding, member_value) if type.custom? - end - end - end - - private - def typed_struct_factory(type_class) - if Object.const_defined?('ActiveRecord') - if type_class.ancestors.include?(ActiveRecord::Base) - qname = XSD::QName.new(@namespace, soap_type_name(type_class.name)) - type_class.instance_variable_set('@qname', qname) - return SoapActiveRecordStructFactory.new - end - end - SOAP::Mapping::Registry::TypedStructFactory - end - - def mark_typed_array(array, qname) - (class << array; self; end).class_eval do - define_method(:arytype) do - qname - end - end - end - - def soap_base_type_name(type) - xsd_type = type.ancestors.find{ |c| c.const_defined? 'Type' } - xsd_type ? xsd_type.const_get('Type') : XSD::XSDAnySimpleType::Type - end - - def soap_type_name(type_name) - type_name.gsub(/::/, '..') - end - - def register_static_factories - @registry.add(ActionWebService::Base64, - SOAP::SOAPBase64, - SoapBase64Factory.new, - nil) - mapping = @registry.find_mapped_soap_class(ActionWebService::Base64) - @type2binding[ActionWebService::Base64] = - SoapBinding.new(self, SOAP::SOAPBase64::Type, - ActionWebService::Base64, mapping) - @registry.add(Array, - SOAP::SOAPArray, - SoapTypedArrayFactory.new, - nil) - end - end - - class SoapBinding - attr :qname - attr :type - attr :mapping - attr :element_binding - - def initialize(marshaler, qname, type, mapping, element_binding=nil) - @marshaler = marshaler - @qname = qname - @type = type - @mapping = mapping - @element_binding = element_binding - end - - def type_name - @type.custom? ? @qname.name : nil - end - - def qualified_type_name(ns=nil) - if @type.custom? - "#{ns ? ns : @qname.namespace}:#{@qname.name}" - else - ns = XSD::NS.new - ns.assign(XSD::Namespace, SOAP::XSDNamespaceTag) - ns.assign(SOAP::EncodingNamespace, "soapenc") - xsd_klass = mapping[0].ancestors.find{|c| c.const_defined?('Type')} - return ns.name(XSD::AnyTypeName) unless xsd_klass - ns.name(xsd_klass.const_get('Type')) - end - end - - def eql?(other) - @qname == other.qname - end - alias :== :eql? - - def hash - @qname.hash - end - end - - class SoapActiveRecordStructFactory < SOAP::Mapping::Factory - def obj2soap(soap_class, obj, info, map) - unless obj.is_a?(ActiveRecord::Base) - return nil - end - soap_obj = soap_class.new(obj.class.instance_variable_get('@qname')) - obj.class.columns.each do |column| - key = column.name.to_s - value = obj.send(key) - soap_obj[key] = SOAP::Mapping._obj2soap(value, map) - end - soap_obj - end - - def soap2obj(obj_class, node, info, map) - unless node.type == obj_class.instance_variable_get('@qname') - return false - end - obj = obj_class.new - node.each do |key, value| - obj[key] = value.data - end - obj.instance_variable_set('@new_record', false) - return true, obj - end - end - - class SoapTypedArrayFactory < SOAP::Mapping::Factory - def obj2soap(soap_class, obj, info, map) - unless obj.respond_to?(:arytype) - return nil - end - soap_obj = soap_class.new(SOAP::ValueArrayName, 1, obj.arytype) - mark_marshalled_obj(obj, soap_obj) - obj.each do |item| - child = SOAP::Mapping._obj2soap(item, map) - soap_obj.add(child) - end - soap_obj - end - - def soap2obj(obj_class, node, info, map) - return false - end - end - - class SoapBase64Factory < SOAP::Mapping::Factory - def obj2soap(soap_class, obj, info, map) - unless obj.is_a?(ActionWebService::Base64) - return nil - end - return soap_class.new(obj) - end - - def soap2obj(obj_class, node, info, map) - unless node.type == SOAP::SOAPBase64::Type - return false - end - return true, obj_class.new(node.string) - end - end - - end - end -end diff --git a/tracks/vendor/rails/actionwebservice/lib/action_web_service/protocol/xmlrpc_protocol.rb b/tracks/vendor/rails/actionwebservice/lib/action_web_service/protocol/xmlrpc_protocol.rb deleted file mode 100644 index 53b67ced..00000000 --- a/tracks/vendor/rails/actionwebservice/lib/action_web_service/protocol/xmlrpc_protocol.rb +++ /dev/null @@ -1,97 +0,0 @@ -require 'xmlrpc/marshal' -require 'action_web_service/client/xmlrpc_client' - -module XMLRPC # :nodoc: - class FaultException # :nodoc: - alias :message :faultString - end -end - -module ActionWebService # :nodoc: - module API # :nodoc: - class Base # :nodoc: - def self.xmlrpc_client(endpoint_uri, options={}) - ActionWebService::Client::XmlRpc.new self, endpoint_uri, options - end - end - end - - module Protocol # :nodoc: - module XmlRpc # :nodoc: - def self.included(base) - base.register_protocol(XmlRpcProtocol) - end - - class XmlRpcProtocol < AbstractProtocol # :nodoc: - def self.create(controller) - XmlRpcProtocol.new - end - - def decode_action_pack_request(action_pack_request) - service_name = action_pack_request.parameters['action'] - decode_request(action_pack_request.raw_post, service_name) - end - - def decode_request(raw_request, service_name) - method_name, params = XMLRPC::Marshal.load_call(raw_request) - Request.new(self, method_name, params, service_name) - end - - def encode_request(method_name, params, param_types) - if param_types - params = params.dup - param_types.each_with_index{ |type, i| params[i] = value_to_xmlrpc_wire_format(params[i], type) } - end - XMLRPC::Marshal.dump_call(method_name, *params) - end - - def decode_response(raw_response) - [nil, XMLRPC::Marshal.load_response(raw_response)] - end - - def encode_response(method_name, return_value, return_type, protocol_options={}) - return_value = true if return_value.nil? - if return_type - return_value = value_to_xmlrpc_wire_format(return_value, return_type) - end - raw_response = XMLRPC::Marshal.dump_response(return_value) - Response.new(raw_response, 'text/xml', return_value) - end - - def protocol_client(api, protocol_name, endpoint_uri, options={}) - return nil unless protocol_name == :xmlrpc - ActionWebService::Client::XmlRpc.new(api, endpoint_uri, options) - end - - def value_to_xmlrpc_wire_format(value, value_type) - if value_type.array? - value.map{ |val| value_to_xmlrpc_wire_format(val, value_type.element_type) } - else - if value.is_a?(ActionWebService::Struct) - struct = {} - value.class.members.each do |name, type| - member_value = value[name] - next if member_value.nil? - struct[name.to_s] = value_to_xmlrpc_wire_format(member_value, type) - end - struct - elsif value.is_a?(ActiveRecord::Base) - struct = {} - value.attributes.each do |key, member_value| - next if member_value.nil? - struct[key.to_s] = member_value - end - struct - elsif value.is_a?(ActionWebService::Base64) - XMLRPC::Base64.new(value) - elsif value.is_a?(Exception) && !value.is_a?(XMLRPC::FaultException) - XMLRPC::FaultException.new(2, value.message) - else - value - end - end - end - end - end - end -end diff --git a/tracks/vendor/rails/actionwebservice/lib/action_web_service/scaffolding.rb b/tracks/vendor/rails/actionwebservice/lib/action_web_service/scaffolding.rb deleted file mode 100644 index 59fec0ef..00000000 --- a/tracks/vendor/rails/actionwebservice/lib/action_web_service/scaffolding.rb +++ /dev/null @@ -1,275 +0,0 @@ -require 'benchmark' -require 'pathname' - -module ActionWebService - module Scaffolding # :nodoc: - class ScaffoldingError < ActionWebServiceError # :nodoc: - end - - def self.append_features(base) - super - base.extend(ClassMethods) - end - - # Web service invocation scaffolding provides a way to quickly invoke web service methods in a controller. The - # generated scaffold actions have default views to let you enter the method parameters and view the - # results. - # - # Example: - # - # class ApiController < ActionController - # web_service_scaffold :invoke - # end - # - # This example generates an +invoke+ action in the +ApiController+ that you can navigate to from - # your browser, select the API method, enter its parameters, and perform the invocation. - # - # If you want to customize the default views, create the following views in "app/views": - # - # * action_name/methods.rhtml - # * action_name/parameters.rhtml - # * action_name/result.rhtml - # * action_name/layout.rhtml - # - # Where action_name is the name of the action you gave to ClassMethods#web_service_scaffold. - # - # You can use the default views in RAILS_DIR/lib/action_web_service/templates/scaffolds as - # a guide. - module ClassMethods - # Generates web service invocation scaffolding for the current controller. The given action name - # can then be used as the entry point for invoking API methods from a web browser. - def web_service_scaffold(action_name) - add_template_helper(Helpers) - module_eval <<-"end_eval", __FILE__, __LINE__ - def #{action_name} - if request.method == :get - setup_invocation_assigns - render_invocation_scaffold 'methods' - end - end - - def #{action_name}_method_params - if request.method == :get - setup_invocation_assigns - render_invocation_scaffold 'parameters' - end - end - - def #{action_name}_submit - if request.method == :post - setup_invocation_assigns - protocol_name = params['protocol'] ? params['protocol'].to_sym : :soap - case protocol_name - when :soap - @protocol = Protocol::Soap::SoapProtocol.create(self) - when :xmlrpc - @protocol = Protocol::XmlRpc::XmlRpcProtocol.create(self) - end - @invocation_cgi = request.respond_to?(:cgi) ? request.cgi : nil - bm = Benchmark.measure do - @protocol.register_api(@scaffold_service.api) - post_params = params['method_params'] ? params['method_params'].dup : nil - params = [] - if @scaffold_method.expects - @scaffold_method.expects.length.times do |i| - params << post_params[i.to_s] - end - end - params = @scaffold_method.cast_expects(params) - method_name = public_method_name(@scaffold_service.name, @scaffold_method.public_name) - @method_request_xml = @protocol.encode_request(method_name, params, @scaffold_method.expects) - new_request = @protocol.encode_action_pack_request(@scaffold_service.name, @scaffold_method.public_name, @method_request_xml) - prepare_request(new_request, @scaffold_service.name, @scaffold_method.public_name) - @request = new_request - if @scaffold_container.dispatching_mode != :direct - request.parameters['action'] = @scaffold_service.name - end - dispatch_web_service_request - @method_response_xml = @response.body - method_name, obj = @protocol.decode_response(@method_response_xml) - return if handle_invocation_exception(obj) - @method_return_value = @scaffold_method.cast_returns(obj) - end - @method_elapsed = bm.real - add_instance_variables_to_assigns - reset_invocation_response - render_invocation_scaffold 'result' - end - end - - private - def setup_invocation_assigns - @scaffold_class = self.class - @scaffold_action_name = "#{action_name}" - @scaffold_container = WebServiceModel::Container.new(self) - if params['service'] && params['method'] - @scaffold_service = @scaffold_container.services.find{ |x| x.name == params['service'] } - @scaffold_method = @scaffold_service.api_methods[params['method']] - end - add_instance_variables_to_assigns - end - - def render_invocation_scaffold(action) - customized_template = "\#{self.class.controller_path}/#{action_name}/\#{action}" - default_template = scaffold_path(action) - if template_exists?(customized_template) - content = @template.render_file(customized_template) - else - content = @template.render_file(default_template, false) - end - @template.instance_variable_set("@content_for_layout", content) - if self.active_layout.nil? - render_file(scaffold_path("layout")) - else - render_file(self.active_layout, "200 OK", true) - end - end - - def scaffold_path(template_name) - File.dirname(__FILE__) + "/templates/scaffolds/" + template_name + ".rhtml" - end - - def reset_invocation_response - template = response.template - if @invocation_cgi - @response = ::ActionController::CgiResponse.new(@invocation_cgi) - else - @response = ::ActionController::TestResponse.new - end - response.template = template - @performed_render = false - end - - def public_method_name(service_name, method_name) - if web_service_dispatching_mode == :layered && @protocol.is_a?(ActionWebService::Protocol::XmlRpc::XmlRpcProtocol) - service_name + '.' + method_name - else - method_name - end - end - - def prepare_request(new_request, service_name, method_name) - new_request.parameters.update(request.parameters) - request.env.each{ |k, v| new_request.env[k] = v unless new_request.env.has_key?(k) } - if web_service_dispatching_mode == :layered && @protocol.is_a?(ActionWebService::Protocol::Soap::SoapProtocol) - new_request.env['HTTP_SOAPACTION'] = "/\#{controller_name()}/\#{service_name}/\#{method_name}" - end - end - - def handle_invocation_exception(obj) - exception = nil - if obj.respond_to?(:detail) && obj.detail.respond_to?(:cause) && obj.detail.cause.is_a?(Exception) - exception = obj.detail.cause - elsif obj.is_a?(XMLRPC::FaultException) - exception = obj - end - return unless exception - reset_invocation_response - rescue_action(exception) - true - end - end_eval - end - end - - module Helpers # :nodoc: - def method_parameter_input_fields(method, type, field_name_base) - if type.array? - return content_tag('em', "Typed array input fields not supported yet (#{type.name})") - end - if type.structured? - parameters = "" - type.each_member do |member_name, member_type| - label = method_parameter_label(member_name, member_type) - nested_content = method_parameter_input_fields( - method, - member_type, - field_name_base + '[' + member_name.to_s + ']') - if member_type.custom? - parameters << content_tag('li', label) - parameters << content_tag('ul', nested_content) - else - parameters << content_tag('li', label + ' ' + nested_content) - end - end - content_tag('ul', parameters) - else - case type.type - when :int - text_field_tag field_name_base - when :string - text_field_tag field_name_base - when :bool - radio_button_tag(field_name_base, "true") + " True" + - radio_button_tag(field_name_base, "false") + "False" - when :float - text_field_tag field_name_base - when :time - select_datetime Time.now, 'name' => field_name_base - when :date - select_date Date.today, 'name' => field_name_base - end - end - end - - def method_parameter_label(name, type) - name.to_s.capitalize + ' (' + type.human_name(false) + ')' - end - - def service_method_list(service) - action = @scaffold_action_name + '_method_params' - methods = service.api_methods_full.map do |desc, name| - content_tag("li", link_to(desc, :action => action, :service => service.name, :method => name)) - end - content_tag("ul", methods.join("\n")) - end - end - - module WebServiceModel # :nodoc: - class Container # :nodoc: - attr :services - attr :dispatching_mode - - def initialize(real_container) - @real_container = real_container - @dispatching_mode = @real_container.class.web_service_dispatching_mode - @services = [] - if @dispatching_mode == :direct - @services << Service.new(@real_container.controller_name, @real_container) - else - @real_container.class.web_services.each do |name, obj| - @services << Service.new(name, @real_container.instance_eval{ web_service_object(name) }) - end - end - end - end - - class Service # :nodoc: - attr :name - attr :object - attr :api - attr :api_methods - attr :api_methods_full - - def initialize(name, real_service) - @name = name.to_s - @object = real_service - @api = @object.class.web_service_api - if @api.nil? - raise ScaffoldingError, "No web service API attached to #{object.class}" - end - @api_methods = {} - @api_methods_full = [] - @api.api_methods.each do |name, method| - @api_methods[method.public_name.to_s] = method - @api_methods_full << [method.to_s, method.public_name.to_s] - end - end - - def to_s - self.name.camelize - end - end - end - end -end diff --git a/tracks/vendor/rails/actionwebservice/lib/action_web_service/struct.rb b/tracks/vendor/rails/actionwebservice/lib/action_web_service/struct.rb deleted file mode 100644 index 536207aa..00000000 --- a/tracks/vendor/rails/actionwebservice/lib/action_web_service/struct.rb +++ /dev/null @@ -1,65 +0,0 @@ -module ActionWebService - # To send structured types across the wire, derive from ActionWebService::Struct, - # and use +member+ to declare structure members. - # - # ActionWebService::Struct should be used in method signatures when you want to accept or return - # structured types that have no Active Record model class representations, or you don't - # want to expose your entire Active Record model to remote callers. - # - # === Example - # - # class Person < ActionWebService::Struct - # member :id, :int - # member :firstnames, [:string] - # member :lastname, :string - # member :email, :string - # end - # person = Person.new(:id => 5, :firstname => 'john', :lastname => 'doe') - # - # Active Record model classes are already implicitly supported in method - # signatures. - class Struct - - # If a Hash is given as argument to an ActionWebService::Struct constructor, - # it can contain initial values for the structure member. - def initialize(values={}) - if values.is_a?(Hash) - values.map{|k,v| __send__('%s=' % k.to_s, v)} - end - end - - # The member with the given name - def [](name) - send(name.to_s) - end - - # Iterates through each member - def each_pair(&block) - self.class.members.each do |name, type| - yield name, self.__send__(name) - end - end - - class << self - # Creates a structure member with the specified +name+ and +type+. Generates - # accessor methods for reading and writing the member value. - def member(name, type) - name = name.to_sym - type = ActionWebService::SignatureTypes.canonical_signature_entry({ name => type }, 0) - write_inheritable_hash("struct_members", name => type) - class_eval <<-END - def #{name}; @#{name}; end - def #{name}=(value); @#{name} = value; end - END - end - - def members # :nodoc: - read_inheritable_attribute("struct_members") || {} - end - - def member_type(name) # :nodoc: - members[name.to_sym] - end - end - end -end diff --git a/tracks/vendor/rails/actionwebservice/lib/action_web_service/support/class_inheritable_options.rb b/tracks/vendor/rails/actionwebservice/lib/action_web_service/support/class_inheritable_options.rb deleted file mode 100644 index 4d1c2ed4..00000000 --- a/tracks/vendor/rails/actionwebservice/lib/action_web_service/support/class_inheritable_options.rb +++ /dev/null @@ -1,26 +0,0 @@ -class Class # :nodoc: - def class_inheritable_option(sym, default_value=nil) - write_inheritable_attribute sym, default_value - class_eval <<-EOS - def self.#{sym}(value=nil) - if !value.nil? - write_inheritable_attribute(:#{sym}, value) - else - read_inheritable_attribute(:#{sym}) - end - end - - def self.#{sym}=(value) - write_inheritable_attribute(:#{sym}, value) - end - - def #{sym} - self.class.#{sym} - end - - def #{sym}=(value) - self.class.#{sym} = value - end - EOS - end -end diff --git a/tracks/vendor/rails/actionwebservice/lib/action_web_service/support/signature_types.rb b/tracks/vendor/rails/actionwebservice/lib/action_web_service/support/signature_types.rb deleted file mode 100644 index 2100eab1..00000000 --- a/tracks/vendor/rails/actionwebservice/lib/action_web_service/support/signature_types.rb +++ /dev/null @@ -1,222 +0,0 @@ -module ActionWebService # :nodoc: - # Action Web Service supports the following base types in a signature: - # - # [:int] Represents an integer value, will be cast to an integer using Integer(value) - # [:string] Represents a string value, will be cast to an string using the to_s method on an object - # [:base64] Represents a Base 64 value, will contain the binary bytes of a Base 64 value sent by the caller - # [:bool] Represents a boolean value, whatever is passed will be cast to boolean (true, '1', 'true', 'y', 'yes' are taken to represent true; false, '0', 'false', 'n', 'no' and nil represent false) - # [:float] Represents a floating point value, will be cast to a float using Float(value) - # [:time] Represents a timestamp, will be cast to a Time object - # [:datetime] Represents a timestamp, will be cast to a DateTime object - # [:date] Represents a date, will be cast to a Date object - # - # For structured types, you'll need to pass in the Class objects of - # ActionWebService::Struct and ActiveRecord::Base derivatives. - module SignatureTypes - def canonical_signature(signature) # :nodoc: - return nil if signature.nil? - unless signature.is_a?(Array) - raise(ActionWebServiceError, "Expected signature to be an Array") - end - i = -1 - signature.map{ |spec| canonical_signature_entry(spec, i += 1) } - end - - def canonical_signature_entry(spec, i) # :nodoc: - orig_spec = spec - name = "param#{i}" - if spec.is_a?(Hash) - name, spec = spec.keys.first, spec.values.first - end - type = spec - if spec.is_a?(Array) - ArrayType.new(orig_spec, canonical_signature_entry(spec[0], 0), name) - else - type = canonical_type(type) - if type.is_a?(Symbol) - BaseType.new(orig_spec, type, name) - else - StructuredType.new(orig_spec, type, name) - end - end - end - - def canonical_type(type) # :nodoc: - type_name = symbol_name(type) || class_to_type_name(type) - type = type_name || type - return canonical_type_name(type) if type.is_a?(Symbol) - type - end - - def canonical_type_name(name) # :nodoc: - name = name.to_sym - case name - when :int, :integer, :fixnum, :bignum - :int - when :string - :string - when :base64 - :base64 - when :bool, :boolean - :bool - when :float, :double - :float - when :time, :timestamp - :time - when :datetime - :datetime - when :date - :date - else - raise(TypeError, "#{name} is not a valid base type") - end - end - - def canonical_type_class(type) # :nodoc: - type = canonical_type(type) - type.is_a?(Symbol) ? type_name_to_class(type) : type - end - - def symbol_name(name) # :nodoc: - return name.to_sym if name.is_a?(Symbol) || name.is_a?(String) - nil - end - - def class_to_type_name(klass) # :nodoc: - klass = klass.class unless klass.is_a?(Class) - if derived_from?(Integer, klass) || derived_from?(Fixnum, klass) || derived_from?(Bignum, klass) - :int - elsif klass == String - :string - elsif klass == Base64 - :base64 - elsif klass == TrueClass || klass == FalseClass - :bool - elsif derived_from?(Float, klass) || derived_from?(Precision, klass) || derived_from?(Numeric, klass) - :float - elsif klass == Time - :time - elsif klass == DateTime - :datetime - elsif klass == Date - :date - else - nil - end - end - - def type_name_to_class(name) # :nodoc: - case canonical_type_name(name) - when :int - Integer - when :string - String - when :base64 - Base64 - when :bool - TrueClass - when :float - Float - when :time - Time - when :date - Date - when :datetime - DateTime - else - nil - end - end - - def derived_from?(ancestor, child) # :nodoc: - child.ancestors.include?(ancestor) - end - - module_function :type_name_to_class - module_function :class_to_type_name - module_function :symbol_name - module_function :canonical_type_class - module_function :canonical_type_name - module_function :canonical_type - module_function :canonical_signature_entry - module_function :canonical_signature - module_function :derived_from? - end - - class BaseType # :nodoc: - include SignatureTypes - - attr :spec - attr :type - attr :type_class - attr :name - - def initialize(spec, type, name) - @spec = spec - @type = canonical_type(type) - @type_class = canonical_type_class(@type) - @name = name - end - - def custom? - false - end - - def array? - false - end - - def structured? - false - end - - def human_name(show_name=true) - type_type = array? ? element_type.type.to_s : self.type.to_s - str = array? ? (type_type + '[]') : type_type - show_name ? (str + " " + name.to_s) : str - end - end - - class ArrayType < BaseType # :nodoc: - attr :element_type - - def initialize(spec, element_type, name) - super(spec, Array, name) - @element_type = element_type - end - - def custom? - true - end - - def array? - true - end - end - - class StructuredType < BaseType # :nodoc: - def each_member - if @type_class.respond_to?(:members) - @type_class.members.each do |name, type| - yield name, type - end - elsif @type_class.respond_to?(:columns) - i = -1 - @type_class.columns.each do |column| - yield column.name, canonical_signature_entry(column.klass, i += 1) - end - end - end - - def custom? - true - end - - def structured? - true - end - end - - class Base64 < String # :nodoc: - end -end diff --git a/tracks/vendor/rails/actionwebservice/lib/action_web_service/templates/scaffolds/layout.rhtml b/tracks/vendor/rails/actionwebservice/lib/action_web_service/templates/scaffolds/layout.rhtml deleted file mode 100644 index f083fae0..00000000 --- a/tracks/vendor/rails/actionwebservice/lib/action_web_service/templates/scaffolds/layout.rhtml +++ /dev/null @@ -1,65 +0,0 @@ - - - <%= @scaffold_class.wsdl_service_name %> Web Service - - - - -<%= @content_for_layout %> - - - diff --git a/tracks/vendor/rails/actionwebservice/lib/action_web_service/templates/scaffolds/methods.rhtml b/tracks/vendor/rails/actionwebservice/lib/action_web_service/templates/scaffolds/methods.rhtml deleted file mode 100644 index 60dfe23f..00000000 --- a/tracks/vendor/rails/actionwebservice/lib/action_web_service/templates/scaffolds/methods.rhtml +++ /dev/null @@ -1,6 +0,0 @@ -<% @scaffold_container.services.each do |service| %> - -

    API Methods for <%= service %>

    - <%= service_method_list(service) %> - -<% end %> diff --git a/tracks/vendor/rails/actionwebservice/lib/action_web_service/templates/scaffolds/parameters.rhtml b/tracks/vendor/rails/actionwebservice/lib/action_web_service/templates/scaffolds/parameters.rhtml deleted file mode 100644 index a9d295ae..00000000 --- a/tracks/vendor/rails/actionwebservice/lib/action_web_service/templates/scaffolds/parameters.rhtml +++ /dev/null @@ -1,30 +0,0 @@ -

    Method Invocation Details for <%= @scaffold_service %>#<%= @scaffold_method.public_name %>

    - -<%= form_tag :action => @scaffold_action_name + '_submit' %> -<%= hidden_field_tag "service", @scaffold_service.name %> -<%= hidden_field_tag "method", @scaffold_method.public_name %> - -

    -
    -<%= select_tag 'protocol', options_for_select([['SOAP', 'soap'], ['XML-RPC', 'xmlrpc']], @params['protocol']) %> -

    - -<% if @scaffold_method.expects %> -<% i = 0 %> - -Method Parameters:
    -<% @scaffold_method.expects.each do |type| %> -

    -
    - <%= method_parameter_input_fields(@scaffold_method, type, "method_params[#{i}]") %> -

    - <% i += 1 %> -<% end %> - -<% end %> - -<%= submit_tag "Invoke" %> - -

    -<%= link_to "Back", :action => @scaffold_action_name %> -

    diff --git a/tracks/vendor/rails/actionwebservice/lib/action_web_service/templates/scaffolds/result.rhtml b/tracks/vendor/rails/actionwebservice/lib/action_web_service/templates/scaffolds/result.rhtml deleted file mode 100644 index 5317688f..00000000 --- a/tracks/vendor/rails/actionwebservice/lib/action_web_service/templates/scaffolds/result.rhtml +++ /dev/null @@ -1,30 +0,0 @@ -

    Method Invocation Result for <%= @scaffold_service %>#<%= @scaffold_method.public_name %>

    - -

    -Invocation took <%= '%f' % @method_elapsed %> seconds -

    - -

    -Return Value:
    -

    -<%= h @method_return_value.inspect %>
    -
    -

    - -

    -Request XML:
    -

    -<%= h @method_request_xml %>
    -
    -

    - -

    -Response XML:
    -

    -<%= h @method_response_xml %>
    -
    -

    - -

    -<%= link_to "Back", :action => @scaffold_action_name + '_method_params', :method => @scaffold_method.public_name, :service => @scaffold_service.name %> -

    diff --git a/tracks/vendor/rails/actionwebservice/lib/action_web_service/test_invoke.rb b/tracks/vendor/rails/actionwebservice/lib/action_web_service/test_invoke.rb deleted file mode 100644 index ee150708..00000000 --- a/tracks/vendor/rails/actionwebservice/lib/action_web_service/test_invoke.rb +++ /dev/null @@ -1,109 +0,0 @@ -require 'test/unit' - -module Test # :nodoc: - module Unit # :nodoc: - class TestCase # :nodoc: - private - # invoke the specified API method - def invoke_direct(method_name, *args) - prepare_request('api', 'api', method_name, *args) - @controller.process(@request, @response) - decode_rpc_response - end - alias_method :invoke, :invoke_direct - - # invoke the specified API method on the specified service - def invoke_delegated(service_name, method_name, *args) - prepare_request(service_name.to_s, service_name, method_name, *args) - @controller.process(@request, @response) - decode_rpc_response - end - - # invoke the specified layered API method on the correct service - def invoke_layered(service_name, method_name, *args) - prepare_request('api', service_name, method_name, *args) - @controller.process(@request, @response) - decode_rpc_response - end - - # ---------------------- internal --------------------------- - - def prepare_request(action, service_name, api_method_name, *args) - @request.recycle! - @request.request_parameters['action'] = action - @request.env['REQUEST_METHOD'] = 'POST' - @request.env['HTTP_CONTENT_TYPE'] = 'text/xml' - @request.env['RAW_POST_DATA'] = encode_rpc_call(service_name, api_method_name, *args) - case protocol - when ActionWebService::Protocol::Soap::SoapProtocol - soap_action = "/#{@controller.controller_name}/#{service_name}/#{public_method_name(service_name, api_method_name)}" - @request.env['HTTP_SOAPACTION'] = soap_action - when ActionWebService::Protocol::XmlRpc::XmlRpcProtocol - @request.env.delete('HTTP_SOAPACTION') - end - end - - def encode_rpc_call(service_name, api_method_name, *args) - case @controller.web_service_dispatching_mode - when :direct - api = @controller.class.web_service_api - when :delegated, :layered - api = @controller.web_service_object(service_name.to_sym).class.web_service_api - end - protocol.register_api(api) - method = api.api_methods[api_method_name.to_sym] - protocol.encode_request(public_method_name(service_name, api_method_name), args.dup, method.expects) - end - - def decode_rpc_response - public_method_name, return_value = protocol.decode_response(@response.body) - exception = is_exception?(return_value) - raise exception if exception - return_value - end - - def public_method_name(service_name, api_method_name) - public_name = service_api(service_name).public_api_method_name(api_method_name) - if @controller.web_service_dispatching_mode == :layered && protocol.is_a?(ActionWebService::Protocol::XmlRpc::XmlRpcProtocol) - '%s.%s' % [service_name.to_s, public_name] - else - public_name - end - end - - def service_api(service_name) - case @controller.web_service_dispatching_mode - when :direct - @controller.class.web_service_api - when :delegated, :layered - @controller.web_service_object(service_name.to_sym).class.web_service_api - end - end - - def protocol - if @protocol.nil? - @protocol ||= ActionWebService::Protocol::Soap::SoapProtocol.create(@controller) - else - case @protocol - when :xmlrpc - @protocol = ActionWebService::Protocol::XmlRpc::XmlRpcProtocol.create(@controller) - when :soap - @protocol = ActionWebService::Protocol::Soap::SoapProtocol.create(@controller) - else - @protocol - end - end - end - - def is_exception?(obj) - case protocol - when :soap, ActionWebService::Protocol::Soap::SoapProtocol - (obj.respond_to?(:detail) && obj.detail.respond_to?(:cause) && \ - obj.detail.cause.is_a?(Exception)) ? obj.detail.cause : nil - when :xmlrpc, ActionWebService::Protocol::XmlRpc::XmlRpcProtocol - obj.is_a?(XMLRPC::FaultException) ? obj : nil - end - end - end - end -end diff --git a/tracks/vendor/rails/actionwebservice/lib/action_web_service/version.rb b/tracks/vendor/rails/actionwebservice/lib/action_web_service/version.rb deleted file mode 100644 index 6e27519d..00000000 --- a/tracks/vendor/rails/actionwebservice/lib/action_web_service/version.rb +++ /dev/null @@ -1,9 +0,0 @@ -module ActionWebService - module VERSION - MAJOR = 1 - MINOR = 0 - TINY = 0 - - STRING = [MAJOR, MINOR, TINY].join('.') - end -end diff --git a/tracks/vendor/rails/actionwebservice/setup.rb b/tracks/vendor/rails/actionwebservice/setup.rb deleted file mode 100644 index 9ab880d3..00000000 --- a/tracks/vendor/rails/actionwebservice/setup.rb +++ /dev/null @@ -1,1379 +0,0 @@ -# -# setup.rb -# -# Copyright (c) 2000-2004 Minero Aoki -# -# 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. -# -# Note: Originally licensed under LGPL v2+. Using MIT license for Rails -# with permission of Minero Aoki. - -# - -unless Enumerable.method_defined?(:map) # Ruby 1.4.6 - module Enumerable - alias map collect - end -end - -unless File.respond_to?(:read) # Ruby 1.6 - def File.read(fname) - open(fname) {|f| - return f.read - } - end -end - -def File.binread(fname) - open(fname, 'rb') {|f| - return f.read - } -end - -# for corrupted windows stat(2) -def File.dir?(path) - File.directory?((path[-1,1] == '/') ? path : path + '/') -end - - -class SetupError < StandardError; end - -def setup_rb_error(msg) - raise SetupError, msg -end - -# -# Config -# - -if arg = ARGV.detect {|arg| /\A--rbconfig=/ =~ arg } - ARGV.delete(arg) - require arg.split(/=/, 2)[1] - $".push 'rbconfig.rb' -else - require 'rbconfig' -end - -def multipackage_install? - FileTest.directory?(File.dirname($0) + '/packages') -end - - -class ConfigItem - def initialize(name, template, default, desc) - @name = name.freeze - @template = template - @value = default - @default = default.dup.freeze - @description = desc - end - - attr_reader :name - attr_reader :description - - attr_accessor :default - alias help_default default - - def help_opt - "--#{@name}=#{@template}" - end - - def value - @value - end - - def eval(table) - @value.gsub(%r<\$([^/]+)>) { table[$1] } - end - - def set(val) - @value = check(val) - end - - private - - def check(val) - setup_rb_error "config: --#{name} requires argument" unless val - val - end -end - -class BoolItem < ConfigItem - def config_type - 'bool' - end - - def help_opt - "--#{@name}" - end - - private - - def check(val) - return 'yes' unless val - unless /\A(y(es)?|n(o)?|t(rue)?|f(alse))\z/i =~ val - setup_rb_error "config: --#{@name} accepts only yes/no for argument" - end - (/\Ay(es)?|\At(rue)/i =~ value) ? 'yes' : 'no' - end -end - -class PathItem < ConfigItem - def config_type - 'path' - end - - private - - def check(path) - setup_rb_error "config: --#{@name} requires argument" unless path - path[0,1] == '$' ? path : File.expand_path(path) - end -end - -class ProgramItem < ConfigItem - def config_type - 'program' - end -end - -class SelectItem < ConfigItem - def initialize(name, template, default, desc) - super - @ok = template.split('/') - end - - def config_type - 'select' - end - - private - - def check(val) - unless @ok.include?(val.strip) - setup_rb_error "config: use --#{@name}=#{@template} (#{val})" - end - val.strip - end -end - -class PackageSelectionItem < ConfigItem - def initialize(name, template, default, help_default, desc) - super name, template, default, desc - @help_default = help_default - end - - attr_reader :help_default - - def config_type - 'package' - end - - private - - def check(val) - unless File.dir?("packages/#{val}") - setup_rb_error "config: no such package: #{val}" - end - val - end -end - -class ConfigTable_class - - def initialize(items) - @items = items - @table = {} - items.each do |i| - @table[i.name] = i - end - ALIASES.each do |ali, name| - @table[ali] = @table[name] - end - end - - include Enumerable - - def each(&block) - @items.each(&block) - end - - def key?(name) - @table.key?(name) - end - - def lookup(name) - @table[name] or raise ArgumentError, "no such config item: #{name}" - end - - def add(item) - @items.push item - @table[item.name] = item - end - - def remove(name) - item = lookup(name) - @items.delete_if {|i| i.name == name } - @table.delete_if {|name, i| i.name == name } - item - end - - def new - dup() - end - - def savefile - '.config' - end - - def load - begin - t = dup() - File.foreach(savefile()) do |line| - k, v = *line.split(/=/, 2) - t[k] = v.strip - end - t - rescue Errno::ENOENT - setup_rb_error $!.message + "#{File.basename($0)} config first" - end - end - - def save - @items.each {|i| i.value } - File.open(savefile(), 'w') {|f| - @items.each do |i| - f.printf "%s=%s\n", i.name, i.value if i.value - end - } - end - - def [](key) - lookup(key).eval(self) - end - - def []=(key, val) - lookup(key).set val - end - -end - -c = ::Config::CONFIG - -rubypath = c['bindir'] + '/' + c['ruby_install_name'] - -major = c['MAJOR'].to_i -minor = c['MINOR'].to_i -teeny = c['TEENY'].to_i -version = "#{major}.#{minor}" - -# ruby ver. >= 1.4.4? -newpath_p = ((major >= 2) or - ((major == 1) and - ((minor >= 5) or - ((minor == 4) and (teeny >= 4))))) - -if c['rubylibdir'] - # V < 1.6.3 - _stdruby = c['rubylibdir'] - _siteruby = c['sitedir'] - _siterubyver = c['sitelibdir'] - _siterubyverarch = c['sitearchdir'] -elsif newpath_p - # 1.4.4 <= V <= 1.6.3 - _stdruby = "$prefix/lib/ruby/#{version}" - _siteruby = c['sitedir'] - _siterubyver = "$siteruby/#{version}" - _siterubyverarch = "$siterubyver/#{c['arch']}" -else - # V < 1.4.4 - _stdruby = "$prefix/lib/ruby/#{version}" - _siteruby = "$prefix/lib/ruby/#{version}/site_ruby" - _siterubyver = _siteruby - _siterubyverarch = "$siterubyver/#{c['arch']}" -end -libdir = '-* dummy libdir *-' -stdruby = '-* dummy rubylibdir *-' -siteruby = '-* dummy site_ruby *-' -siterubyver = '-* dummy site_ruby version *-' -parameterize = lambda {|path| - path.sub(/\A#{Regexp.quote(c['prefix'])}/, '$prefix')\ - .sub(/\A#{Regexp.quote(libdir)}/, '$libdir')\ - .sub(/\A#{Regexp.quote(stdruby)}/, '$stdruby')\ - .sub(/\A#{Regexp.quote(siteruby)}/, '$siteruby')\ - .sub(/\A#{Regexp.quote(siterubyver)}/, '$siterubyver') -} -libdir = parameterize.call(c['libdir']) -stdruby = parameterize.call(_stdruby) -siteruby = parameterize.call(_siteruby) -siterubyver = parameterize.call(_siterubyver) -siterubyverarch = parameterize.call(_siterubyverarch) - -if arg = c['configure_args'].split.detect {|arg| /--with-make-prog=/ =~ arg } - makeprog = arg.sub(/'/, '').split(/=/, 2)[1] -else - makeprog = 'make' -end - -common_conf = [ - PathItem.new('prefix', 'path', c['prefix'], - 'path prefix of target environment'), - PathItem.new('bindir', 'path', parameterize.call(c['bindir']), - 'the directory for commands'), - PathItem.new('libdir', 'path', libdir, - 'the directory for libraries'), - PathItem.new('datadir', 'path', parameterize.call(c['datadir']), - 'the directory for shared data'), - PathItem.new('mandir', 'path', parameterize.call(c['mandir']), - 'the directory for man pages'), - PathItem.new('sysconfdir', 'path', parameterize.call(c['sysconfdir']), - 'the directory for man pages'), - PathItem.new('stdruby', 'path', stdruby, - 'the directory for standard ruby libraries'), - PathItem.new('siteruby', 'path', siteruby, - 'the directory for version-independent aux ruby libraries'), - PathItem.new('siterubyver', 'path', siterubyver, - 'the directory for aux ruby libraries'), - PathItem.new('siterubyverarch', 'path', siterubyverarch, - 'the directory for aux ruby binaries'), - PathItem.new('rbdir', 'path', '$siterubyver', - 'the directory for ruby scripts'), - PathItem.new('sodir', 'path', '$siterubyverarch', - 'the directory for ruby extentions'), - PathItem.new('rubypath', 'path', rubypath, - 'the path to set to #! line'), - ProgramItem.new('rubyprog', 'name', rubypath, - 'the ruby program using for installation'), - ProgramItem.new('makeprog', 'name', makeprog, - 'the make program to compile ruby extentions'), - SelectItem.new('shebang', 'all/ruby/never', 'ruby', - 'shebang line (#!) editing mode'), - BoolItem.new('without-ext', 'yes/no', 'no', - 'does not compile/install ruby extentions') -] -class ConfigTable_class # open again - ALIASES = { - 'std-ruby' => 'stdruby', - 'site-ruby-common' => 'siteruby', # For backward compatibility - 'site-ruby' => 'siterubyver', # For backward compatibility - 'bin-dir' => 'bindir', - 'bin-dir' => 'bindir', - 'rb-dir' => 'rbdir', - 'so-dir' => 'sodir', - 'data-dir' => 'datadir', - 'ruby-path' => 'rubypath', - 'ruby-prog' => 'rubyprog', - 'ruby' => 'rubyprog', - 'make-prog' => 'makeprog', - 'make' => 'makeprog' - } -end -multipackage_conf = [ - PackageSelectionItem.new('with', 'name,name...', '', 'ALL', - 'package names that you want to install'), - PackageSelectionItem.new('without', 'name,name...', '', 'NONE', - 'package names that you do not want to install') -] -if multipackage_install? - ConfigTable = ConfigTable_class.new(common_conf + multipackage_conf) -else - ConfigTable = ConfigTable_class.new(common_conf) -end - - -module MetaConfigAPI - - def eval_file_ifexist(fname) - instance_eval File.read(fname), fname, 1 if File.file?(fname) - end - - def config_names - ConfigTable.map {|i| i.name } - end - - def config?(name) - ConfigTable.key?(name) - end - - def bool_config?(name) - ConfigTable.lookup(name).config_type == 'bool' - end - - def path_config?(name) - ConfigTable.lookup(name).config_type == 'path' - end - - def value_config?(name) - case ConfigTable.lookup(name).config_type - when 'bool', 'path' - true - else - false - end - end - - def add_config(item) - ConfigTable.add item - end - - def add_bool_config(name, default, desc) - ConfigTable.add BoolItem.new(name, 'yes/no', default ? 'yes' : 'no', desc) - end - - def add_path_config(name, default, desc) - ConfigTable.add PathItem.new(name, 'path', default, desc) - end - - def set_config_default(name, default) - ConfigTable.lookup(name).default = default - end - - def remove_config(name) - ConfigTable.remove(name) - end - -end - - -# -# File Operations -# - -module FileOperations - - def mkdir_p(dirname, prefix = nil) - dirname = prefix + File.expand_path(dirname) if prefix - $stderr.puts "mkdir -p #{dirname}" if verbose? - return if no_harm? - - # does not check '/'... it's too abnormal case - dirs = File.expand_path(dirname).split(%r<(?=/)>) - if /\A[a-z]:\z/i =~ dirs[0] - disk = dirs.shift - dirs[0] = disk + dirs[0] - end - dirs.each_index do |idx| - path = dirs[0..idx].join('') - Dir.mkdir path unless File.dir?(path) - end - end - - def rm_f(fname) - $stderr.puts "rm -f #{fname}" if verbose? - return if no_harm? - - if File.exist?(fname) or File.symlink?(fname) - File.chmod 0777, fname - File.unlink fname - end - end - - def rm_rf(dn) - $stderr.puts "rm -rf #{dn}" if verbose? - return if no_harm? - - Dir.chdir dn - Dir.foreach('.') do |fn| - next if fn == '.' - next if fn == '..' - if File.dir?(fn) - verbose_off { - rm_rf fn - } - else - verbose_off { - rm_f fn - } - end - end - Dir.chdir '..' - Dir.rmdir dn - end - - def move_file(src, dest) - File.unlink dest if File.exist?(dest) - begin - File.rename src, dest - rescue - File.open(dest, 'wb') {|f| f.write File.binread(src) } - File.chmod File.stat(src).mode, dest - File.unlink src - end - end - - def install(from, dest, mode, prefix = nil) - $stderr.puts "install #{from} #{dest}" if verbose? - return if no_harm? - - realdest = prefix ? prefix + File.expand_path(dest) : dest - realdest = File.join(realdest, File.basename(from)) if File.dir?(realdest) - str = File.binread(from) - if diff?(str, realdest) - verbose_off { - rm_f realdest if File.exist?(realdest) - } - File.open(realdest, 'wb') {|f| - f.write str - } - File.chmod mode, realdest - - File.open("#{objdir_root()}/InstalledFiles", 'a') {|f| - if prefix - f.puts realdest.sub(prefix, '') - else - f.puts realdest - end - } - end - end - - def diff?(new_content, path) - return true unless File.exist?(path) - new_content != File.binread(path) - end - - def command(str) - $stderr.puts str if verbose? - system str or raise RuntimeError, "'system #{str}' failed" - end - - def ruby(str) - command config('rubyprog') + ' ' + str - end - - def make(task = '') - command config('makeprog') + ' ' + task - end - - def extdir?(dir) - File.exist?(dir + '/MANIFEST') - end - - def all_files_in(dirname) - Dir.open(dirname) {|d| - return d.select {|ent| File.file?("#{dirname}/#{ent}") } - } - end - - REJECT_DIRS = %w( - CVS SCCS RCS CVS.adm .svn - ) - - def all_dirs_in(dirname) - Dir.open(dirname) {|d| - return d.select {|n| File.dir?("#{dirname}/#{n}") } - %w(. ..) - REJECT_DIRS - } - end - -end - - -# -# Main Installer -# - -module HookUtils - - def run_hook(name) - try_run_hook "#{curr_srcdir()}/#{name}" or - try_run_hook "#{curr_srcdir()}/#{name}.rb" - end - - def try_run_hook(fname) - return false unless File.file?(fname) - begin - instance_eval File.read(fname), fname, 1 - rescue - setup_rb_error "hook #{fname} failed:\n" + $!.message - end - true - end - -end - - -module HookScriptAPI - - def get_config(key) - @config[key] - end - - alias config get_config - - def set_config(key, val) - @config[key] = val - end - - # - # srcdir/objdir (works only in the package directory) - # - - #abstract srcdir_root - #abstract objdir_root - #abstract relpath - - def curr_srcdir - "#{srcdir_root()}/#{relpath()}" - end - - def curr_objdir - "#{objdir_root()}/#{relpath()}" - end - - def srcfile(path) - "#{curr_srcdir()}/#{path}" - end - - def srcexist?(path) - File.exist?(srcfile(path)) - end - - def srcdirectory?(path) - File.dir?(srcfile(path)) - end - - def srcfile?(path) - File.file? srcfile(path) - end - - def srcentries(path = '.') - Dir.open("#{curr_srcdir()}/#{path}") {|d| - return d.to_a - %w(. ..) - } - end - - def srcfiles(path = '.') - srcentries(path).select {|fname| - File.file?(File.join(curr_srcdir(), path, fname)) - } - end - - def srcdirectories(path = '.') - srcentries(path).select {|fname| - File.dir?(File.join(curr_srcdir(), path, fname)) - } - end - -end - - -class ToplevelInstaller - - Version = '3.3.1' - Copyright = 'Copyright (c) 2000-2004 Minero Aoki' - - TASKS = [ - [ 'all', 'do config, setup, then install' ], - [ 'config', 'saves your configurations' ], - [ 'show', 'shows current configuration' ], - [ 'setup', 'compiles ruby extentions and others' ], - [ 'install', 'installs files' ], - [ 'clean', "does `make clean' for each extention" ], - [ 'distclean',"does `make distclean' for each extention" ] - ] - - def ToplevelInstaller.invoke - instance().invoke - end - - @singleton = nil - - def ToplevelInstaller.instance - @singleton ||= new(File.dirname($0)) - @singleton - end - - include MetaConfigAPI - - def initialize(ardir_root) - @config = nil - @options = { 'verbose' => true } - @ardir = File.expand_path(ardir_root) - end - - def inspect - "#<#{self.class} #{__id__()}>" - end - - def invoke - run_metaconfigs - case task = parsearg_global() - when nil, 'all' - @config = load_config('config') - parsearg_config - init_installers - exec_config - exec_setup - exec_install - else - @config = load_config(task) - __send__ "parsearg_#{task}" - init_installers - __send__ "exec_#{task}" - end - end - - def run_metaconfigs - eval_file_ifexist "#{@ardir}/metaconfig" - end - - def load_config(task) - case task - when 'config' - ConfigTable.new - when 'clean', 'distclean' - if File.exist?(ConfigTable.savefile) - then ConfigTable.load - else ConfigTable.new - end - else - ConfigTable.load - end - end - - def init_installers - @installer = Installer.new(@config, @options, @ardir, File.expand_path('.')) - end - - # - # Hook Script API bases - # - - def srcdir_root - @ardir - end - - def objdir_root - '.' - end - - def relpath - '.' - end - - # - # Option Parsing - # - - def parsearg_global - valid_task = /\A(?:#{TASKS.map {|task,desc| task }.join '|'})\z/ - - while arg = ARGV.shift - case arg - when /\A\w+\z/ - setup_rb_error "invalid task: #{arg}" unless valid_task =~ arg - return arg - - when '-q', '--quiet' - @options['verbose'] = false - - when '--verbose' - @options['verbose'] = true - - when '-h', '--help' - print_usage $stdout - exit 0 - - when '-v', '--version' - puts "#{File.basename($0)} version #{Version}" - exit 0 - - when '--copyright' - puts Copyright - exit 0 - - else - setup_rb_error "unknown global option '#{arg}'" - end - end - - nil - end - - - def parsearg_no_options - unless ARGV.empty? - setup_rb_error "#{task}: unknown options: #{ARGV.join ' '}" - end - end - - alias parsearg_show parsearg_no_options - alias parsearg_setup parsearg_no_options - alias parsearg_clean parsearg_no_options - alias parsearg_distclean parsearg_no_options - - def parsearg_config - re = /\A--(#{ConfigTable.map {|i| i.name }.join('|')})(?:=(.*))?\z/ - @options['config-opt'] = [] - - while i = ARGV.shift - if /\A--?\z/ =~ i - @options['config-opt'] = ARGV.dup - break - end - m = re.match(i) or setup_rb_error "config: unknown option #{i}" - name, value = *m.to_a[1,2] - @config[name] = value - end - end - - def parsearg_install - @options['no-harm'] = false - @options['install-prefix'] = '' - while a = ARGV.shift - case a - when /\A--no-harm\z/ - @options['no-harm'] = true - when /\A--prefix=(.*)\z/ - path = $1 - path = File.expand_path(path) unless path[0,1] == '/' - @options['install-prefix'] = path - else - setup_rb_error "install: unknown option #{a}" - end - end - end - - def print_usage(out) - out.puts 'Typical Installation Procedure:' - out.puts " $ ruby #{File.basename $0} config" - out.puts " $ ruby #{File.basename $0} setup" - out.puts " # ruby #{File.basename $0} install (may require root privilege)" - out.puts - out.puts 'Detailed Usage:' - out.puts " ruby #{File.basename $0} " - out.puts " ruby #{File.basename $0} [] []" - - fmt = " %-24s %s\n" - out.puts - out.puts 'Global options:' - out.printf fmt, '-q,--quiet', 'suppress message outputs' - out.printf fmt, ' --verbose', 'output messages verbosely' - out.printf fmt, '-h,--help', 'print this message' - out.printf fmt, '-v,--version', 'print version and quit' - out.printf fmt, ' --copyright', 'print copyright and quit' - out.puts - out.puts 'Tasks:' - TASKS.each do |name, desc| - out.printf fmt, name, desc - end - - fmt = " %-24s %s [%s]\n" - out.puts - out.puts 'Options for CONFIG or ALL:' - ConfigTable.each do |item| - out.printf fmt, item.help_opt, item.description, item.help_default - end - out.printf fmt, '--rbconfig=path', 'rbconfig.rb to load',"running ruby's" - out.puts - out.puts 'Options for INSTALL:' - out.printf fmt, '--no-harm', 'only display what to do if given', 'off' - out.printf fmt, '--prefix=path', 'install path prefix', '$prefix' - out.puts - end - - # - # Task Handlers - # - - def exec_config - @installer.exec_config - @config.save # must be final - end - - def exec_setup - @installer.exec_setup - end - - def exec_install - @installer.exec_install - end - - def exec_show - ConfigTable.each do |i| - printf "%-20s %s\n", i.name, i.value - end - end - - def exec_clean - @installer.exec_clean - end - - def exec_distclean - @installer.exec_distclean - end - -end - - -class ToplevelInstallerMulti < ToplevelInstaller - - include HookUtils - include HookScriptAPI - include FileOperations - - def initialize(ardir) - super - @packages = all_dirs_in("#{@ardir}/packages") - raise 'no package exists' if @packages.empty? - end - - def run_metaconfigs - eval_file_ifexist "#{@ardir}/metaconfig" - @packages.each do |name| - eval_file_ifexist "#{@ardir}/packages/#{name}/metaconfig" - end - end - - def init_installers - @installers = {} - @packages.each do |pack| - @installers[pack] = Installer.new(@config, @options, - "#{@ardir}/packages/#{pack}", - "packages/#{pack}") - end - - with = extract_selection(config('with')) - without = extract_selection(config('without')) - @selected = @installers.keys.select {|name| - (with.empty? or with.include?(name)) \ - and not without.include?(name) - } - end - - def extract_selection(list) - a = list.split(/,/) - a.each do |name| - setup_rb_error "no such package: #{name}" unless @installers.key?(name) - end - a - end - - def print_usage(f) - super - f.puts 'Inluded packages:' - f.puts ' ' + @packages.sort.join(' ') - f.puts - end - - # - # multi-package metaconfig API - # - - attr_reader :packages - - def declare_packages(list) - raise 'package list is empty' if list.empty? - list.each do |name| - raise "directory packages/#{name} does not exist"\ - unless File.dir?("#{@ardir}/packages/#{name}") - end - @packages = list - end - - # - # Task Handlers - # - - def exec_config - run_hook 'pre-config' - each_selected_installers {|inst| inst.exec_config } - run_hook 'post-config' - @config.save # must be final - end - - def exec_setup - run_hook 'pre-setup' - each_selected_installers {|inst| inst.exec_setup } - run_hook 'post-setup' - end - - def exec_install - run_hook 'pre-install' - each_selected_installers {|inst| inst.exec_install } - run_hook 'post-install' - end - - def exec_clean - rm_f ConfigTable.savefile - run_hook 'pre-clean' - each_selected_installers {|inst| inst.exec_clean } - run_hook 'post-clean' - end - - def exec_distclean - rm_f ConfigTable.savefile - run_hook 'pre-distclean' - each_selected_installers {|inst| inst.exec_distclean } - run_hook 'post-distclean' - end - - # - # lib - # - - def each_selected_installers - Dir.mkdir 'packages' unless File.dir?('packages') - @selected.each do |pack| - $stderr.puts "Processing the package `#{pack}' ..." if @options['verbose'] - Dir.mkdir "packages/#{pack}" unless File.dir?("packages/#{pack}") - Dir.chdir "packages/#{pack}" - yield @installers[pack] - Dir.chdir '../..' - end - end - - def verbose? - @options['verbose'] - end - - def no_harm? - @options['no-harm'] - end - -end - - -class Installer - - FILETYPES = %w( bin lib ext data ) - - include HookScriptAPI - include HookUtils - include FileOperations - - def initialize(config, opt, srcroot, objroot) - @config = config - @options = opt - @srcdir = File.expand_path(srcroot) - @objdir = File.expand_path(objroot) - @currdir = '.' - end - - def inspect - "#<#{self.class} #{File.basename(@srcdir)}>" - end - - # - # Hook Script API base methods - # - - def srcdir_root - @srcdir - end - - def objdir_root - @objdir - end - - def relpath - @currdir - end - - # - # configs/options - # - - def no_harm? - @options['no-harm'] - end - - def verbose? - @options['verbose'] - end - - def verbose_off - begin - save, @options['verbose'] = @options['verbose'], false - yield - ensure - @options['verbose'] = save - end - end - - # - # TASK config - # - - def exec_config - exec_task_traverse 'config' - end - - def config_dir_bin(rel) - end - - def config_dir_lib(rel) - end - - def config_dir_ext(rel) - extconf if extdir?(curr_srcdir()) - end - - def extconf - opt = @options['config-opt'].join(' ') - command "#{config('rubyprog')} #{curr_srcdir()}/extconf.rb #{opt}" - end - - def config_dir_data(rel) - end - - # - # TASK setup - # - - def exec_setup - exec_task_traverse 'setup' - end - - def setup_dir_bin(rel) - all_files_in(curr_srcdir()).each do |fname| - adjust_shebang "#{curr_srcdir()}/#{fname}" - end - end - - def adjust_shebang(path) - return if no_harm? - tmpfile = File.basename(path) + '.tmp' - begin - File.open(path, 'rb') {|r| - first = r.gets - return unless File.basename(config('rubypath')) == 'ruby' - return unless File.basename(first.sub(/\A\#!/, '').split[0]) == 'ruby' - $stderr.puts "adjusting shebang: #{File.basename(path)}" if verbose? - File.open(tmpfile, 'wb') {|w| - w.print first.sub(/\A\#!\s*\S+/, '#! ' + config('rubypath')) - w.write r.read - } - move_file tmpfile, File.basename(path) - } - ensure - File.unlink tmpfile if File.exist?(tmpfile) - end - end - - def setup_dir_lib(rel) - end - - def setup_dir_ext(rel) - make if extdir?(curr_srcdir()) - end - - def setup_dir_data(rel) - end - - # - # TASK install - # - - def exec_install - rm_f 'InstalledFiles' - exec_task_traverse 'install' - end - - def install_dir_bin(rel) - install_files collect_filenames_auto(), "#{config('bindir')}/#{rel}", 0755 - end - - def install_dir_lib(rel) - install_files ruby_scripts(), "#{config('rbdir')}/#{rel}", 0644 - end - - def install_dir_ext(rel) - return unless extdir?(curr_srcdir()) - install_files ruby_extentions('.'), - "#{config('sodir')}/#{File.dirname(rel)}", - 0555 - end - - def install_dir_data(rel) - install_files collect_filenames_auto(), "#{config('datadir')}/#{rel}", 0644 - end - - def install_files(list, dest, mode) - mkdir_p dest, @options['install-prefix'] - list.each do |fname| - install fname, dest, mode, @options['install-prefix'] - end - end - - def ruby_scripts - collect_filenames_auto().select {|n| /\.rb\z/ =~ n } - end - - # picked up many entries from cvs-1.11.1/src/ignore.c - reject_patterns = %w( - core RCSLOG tags TAGS .make.state - .nse_depinfo #* .#* cvslog.* ,* .del-* *.olb - *~ *.old *.bak *.BAK *.orig *.rej _$* *$ - - *.org *.in .* - ) - mapping = { - '.' => '\.', - '$' => '\$', - '#' => '\#', - '*' => '.*' - } - REJECT_PATTERNS = Regexp.new('\A(?:' + - reject_patterns.map {|pat| - pat.gsub(/[\.\$\#\*]/) {|ch| mapping[ch] } - }.join('|') + - ')\z') - - def collect_filenames_auto - mapdir((existfiles() - hookfiles()).reject {|fname| - REJECT_PATTERNS =~ fname - }) - end - - def existfiles - all_files_in(curr_srcdir()) | all_files_in('.') - end - - def hookfiles - %w( pre-%s post-%s pre-%s.rb post-%s.rb ).map {|fmt| - %w( config setup install clean ).map {|t| sprintf(fmt, t) } - }.flatten - end - - def mapdir(filelist) - filelist.map {|fname| - if File.exist?(fname) # objdir - fname - else # srcdir - File.join(curr_srcdir(), fname) - end - } - end - - def ruby_extentions(dir) - Dir.open(dir) {|d| - ents = d.select {|fname| /\.#{::Config::CONFIG['DLEXT']}\z/ =~ fname } - if ents.empty? - setup_rb_error "no ruby extention exists: 'ruby #{$0} setup' first" - end - return ents - } - end - - # - # TASK clean - # - - def exec_clean - exec_task_traverse 'clean' - rm_f ConfigTable.savefile - rm_f 'InstalledFiles' - end - - def clean_dir_bin(rel) - end - - def clean_dir_lib(rel) - end - - def clean_dir_ext(rel) - return unless extdir?(curr_srcdir()) - make 'clean' if File.file?('Makefile') - end - - def clean_dir_data(rel) - end - - # - # TASK distclean - # - - def exec_distclean - exec_task_traverse 'distclean' - rm_f ConfigTable.savefile - rm_f 'InstalledFiles' - end - - def distclean_dir_bin(rel) - end - - def distclean_dir_lib(rel) - end - - def distclean_dir_ext(rel) - return unless extdir?(curr_srcdir()) - make 'distclean' if File.file?('Makefile') - end - - # - # lib - # - - def exec_task_traverse(task) - run_hook "pre-#{task}" - FILETYPES.each do |type| - if config('without-ext') == 'yes' and type == 'ext' - $stderr.puts 'skipping ext/* by user option' if verbose? - next - end - traverse task, type, "#{task}_dir_#{type}" - end - run_hook "post-#{task}" - end - - def traverse(task, rel, mid) - dive_into(rel) { - run_hook "pre-#{task}" - __send__ mid, rel.sub(%r[\A.*?(?:/|\z)], '') - all_dirs_in(curr_srcdir()).each do |d| - traverse task, "#{rel}/#{d}", mid - end - run_hook "post-#{task}" - } - end - - def dive_into(rel) - return unless File.dir?("#{@srcdir}/#{rel}") - - dir = File.basename(rel) - Dir.mkdir dir unless File.dir?(dir) - prevdir = Dir.pwd - Dir.chdir dir - $stderr.puts '---> ' + rel if verbose? - @currdir = rel - yield - Dir.chdir prevdir - $stderr.puts '<--- ' + rel if verbose? - @currdir = File.dirname(rel) - end - -end - - -if $0 == __FILE__ - begin - if multipackage_install? - ToplevelInstallerMulti.invoke - else - ToplevelInstaller.invoke - end - rescue SetupError - raise if $DEBUG - $stderr.puts $!.message - $stderr.puts "Try 'ruby #{$0} --help' for detailed usage." - exit 1 - end -end diff --git a/tracks/vendor/rails/actionwebservice/test/abstract_client.rb b/tracks/vendor/rails/actionwebservice/test/abstract_client.rb deleted file mode 100644 index 0efa1d7e..00000000 --- a/tracks/vendor/rails/actionwebservice/test/abstract_client.rb +++ /dev/null @@ -1,128 +0,0 @@ -require File.dirname(__FILE__) + '/abstract_unit' -require 'webrick' -require 'webrick/log' -require 'singleton' - -module ClientTest - class Person < ActionWebService::Struct - member :firstnames, [:string] - member :lastname, :string - - def ==(other) - firstnames == other.firstnames && lastname == other.lastname - end - end - - class API < ActionWebService::API::Base - api_method :void - api_method :normal, :expects => [:int, :int], :returns => [:int] - api_method :array_return, :returns => [[Person]] - api_method :struct_pass, :expects => [[Person]], :returns => [:bool] - api_method :client_container, :returns => [:int] - api_method :named_parameters, :expects => [{:key=>:string}, {:id=>:int}] - api_method :thrower - end - - class NullLogOut - def <<(*args); end - end - - class Container < ActionController::Base - web_service_api API - - attr_accessor :value_void - attr_accessor :value_normal - attr_accessor :value_array_return - attr_accessor :value_struct_pass - attr_accessor :value_named_parameters - - def initialize - @session = @assigns = {} - @value_void = nil - @value_normal = nil - @value_array_return = nil - @value_struct_pass = nil - @value_named_parameters = nil - end - - def void - @value_void = @method_params - end - - def normal - @value_normal = @method_params - 5 - end - - def array_return - person = Person.new - person.firstnames = ["one", "two"] - person.lastname = "last" - @value_array_return = [person] - end - - def struct_pass - @value_struct_pass = @method_params - true - end - - def client_container - 50 - end - - def named_parameters - @value_named_parameters = @method_params - end - - def thrower - raise "Hi" - end - end - - class AbstractClientLet < WEBrick::HTTPServlet::AbstractServlet - def initialize(controller) - @controller = controller - end - - def get_instance(*args) - self - end - - def require_path_info? - false - end - - def do_GET(req, res) - raise WEBrick::HTTPStatus::MethodNotAllowed, "GET request not allowed." - end - - def do_POST(req, res) - raise NotImplementedError - end - end - - class AbstractServer - include ClientTest - include Singleton - attr :container - def initialize - @container = Container.new - @clientlet = create_clientlet(@container) - log = WEBrick::BasicLog.new(NullLogOut.new) - @server = WEBrick::HTTPServer.new(:Port => server_port, :Logger => log, :AccessLog => log) - @server.mount('/', @clientlet) - @thr = Thread.new { @server.start } - until @server.status == :Running; end - at_exit { @server.stop; @thr.join } - end - - protected - def create_clientlet - raise NotImplementedError - end - - def server_port - raise NotImplementedError - end - end -end diff --git a/tracks/vendor/rails/actionwebservice/test/abstract_dispatcher.rb b/tracks/vendor/rails/actionwebservice/test/abstract_dispatcher.rb deleted file mode 100644 index b857e4a9..00000000 --- a/tracks/vendor/rails/actionwebservice/test/abstract_dispatcher.rb +++ /dev/null @@ -1,500 +0,0 @@ -require File.dirname(__FILE__) + '/abstract_unit' -require 'stringio' - -class ActionController::Base; def rescue_action(e) raise e end; end - -module DispatcherTest - Utf8String = "One World Caf\303\251" - WsdlNamespace = 'http://rubyonrails.com/some/namespace' - - class Node < ActiveRecord::Base - def initialize(*args) - super(*args) - @new_record = false - end - - class << self - def name - "DispatcherTest::Node" - end - - def columns(*args) - [ - ActiveRecord::ConnectionAdapters::Column.new('id', 0, 'int'), - ActiveRecord::ConnectionAdapters::Column.new('name', nil, 'string'), - ActiveRecord::ConnectionAdapters::Column.new('description', nil, 'string'), - ] - end - - def connection - self - end - end - end - - class Person < ActionWebService::Struct - member :id, :int - member :name, :string - - def ==(other) - self.id == other.id && self.name == other.name - end - end - - class API < ActionWebService::API::Base - api_method :add, :expects => [:int, :int], :returns => [:int] - api_method :interceptee - api_method :struct_return, :returns => [[Node]] - api_method :void - end - - class DirectAPI < ActionWebService::API::Base - api_method :add, :expects => [{:a=>:int}, {:b=>:int}], :returns => [:int] - api_method :add2, :expects => [{:a=>:int}, {:b=>:int}], :returns => [:int] - api_method :before_filtered - api_method :after_filtered, :returns => [[:int]] - api_method :struct_return, :returns => [[Node]] - api_method :struct_pass, :expects => [{:person => Person}] - api_method :base_struct_return, :returns => [[Person]] - api_method :hash_struct_return, :returns => [[Person]] - api_method :thrower - api_method :void - api_method :test_utf8, :returns => [:string] - api_method :hex, :expects => [:base64], :returns => [:string] - api_method :unhex, :expects => [:string], :returns => [:base64] - api_method :time, :expects => [:time], :returns => [:time] - end - - class VirtualAPI < ActionWebService::API::Base - default_api_method :fallback - end - - class Service < ActionWebService::Base - web_service_api API - - before_invocation :do_intercept, :only => [:interceptee] - - attr :added - attr :intercepted - attr :void_called - - def initialize - @void_called = false - end - - def add(a, b) - @added = a + b - end - - def interceptee - @intercepted = false - end - - def struct_return - n1 = Node.new('id' => 1, 'name' => 'node1', 'description' => 'Node 1') - n2 = Node.new('id' => 2, 'name' => 'node2', 'description' => 'Node 2') - [n1, n2] - end - - def void(*args) - @void_called = args - end - - def do_intercept(name, args) - [false, "permission denied"] - end - end - - class MTAPI < ActionWebService::API::Base - inflect_names false - api_method :getCategories, :returns => [[:string]] - api_method :bool, :returns => [:bool] - api_method :alwaysFail - end - - class BloggerAPI < ActionWebService::API::Base - inflect_names false - api_method :getCategories, :returns => [[:string]] - api_method :str, :expects => [:int], :returns => [:string] - api_method :alwaysFail - end - - class MTService < ActionWebService::Base - web_service_api MTAPI - - def getCategories - ["mtCat1", "mtCat2"] - end - - def bool - 'y' - end - - def alwaysFail - raise "MT AlwaysFail" - end - end - - class BloggerService < ActionWebService::Base - web_service_api BloggerAPI - - def getCategories - ["bloggerCat1", "bloggerCat2"] - end - - def str(int) - unless int.is_a?(Integer) - raise "Not an integer!" - end - 500 + int - end - - def alwaysFail - raise "Blogger AlwaysFail" - end - end - - class AbstractController < ActionController::Base - def generate_wsdl - @request ||= ::ActionController::TestRequest.new - to_wsdl - end - end - - class DelegatedController < AbstractController - web_service_dispatching_mode :delegated - wsdl_namespace WsdlNamespace - - web_service(:test_service) { @service ||= Service.new; @service } - end - - class LayeredController < AbstractController - web_service_dispatching_mode :layered - wsdl_namespace WsdlNamespace - - web_service(:mt) { @mt_service ||= MTService.new; @mt_service } - web_service(:blogger) { @blogger_service ||= BloggerService.new; @blogger_service } - end - - class DirectController < AbstractController - web_service_api DirectAPI - web_service_dispatching_mode :direct - wsdl_namespace WsdlNamespace - - before_invocation :alwaysfail, :only => [:before_filtered] - after_invocation :alwaysok, :only => [:after_filtered] - - attr :added - attr :added2 - attr :before_filter_called - attr :before_filter_target_called - attr :after_filter_called - attr :after_filter_target_called - attr :void_called - attr :struct_pass_value - - def initialize - @before_filter_called = false - @before_filter_target_called = false - @after_filter_called = false - @after_filter_target_called = false - @void_called = false - @struct_pass_value = false - end - - def add - @added = @params['a'] + @params['b'] - end - - def add2(a, b) - @added2 = a + b - end - - def before_filtered - @before_filter_target_called = true - end - - def after_filtered - @after_filter_target_called = true - [5, 6, 7] - end - - def thrower - raise "Hi, I'm an exception" - end - - def struct_return - n1 = Node.new('id' => 1, 'name' => 'node1', 'description' => 'Node 1') - n2 = Node.new('id' => 2, 'name' => 'node2', 'description' => 'Node 2') - [n1, n2] - end - - def struct_pass(person) - @struct_pass_value = person - end - - def base_struct_return - p1 = Person.new('id' => 1, 'name' => 'person1') - p2 = Person.new('id' => 2, 'name' => 'person2') - [p1, p2] - end - - def hash_struct_return - p1 = { :id => '1', 'name' => 'test' } - p2 = { 'id' => '2', :name => 'person2' } - [p1, p2] - end - - def void - @void_called = @method_params - end - - def test_utf8 - Utf8String - end - - def hex(s) - return s.unpack("H*")[0] - end - - def unhex(s) - return [s].pack("H*") - end - - def time(t) - t - end - - protected - def alwaysfail(method_name, params) - @before_filter_called = true - false - end - - def alwaysok(method_name, params, return_value) - @after_filter_called = true - end - end - - class VirtualController < AbstractController - web_service_api VirtualAPI - wsdl_namespace WsdlNamespace - - def fallback - "fallback!" - end - end -end - -module DispatcherCommonTests - def test_direct_dispatching - assert_equal(70, do_method_call(@direct_controller, 'Add', 20, 50)) - assert_equal(70, @direct_controller.added) - assert_equal(50, do_method_call(@direct_controller, 'Add2', 25, 25)) - assert_equal(50, @direct_controller.added2) - assert(@direct_controller.void_called == false) - assert(do_method_call(@direct_controller, 'Void', 3, 4, 5).nil?) - assert(@direct_controller.void_called == []) - result = do_method_call(@direct_controller, 'BaseStructReturn') - assert(result[0].is_a?(DispatcherTest::Person)) - assert(result[1].is_a?(DispatcherTest::Person)) - assert_equal("cafe", do_method_call(@direct_controller, 'Hex', "\xca\xfe")) - assert_equal("\xca\xfe", do_method_call(@direct_controller, 'Unhex', "cafe")) - time = Time.gm(1998, "Feb", 02, 15, 12, 01) - assert_equal(time, do_method_call(@direct_controller, 'Time', time)) - end - - def test_direct_entrypoint - assert(@direct_controller.respond_to?(:api)) - end - - def test_virtual_dispatching - assert_equal("fallback!", do_method_call(@virtual_controller, 'VirtualOne')) - assert_equal("fallback!", do_method_call(@virtual_controller, 'VirtualTwo')) - end - - def test_direct_filtering - assert_equal(false, @direct_controller.before_filter_called) - assert_equal(false, @direct_controller.before_filter_target_called) - do_method_call(@direct_controller, 'BeforeFiltered') - assert_equal(true, @direct_controller.before_filter_called) - assert_equal(false, @direct_controller.before_filter_target_called) - assert_equal(false, @direct_controller.after_filter_called) - assert_equal(false, @direct_controller.after_filter_target_called) - assert_equal([5, 6, 7], do_method_call(@direct_controller, 'AfterFiltered')) - assert_equal(true, @direct_controller.after_filter_called) - assert_equal(true, @direct_controller.after_filter_target_called) - end - - def test_delegated_dispatching - assert_equal(130, do_method_call(@delegated_controller, 'Add', 50, 80)) - service = @delegated_controller.web_service_object(:test_service) - assert_equal(130, service.added) - @delegated_controller.web_service_exception_reporting = true - assert(service.intercepted.nil?) - result = do_method_call(@delegated_controller, 'Interceptee') - assert(service.intercepted.nil?) - assert(is_exception?(result)) - assert_match(/permission denied/, exception_message(result)) - result = do_method_call(@delegated_controller, 'NonExistentMethod') - assert(is_exception?(result)) - assert_match(/NonExistentMethod/, exception_message(result)) - assert(service.void_called == false) - assert(do_method_call(@delegated_controller, 'Void', 3, 4, 5).nil?) - assert(service.void_called == []) - end - - def test_garbage_request - [@direct_controller, @delegated_controller].each do |controller| - controller.class.web_service_exception_reporting = true - send_garbage_request = lambda do - service_name = service_name(controller) - request = protocol.encode_action_pack_request(service_name, 'broken, method, name!', 'broken request body', :request_class => ActionController::TestRequest) - response = ActionController::TestResponse.new - controller.process(request, response) - # puts response.body - assert(response.headers['Status'] =~ /^500/) - end - send_garbage_request.call - controller.class.web_service_exception_reporting = false - send_garbage_request.call - end - end - - def test_exception_marshaling - @direct_controller.web_service_exception_reporting = true - result = do_method_call(@direct_controller, 'Thrower') - assert(is_exception?(result)) - assert_equal("Hi, I'm an exception", exception_message(result)) - @direct_controller.web_service_exception_reporting = false - result = do_method_call(@direct_controller, 'Thrower') - assert(exception_message(result) != "Hi, I'm an exception") - end - - def test_ar_struct_return - [@direct_controller, @delegated_controller].each do |controller| - result = do_method_call(controller, 'StructReturn') - assert(result[0].is_a?(DispatcherTest::Node)) - assert(result[1].is_a?(DispatcherTest::Node)) - assert_equal('node1', result[0].name) - assert_equal('node2', result[1].name) - end - end - - def test_casting - assert_equal 70, do_method_call(@direct_controller, 'Add', "50", "20") - assert_equal false, @direct_controller.struct_pass_value - person = DispatcherTest::Person.new(:id => 1, :name => 'test') - result = do_method_call(@direct_controller, 'StructPass', person) - assert(nil == result || true == result) - assert_equal person, @direct_controller.struct_pass_value - assert !person.equal?(@direct_controller.struct_pass_value) - result = do_method_call(@direct_controller, 'StructPass', {'id' => '1', 'name' => 'test'}) - case - when soap? - assert_equal(person, @direct_controller.struct_pass_value) - assert !person.equal?(@direct_controller.struct_pass_value) - when xmlrpc? - assert_equal(person, @direct_controller.struct_pass_value) - assert !person.equal?(@direct_controller.struct_pass_value) - end - assert_equal person, do_method_call(@direct_controller, 'HashStructReturn')[0] - result = do_method_call(@direct_controller, 'StructPass', {'id' => '1', 'name' => 'test', 'nonexistent_attribute' => 'value'}) - case - when soap? - assert_equal(person, @direct_controller.struct_pass_value) - assert !person.equal?(@direct_controller.struct_pass_value) - when xmlrpc? - assert_equal(person, @direct_controller.struct_pass_value) - assert !person.equal?(@direct_controller.struct_pass_value) - end - end - - def test_logging - buf = "" - ActionController::Base.logger = Logger.new(StringIO.new(buf)) - test_casting - test_garbage_request - test_exception_marshaling - ActionController::Base.logger = nil - assert_match /Web Service Response/, buf - assert_match /Web Service Request/, buf - end - - protected - def service_name(container) - raise NotImplementedError - end - - def exception_message(obj) - raise NotImplementedError - end - - def is_exception?(obj) - raise NotImplementedError - end - - def protocol - @protocol - end - - def soap? - protocol.is_a? ActionWebService::Protocol::Soap::SoapProtocol - end - - def xmlrpc? - protocol.is_a? ActionWebService::Protocol::XmlRpc::XmlRpcProtocol - end - - def do_method_call(container, public_method_name, *params) - request_env = {} - mode = container.web_service_dispatching_mode - case mode - when :direct - service_name = service_name(container) - api = container.class.web_service_api - method = api.public_api_method_instance(public_method_name) - when :delegated - service_name = service_name(container) - api = container.web_service_object(service_name).class.web_service_api - method = api.public_api_method_instance(public_method_name) - when :layered - service_name = nil - real_method_name = nil - if public_method_name =~ /^([^\.]+)\.(.*)$/ - service_name = $1 - real_method_name = $2 - end - if soap? - public_method_name = real_method_name - request_env['HTTP_SOAPACTION'] = "/soap/#{service_name}/#{real_method_name}" - end - api = container.web_service_object(service_name.to_sym).class.web_service_api rescue nil - method = api.public_api_method_instance(real_method_name) rescue nil - service_name = self.service_name(container) - end - protocol.register_api(api) - virtual = false - unless method - virtual = true - method ||= ActionWebService::API::Method.new(public_method_name.underscore.to_sym, public_method_name, nil, nil) - end - body = protocol.encode_request(public_method_name, params.dup, method.expects) - # puts body - ap_request = protocol.encode_action_pack_request(service_name, public_method_name, body, :request_class => ActionController::TestRequest) - ap_request.env.update(request_env) - ap_response = ActionController::TestResponse.new - container.process(ap_request, ap_response) - # puts ap_response.body - @response_body = ap_response.body - public_method_name, return_value = protocol.decode_response(ap_response.body) - unless is_exception?(return_value) || virtual - return_value = method.cast_returns(return_value) - end - if soap? - # http://dev.rubyonrails.com/changeset/920 - assert_match(/Response$/, public_method_name) unless public_method_name == "fault" - end - return_value - end -end diff --git a/tracks/vendor/rails/actionwebservice/test/abstract_unit.rb b/tracks/vendor/rails/actionwebservice/test/abstract_unit.rb deleted file mode 100644 index a57299be..00000000 --- a/tracks/vendor/rails/actionwebservice/test/abstract_unit.rb +++ /dev/null @@ -1,14 +0,0 @@ -ENV["RAILS_ENV"] = "test" -$:.unshift(File.dirname(__FILE__) + '/../lib') -$:.unshift(File.dirname(__FILE__) + '/../../activesupport/lib') -$:.unshift(File.dirname(__FILE__) + '/../../actionpack/lib') -$:.unshift(File.dirname(__FILE__) + '/../../activerecord/lib') - -require 'test/unit' -require 'active_record' -require 'action_web_service' -require 'action_controller' -require 'action_controller/test_process' - -ActionController::Base.logger = nil -ActionController::Base.ignore_missing_templates = true diff --git a/tracks/vendor/rails/actionwebservice/test/api_test.rb b/tracks/vendor/rails/actionwebservice/test/api_test.rb deleted file mode 100644 index 0e58d848..00000000 --- a/tracks/vendor/rails/actionwebservice/test/api_test.rb +++ /dev/null @@ -1,102 +0,0 @@ -require File.dirname(__FILE__) + '/abstract_unit' - -module APITest - class API < ActionWebService::API::Base - api_method :void - api_method :expects_and_returns, :expects_and_returns => [:string] - api_method :expects, :expects => [:int, :bool] - api_method :returns, :returns => [:int, [:string]] - api_method :named_signature, :expects => [{:appkey=>:int}, {:publish=>:bool}] - api_method :string_types, :expects => ['int', 'string', 'bool', 'base64'] - api_method :class_types, :expects => [TrueClass, Bignum, String] - end -end - -class TC_API < Test::Unit::TestCase - API = APITest::API - - def test_api_method_declaration - %w( - void - expects_and_returns - expects - returns - named_signature - string_types - class_types - ).each do |name| - name = name.to_sym - public_name = API.public_api_method_name(name) - assert(API.has_api_method?(name)) - assert(API.has_public_api_method?(public_name)) - assert(API.api_method_name(public_name) == name) - assert(API.api_methods.has_key?(name)) - end - end - - def test_signature_canonicalization - assert_equal(nil, API.api_methods[:void].expects) - assert_equal(nil, API.api_methods[:void].returns) - assert_equal([String], API.api_methods[:expects_and_returns].expects.map{|x| x.type_class}) - assert_equal([String], API.api_methods[:expects_and_returns].returns.map{|x| x.type_class}) - assert_equal([Integer, TrueClass], API.api_methods[:expects].expects.map{|x| x.type_class}) - assert_equal(nil, API.api_methods[:expects].returns) - assert_equal(nil, API.api_methods[:returns].expects) - assert_equal([Integer, [String]], API.api_methods[:returns].returns.map{|x| x.array?? [x.element_type.type_class] : x.type_class}) - assert_equal([[:appkey, Integer], [:publish, TrueClass]], API.api_methods[:named_signature].expects.map{|x| [x.name, x.type_class]}) - assert_equal(nil, API.api_methods[:named_signature].returns) - assert_equal([Integer, String, TrueClass, ActionWebService::Base64], API.api_methods[:string_types].expects.map{|x| x.type_class}) - assert_equal(nil, API.api_methods[:string_types].returns) - assert_equal([TrueClass, Integer, String], API.api_methods[:class_types].expects.map{|x| x.type_class}) - assert_equal(nil, API.api_methods[:class_types].returns) - end - - def test_not_instantiable - assert_raises(NoMethodError) do - API.new - end - end - - def test_api_errors - assert_raises(ActionWebService::ActionWebServiceError) do - klass = Class.new(ActionWebService::API::Base) do - api_method :test, :expects => [ActiveRecord::Base] - end - end - klass = Class.new(ActionWebService::API::Base) do - allow_active_record_expects true - api_method :test2, :expects => [ActiveRecord::Base] - end - assert_raises(ActionWebService::ActionWebServiceError) do - klass = Class.new(ActionWebService::API::Base) do - api_method :test, :invalid => [:int] - end - end - end - - def test_parameter_names - method = API.api_methods[:named_signature] - assert_equal 0, method.expects_index_of(:appkey) - assert_equal 1, method.expects_index_of(:publish) - assert_equal 1, method.expects_index_of('publish') - assert_equal 0, method.expects_index_of('appkey') - assert_equal -1, method.expects_index_of('blah') - assert_equal -1, method.expects_index_of(:missing) - assert_equal -1, API.api_methods[:void].expects_index_of('test') - end - - def test_parameter_hash - method = API.api_methods[:named_signature] - hash = method.expects_to_hash([5, false]) - assert_equal({:appkey => 5, :publish => false}, hash) - end - - def test_api_methods_compat - sig = API.api_methods[:named_signature][:expects] - assert_equal [{:appkey=>Integer}, {:publish=>TrueClass}], sig - end - - def test_to_s - assert_equal 'void Expects(int param0, bool param1)', APITest::API.api_methods[:expects].to_s - end -end diff --git a/tracks/vendor/rails/actionwebservice/test/apis/auto_load_api.rb b/tracks/vendor/rails/actionwebservice/test/apis/auto_load_api.rb deleted file mode 100644 index a35bbe3f..00000000 --- a/tracks/vendor/rails/actionwebservice/test/apis/auto_load_api.rb +++ /dev/null @@ -1,3 +0,0 @@ -class AutoLoadAPI < ActionWebService::API::Base - api_method :void -end diff --git a/tracks/vendor/rails/actionwebservice/test/apis/broken_auto_load_api.rb b/tracks/vendor/rails/actionwebservice/test/apis/broken_auto_load_api.rb deleted file mode 100644 index 139597f9..00000000 --- a/tracks/vendor/rails/actionwebservice/test/apis/broken_auto_load_api.rb +++ /dev/null @@ -1,2 +0,0 @@ - - diff --git a/tracks/vendor/rails/actionwebservice/test/base_test.rb b/tracks/vendor/rails/actionwebservice/test/base_test.rb deleted file mode 100644 index 55a112a0..00000000 --- a/tracks/vendor/rails/actionwebservice/test/base_test.rb +++ /dev/null @@ -1,42 +0,0 @@ -require File.dirname(__FILE__) + '/abstract_unit' - -module BaseTest - class API < ActionWebService::API::Base - api_method :add, :expects => [:int, :int], :returns => [:int] - api_method :void - end - - class PristineAPI < ActionWebService::API::Base - inflect_names false - - api_method :add - api_method :under_score - end - - class Service < ActionWebService::Base - web_service_api API - - def add(a, b) - end - - def void - end - end - - class PristineService < ActionWebService::Base - web_service_api PristineAPI - - def add - end - - def under_score - end - end -end - -class TC_Base < Test::Unit::TestCase - def test_options - assert(BaseTest::PristineService.web_service_api.inflect_names == false) - assert(BaseTest::Service.web_service_api.inflect_names == true) - end -end diff --git a/tracks/vendor/rails/actionwebservice/test/casting_test.rb b/tracks/vendor/rails/actionwebservice/test/casting_test.rb deleted file mode 100644 index 34bad07d..00000000 --- a/tracks/vendor/rails/actionwebservice/test/casting_test.rb +++ /dev/null @@ -1,86 +0,0 @@ -require File.dirname(__FILE__) + '/abstract_unit' - -module CastingTest - class API < ActionWebService::API::Base - api_method :int, :expects => [:int] - api_method :str, :expects => [:string] - api_method :base64, :expects => [:base64] - api_method :bool, :expects => [:bool] - api_method :float, :expects => [:float] - api_method :time, :expects => [:time] - api_method :datetime, :expects => [:datetime] - api_method :date, :expects => [:date] - - api_method :int_array, :expects => [[:int]] - api_method :str_array, :expects => [[:string]] - api_method :bool_array, :expects => [[:bool]] - end -end - -class TC_Casting < Test::Unit::TestCase - include CastingTest - - def test_base_type_casting_valid - assert_equal 10000, cast_expects(:int, '10000')[0] - assert_equal '10000', cast_expects(:str, 10000)[0] - base64 = cast_expects(:base64, 10000)[0] - assert_equal '10000', base64 - assert_instance_of ActionWebService::Base64, base64 - [1, '1', 'true', 'y', 'yes'].each do |val| - assert_equal true, cast_expects(:bool, val)[0] - end - [0, '0', 'false', 'n', 'no'].each do |val| - assert_equal false, cast_expects(:bool, val)[0] - end - assert_equal 3.14159, cast_expects(:float, '3.14159')[0] - now = Time.at(Time.now.tv_sec) - casted = cast_expects(:time, now.to_s)[0] - assert_equal now, casted - now = DateTime.now - assert_equal now.to_s, cast_expects(:datetime, now.to_s)[0].to_s - today = Date.today - assert_equal today, cast_expects(:date, today.to_s)[0] - end - - def test_base_type_casting_invalid - assert_raises ArgumentError do - cast_expects(:int, 'this is not a number') - end - assert_raises ActionWebService::Casting::CastingError do - # neither true or false ;) - cast_expects(:bool, 'i always lie') - end - assert_raises ArgumentError do - cast_expects(:float, 'not a float') - end - assert_raises ArgumentError do - cast_expects(:time, '111111111111111111111111111111111') - end - assert_raises ArgumentError do - cast_expects(:datetime, '-1') - end - assert_raises ArgumentError do - cast_expects(:date, '') - end - end - - def test_array_type_casting - assert_equal [1, 2, 3213992, 4], cast_expects(:int_array, ['1', '2', '3213992', '4'])[0] - assert_equal ['one', 'two', '5.0', '200', nil, 'true'], cast_expects(:str_array, [:one, 'two', 5.0, 200, nil, true])[0] - assert_equal [true, nil, true, true, false], cast_expects(:bool_array, ['1', nil, 'y', true, 'false'])[0] - end - - def test_array_type_casting_failure - assert_raises ActionWebService::Casting::CastingError do - cast_expects(:bool_array, ['false', 'blahblah']) - end - assert_raises ArgumentError do - cast_expects(:int_array, ['1', '2.021', '4']) - end - end - - private - def cast_expects(method_name, *args) - API.api_method_instance(method_name.to_sym).cast_expects([*args]) - end -end diff --git a/tracks/vendor/rails/actionwebservice/test/client_soap_test.rb b/tracks/vendor/rails/actionwebservice/test/client_soap_test.rb deleted file mode 100644 index e118b495..00000000 --- a/tracks/vendor/rails/actionwebservice/test/client_soap_test.rb +++ /dev/null @@ -1,109 +0,0 @@ -require File.dirname(__FILE__) + '/abstract_client' - - -module ClientSoapTest - PORT = 8998 - - class SoapClientLet < ClientTest::AbstractClientLet - def do_POST(req, res) - test_request = ActionController::TestRequest.new - test_request.request_parameters['action'] = req.path.gsub(/^\//, '').split(/\//)[1] - test_request.env['REQUEST_METHOD'] = "POST" - test_request.env['HTTP_CONTENTTYPE'] = 'text/xml' - test_request.env['HTTP_SOAPACTION'] = req.header['soapaction'][0] - test_request.env['RAW_POST_DATA'] = req.body - response = ActionController::TestResponse.new - @controller.process(test_request, response) - res.header['content-type'] = 'text/xml' - res.body = response.body - rescue Exception => e - $stderr.puts e.message - $stderr.puts e.backtrace.join("\n") - end - end - - class ClientContainer < ActionController::Base - web_client_api :client, :soap, "http://localhost:#{PORT}/client/api", :api => ClientTest::API - web_client_api :invalid, :null, "", :api => true - - def get_client - client - end - - def get_invalid - invalid - end - end - - class SoapServer < ClientTest::AbstractServer - def create_clientlet(controller) - SoapClientLet.new(controller) - end - - def server_port - PORT - end - end -end - -class TC_ClientSoap < Test::Unit::TestCase - include ClientTest - include ClientSoapTest - - def setup - @server = SoapServer.instance - @container = @server.container - @client = ActionWebService::Client::Soap.new(API, "http://localhost:#{@server.server_port}/client/api") - end - - def test_void - assert(@container.value_void.nil?) - @client.void - assert(!@container.value_void.nil?) - end - - def test_normal - assert(@container.value_normal.nil?) - assert_equal(5, @client.normal(5, 6)) - assert_equal([5, 6], @container.value_normal) - assert_equal(5, @client.normal("7", "8")) - assert_equal([7, 8], @container.value_normal) - assert_equal(5, @client.normal(true, false)) - end - - def test_array_return - assert(@container.value_array_return.nil?) - new_person = Person.new - new_person.firstnames = ["one", "two"] - new_person.lastname = "last" - assert_equal([new_person], @client.array_return) - assert_equal([new_person], @container.value_array_return) - end - - def test_struct_pass - assert(@container.value_struct_pass.nil?) - new_person = Person.new - new_person.firstnames = ["one", "two"] - new_person.lastname = "last" - assert_equal(true, @client.struct_pass([new_person])) - assert_equal([[new_person]], @container.value_struct_pass) - end - - def test_client_container - assert_equal(50, ClientContainer.new.get_client.client_container) - assert(ClientContainer.new.get_invalid.nil?) - end - - def test_named_parameters - assert(@container.value_named_parameters.nil?) - assert(@client.named_parameters("key", 5).nil?) - assert_equal(["key", 5], @container.value_named_parameters) - end - - def test_capitalized_method_name - @container.value_normal = nil - assert_equal(5, @client.Normal(5, 6)) - assert_equal([5, 6], @container.value_normal) - @container.value_normal = nil - end -end diff --git a/tracks/vendor/rails/actionwebservice/test/client_xmlrpc_test.rb b/tracks/vendor/rails/actionwebservice/test/client_xmlrpc_test.rb deleted file mode 100644 index de24d9a9..00000000 --- a/tracks/vendor/rails/actionwebservice/test/client_xmlrpc_test.rb +++ /dev/null @@ -1,108 +0,0 @@ -require File.dirname(__FILE__) + '/abstract_client' - - -module ClientXmlRpcTest - PORT = 8999 - - class XmlRpcClientLet < ClientTest::AbstractClientLet - def do_POST(req, res) - test_request = ActionController::TestRequest.new - test_request.request_parameters['action'] = req.path.gsub(/^\//, '').split(/\//)[1] - test_request.env['REQUEST_METHOD'] = "POST" - test_request.env['HTTP_CONTENT_TYPE'] = 'text/xml' - test_request.env['RAW_POST_DATA'] = req.body - response = ActionController::TestResponse.new - @controller.process(test_request, response) - res.header['content-type'] = 'text/xml' - res.body = response.body - # puts res.body - rescue Exception => e - $stderr.puts e.message - $stderr.puts e.backtrace.join("\n") - end - end - - class ClientContainer < ActionController::Base - web_client_api :client, :xmlrpc, "http://localhost:#{PORT}/client/api", :api => ClientTest::API - - def get_client - client - end - end - - class XmlRpcServer < ClientTest::AbstractServer - def create_clientlet(controller) - XmlRpcClientLet.new(controller) - end - - def server_port - PORT - end - end -end - -class TC_ClientXmlRpc < Test::Unit::TestCase - include ClientTest - include ClientXmlRpcTest - - def setup - @server = XmlRpcServer.instance - @container = @server.container - @client = ActionWebService::Client::XmlRpc.new(API, "http://localhost:#{@server.server_port}/client/api") - end - - def test_void - assert(@container.value_void.nil?) - @client.void - assert(!@container.value_void.nil?) - end - - def test_normal - assert(@container.value_normal.nil?) - assert_equal(5, @client.normal(5, 6)) - assert_equal([5, 6], @container.value_normal) - assert_equal(5, @client.normal("7", "8")) - assert_equal([7, 8], @container.value_normal) - assert_equal(5, @client.normal(true, false)) - end - - def test_array_return - assert(@container.value_array_return.nil?) - new_person = Person.new - new_person.firstnames = ["one", "two"] - new_person.lastname = "last" - assert_equal([new_person], @client.array_return) - assert_equal([new_person], @container.value_array_return) - end - - def test_struct_pass - assert(@container.value_struct_pass.nil?) - new_person = Person.new - new_person.firstnames = ["one", "two"] - new_person.lastname = "last" - assert_equal(true, @client.struct_pass([new_person])) - assert_equal([[new_person]], @container.value_struct_pass) - end - - def test_client_container - assert_equal(50, ClientContainer.new.get_client.client_container) - end - - def test_named_parameters - assert(@container.value_named_parameters.nil?) - assert_equal(true, @client.named_parameters("xxx", 7)) - assert_equal(["xxx", 7], @container.value_named_parameters) - end - - def test_exception - assert_raises(ActionWebService::Client::ClientError) do - assert(@client.thrower) - end - end - - def test_invalid_signature - assert_raises(ArgumentError) do - @client.normal - end - end -end diff --git a/tracks/vendor/rails/actionwebservice/test/container_test.rb b/tracks/vendor/rails/actionwebservice/test/container_test.rb deleted file mode 100644 index 325d420f..00000000 --- a/tracks/vendor/rails/actionwebservice/test/container_test.rb +++ /dev/null @@ -1,73 +0,0 @@ -require File.dirname(__FILE__) + '/abstract_unit' - -module ContainerTest - $immediate_service = Object.new - $deferred_service = Object.new - - class DelegateContainer < ActionController::Base - web_service_dispatching_mode :delegated - - attr :flag - attr :previous_flag - - def initialize - @previous_flag = nil - @flag = true - end - - web_service :immediate_service, $immediate_service - web_service(:deferred_service) { @previous_flag = @flag; @flag = false; $deferred_service } - end - - class DirectContainer < ActionController::Base - web_service_dispatching_mode :direct - end - - class InvalidContainer - include ActionWebService::Container::Direct - end -end - -class TC_Container < Test::Unit::TestCase - include ContainerTest - - def setup - @delegate_container = DelegateContainer.new - @direct_container = DirectContainer.new - end - - def test_registration - assert(DelegateContainer.has_web_service?(:immediate_service)) - assert(DelegateContainer.has_web_service?(:deferred_service)) - assert(!DelegateContainer.has_web_service?(:fake_service)) - assert_raises(ActionWebService::Container::Delegated::ContainerError) do - DelegateContainer.web_service('invalid') - end - end - - def test_service_object - assert_raises(ActionWebService::Container::Delegated::ContainerError) do - @delegate_container.web_service_object(:nonexistent) - end - assert(@delegate_container.flag == true) - assert(@delegate_container.web_service_object(:immediate_service) == $immediate_service) - assert(@delegate_container.previous_flag.nil?) - assert(@delegate_container.flag == true) - assert(@delegate_container.web_service_object(:deferred_service) == $deferred_service) - assert(@delegate_container.previous_flag == true) - assert(@delegate_container.flag == false) - end - - def test_direct_container - assert(DirectContainer.web_service_dispatching_mode == :direct) - end - - def test_validity - assert_raises(ActionWebService::Container::Direct::ContainerError) do - InvalidContainer.web_service_api :test - end - assert_raises(ActionWebService::Container::Direct::ContainerError) do - InvalidContainer.web_service_api 50.0 - end - end -end diff --git a/tracks/vendor/rails/actionwebservice/test/dispatcher_action_controller_soap_test.rb b/tracks/vendor/rails/actionwebservice/test/dispatcher_action_controller_soap_test.rb deleted file mode 100644 index 681c7c54..00000000 --- a/tracks/vendor/rails/actionwebservice/test/dispatcher_action_controller_soap_test.rb +++ /dev/null @@ -1,139 +0,0 @@ -$:.unshift(File.dirname(__FILE__) + '/apis') -require File.dirname(__FILE__) + '/abstract_dispatcher' -require 'wsdl/parser' - -class ActionController::Base - class << self - alias :inherited_without_name_error :inherited - def inherited(child) - begin - inherited_without_name_error(child) - rescue NameError => e - end - end - end -end - -class AutoLoadController < ActionController::Base; end -class FailingAutoLoadController < ActionController::Base; end -class BrokenAutoLoadController < ActionController::Base; end - -class TC_DispatcherActionControllerSoap < Test::Unit::TestCase - include DispatcherTest - include DispatcherCommonTests - - def setup - @direct_controller = DirectController.new - @delegated_controller = DelegatedController.new - @virtual_controller = VirtualController.new - @layered_controller = LayeredController.new - @protocol = ActionWebService::Protocol::Soap::SoapProtocol.create(@direct_controller) - end - - def test_wsdl_generation - ensure_valid_wsdl_generation DelegatedController.new, DispatcherTest::WsdlNamespace - ensure_valid_wsdl_generation DirectController.new, DispatcherTest::WsdlNamespace - end - - def test_wsdl_action - delegated_types = ensure_valid_wsdl_action DelegatedController.new - delegated_names = delegated_types.map{|x| x.name.name} - assert(delegated_names.include?('DispatcherTest..NodeArray')) - assert(delegated_names.include?('DispatcherTest..Node')) - direct_types = ensure_valid_wsdl_action DirectController.new - direct_names = direct_types.map{|x| x.name.name} - assert(direct_names.include?('DispatcherTest..NodeArray')) - assert(direct_names.include?('DispatcherTest..Node')) - assert(direct_names.include?('IntegerArray')) - end - - def test_autoloading - assert(!AutoLoadController.web_service_api.nil?) - assert(AutoLoadController.web_service_api.has_public_api_method?('Void')) - assert(FailingAutoLoadController.web_service_api.nil?) - assert_raises(MissingSourceFile) do - FailingAutoLoadController.require_web_service_api :blah - end - assert_raises(ArgumentError) do - FailingAutoLoadController.require_web_service_api 50.0 - end - assert(BrokenAutoLoadController.web_service_api.nil?) - end - - def test_layered_dispatching - mt_cats = do_method_call(@layered_controller, 'mt.getCategories') - assert_equal(["mtCat1", "mtCat2"], mt_cats) - blogger_cats = do_method_call(@layered_controller, 'blogger.getCategories') - assert_equal(["bloggerCat1", "bloggerCat2"], blogger_cats) - end - - def test_utf8 - @direct_controller.web_service_exception_reporting = true - $KCODE = 'u' - assert_equal(Utf8String, do_method_call(@direct_controller, 'TestUtf8')) - retval = SOAP::Processor.unmarshal(@response_body).body.response - assert retval.is_a?(SOAP::SOAPString) - - # If $KCODE is not set to UTF-8, any strings with non-ASCII UTF-8 data - # will be sent back as base64 by SOAP4R. By the time we get it here though, - # it will be decoded back into a string. So lets read the base64 value - # from the message body directly. - $KCODE = 'NONE' - do_method_call(@direct_controller, 'TestUtf8') - retval = SOAP::Processor.unmarshal(@response_body).body.response - assert retval.is_a?(SOAP::SOAPBase64) - assert_equal "T25lIFdvcmxkIENhZsOp", retval.data.to_s - end - - protected - def exception_message(soap_fault_exception) - soap_fault_exception.detail.cause.message - end - - def is_exception?(obj) - obj.respond_to?(:detail) && obj.detail.respond_to?(:cause) && \ - obj.detail.cause.is_a?(Exception) - end - - def service_name(container) - container.is_a?(DelegatedController) ? 'test_service' : 'api' - end - - def ensure_valid_wsdl_generation(controller, expected_namespace) - wsdl = controller.generate_wsdl - ensure_valid_wsdl(controller, wsdl, expected_namespace) - end - - def ensure_valid_wsdl(controller, wsdl, expected_namespace) - definitions = WSDL::Parser.new.parse(wsdl) - assert(definitions.is_a?(WSDL::Definitions)) - definitions.bindings.each do |binding| - assert(binding.name.name.index(':').nil?) - end - definitions.services.each do |service| - service.ports.each do |port| - assert(port.name.name.index(':').nil?) - end - end - types = definitions.collect_complextypes.map{|x| x.name} - types.each do |type| - assert(type.namespace == expected_namespace) - end - location = definitions.services[0].ports[0].soap_address.location - if controller.is_a?(DelegatedController) - assert_match %r{http://localhost/dispatcher_test/delegated/test_service$}, location - elsif controller.is_a?(DirectController) - assert_match %r{http://localhost/dispatcher_test/direct/api$}, location - end - definitions.collect_complextypes - end - - def ensure_valid_wsdl_action(controller) - test_request = ActionController::TestRequest.new({ 'action' => 'wsdl' }) - test_request.env['REQUEST_METHOD'] = 'GET' - test_request.env['HTTP_HOST'] = 'localhost' - test_response = ActionController::TestResponse.new - wsdl = controller.process(test_request, test_response).body - ensure_valid_wsdl(controller, wsdl, DispatcherTest::WsdlNamespace) - end -end diff --git a/tracks/vendor/rails/actionwebservice/test/dispatcher_action_controller_xmlrpc_test.rb b/tracks/vendor/rails/actionwebservice/test/dispatcher_action_controller_xmlrpc_test.rb deleted file mode 100644 index 95c93339..00000000 --- a/tracks/vendor/rails/actionwebservice/test/dispatcher_action_controller_xmlrpc_test.rb +++ /dev/null @@ -1,57 +0,0 @@ -require File.dirname(__FILE__) + '/abstract_dispatcher' - -class TC_DispatcherActionControllerXmlRpc < Test::Unit::TestCase - include DispatcherTest - include DispatcherCommonTests - - def setup - @direct_controller = DirectController.new - @delegated_controller = DelegatedController.new - @layered_controller = LayeredController.new - @virtual_controller = VirtualController.new - @protocol = ActionWebService::Protocol::XmlRpc::XmlRpcProtocol.create(@direct_controller) - end - - def test_layered_dispatching - mt_cats = do_method_call(@layered_controller, 'mt.getCategories') - assert_equal(["mtCat1", "mtCat2"], mt_cats) - blogger_cats = do_method_call(@layered_controller, 'blogger.getCategories') - assert_equal(["bloggerCat1", "bloggerCat2"], blogger_cats) - end - - def test_multicall - response = do_method_call(@layered_controller, 'system.multicall', [ - {'methodName' => 'mt.getCategories'}, - {'methodName' => 'blogger.getCategories'}, - {'methodName' => 'mt.bool'}, - {'methodName' => 'blogger.str', 'params' => ['2000']}, - {'methodName' => 'mt.alwaysFail'}, - {'methodName' => 'blogger.alwaysFail'}, - {'methodName' => 'mt.blah'}, - {'methodName' => 'blah.blah'} - ]) - assert_equal [ - [["mtCat1", "mtCat2"]], - [["bloggerCat1", "bloggerCat2"]], - [true], - ["2500"], - {"faultCode" => 3, "faultString" => "MT AlwaysFail"}, - {"faultCode" => 3, "faultString" => "Blogger AlwaysFail"}, - {"faultCode" => 4, "faultMessage" => "no such method 'blah' on API DispatcherTest::MTAPI"}, - {"faultCode" => 4, "faultMessage" => "no such web service 'blah'"} - ], response - end - - protected - def exception_message(xmlrpc_fault_exception) - xmlrpc_fault_exception.faultString - end - - def is_exception?(obj) - obj.is_a?(XMLRPC::FaultException) - end - - def service_name(container) - container.is_a?(DelegatedController) ? 'test_service' : 'api' - end -end diff --git a/tracks/vendor/rails/actionwebservice/test/gencov b/tracks/vendor/rails/actionwebservice/test/gencov deleted file mode 100644 index 1faab34c..00000000 --- a/tracks/vendor/rails/actionwebservice/test/gencov +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh - -rcov -x '.*_test\.rb,rubygems,abstract_,/run,/apis' ./run diff --git a/tracks/vendor/rails/actionwebservice/test/invocation_test.rb b/tracks/vendor/rails/actionwebservice/test/invocation_test.rb deleted file mode 100644 index 3ef22faf..00000000 --- a/tracks/vendor/rails/actionwebservice/test/invocation_test.rb +++ /dev/null @@ -1,185 +0,0 @@ -require File.dirname(__FILE__) + '/abstract_unit' - -module InvocationTest - class API < ActionWebService::API::Base - api_method :add, :expects => [:int, :int], :returns => [:int] - api_method :transmogrify, :expects_and_returns => [:string] - api_method :fail_with_reason - api_method :fail_generic - api_method :no_before - api_method :no_after - api_method :only_one - api_method :only_two - end - - class Interceptor - attr :args - - def initialize - @args = nil - end - - def intercept(*args) - @args = args - end - end - - InterceptorClass = Interceptor.new - - class Service < ActionController::Base - web_service_api API - - before_invocation :intercept_before, :except => [:no_before] - after_invocation :intercept_after, :except => [:no_after] - prepend_after_invocation :intercept_after_first, :except => [:no_after] - prepend_before_invocation :intercept_only, :only => [:only_one, :only_two] - after_invocation(:only => [:only_one]) do |*args| - args[0].instance_variable_set('@block_invoked', args[1]) - end - after_invocation InterceptorClass, :only => [:only_one] - - attr_accessor :before_invoked - attr_accessor :after_invoked - attr_accessor :after_first_invoked - attr_accessor :only_invoked - attr_accessor :block_invoked - attr_accessor :invocation_result - - def initialize - @before_invoked = nil - @after_invoked = nil - @after_first_invoked = nil - @only_invoked = nil - @invocation_result = nil - @block_invoked = nil - end - - def add(a, b) - a + b - end - - def transmogrify(str) - str.upcase - end - - def fail_with_reason - end - - def fail_generic - end - - def no_before - 5 - end - - def no_after - end - - def only_one - end - - def only_two - end - - protected - def intercept_before(name, args) - @before_invoked = name - return [false, "permission denied"] if name == :fail_with_reason - return false if name == :fail_generic - end - - def intercept_after(name, args, result) - @after_invoked = name - @invocation_result = result - end - - def intercept_after_first(name, args, result) - @after_first_invoked = name - end - - def intercept_only(name, args) - raise "Interception error" unless name == :only_one || name == :only_two - @only_invoked = name - end - end -end - -class TC_Invocation < Test::Unit::TestCase - include ActionWebService::Invocation - - def setup - @service = InvocationTest::Service.new - end - - def test_invocation - assert(perform_invocation(:add, 5, 10) == 15) - assert(perform_invocation(:transmogrify, "hello") == "HELLO") - assert_raises(NoMethodError) do - perform_invocation(:nonexistent_method_xyzzy) - end - end - - def test_interceptor_registration - assert(InvocationTest::Service.before_invocation_interceptors.length == 2) - assert(InvocationTest::Service.after_invocation_interceptors.length == 4) - assert_equal(:intercept_only, InvocationTest::Service.before_invocation_interceptors[0]) - assert_equal(:intercept_after_first, InvocationTest::Service.after_invocation_interceptors[0]) - end - - def test_interception - assert(@service.before_invoked.nil?) - assert(@service.after_invoked.nil?) - assert(@service.only_invoked.nil?) - assert(@service.block_invoked.nil?) - assert(@service.invocation_result.nil?) - perform_invocation(:add, 20, 50) - assert(@service.before_invoked == :add) - assert(@service.after_invoked == :add) - assert(@service.invocation_result == 70) - end - - def test_interception_canceling - reason = nil - perform_invocation(:fail_with_reason){|r| reason = r} - assert(@service.before_invoked == :fail_with_reason) - assert(@service.after_invoked.nil?) - assert(@service.invocation_result.nil?) - assert(reason == "permission denied") - reason = true - @service.before_invoked = @service.after_invoked = @service.invocation_result = nil - perform_invocation(:fail_generic){|r| reason = r} - assert(@service.before_invoked == :fail_generic) - assert(@service.after_invoked.nil?) - assert(@service.invocation_result.nil?) - assert(reason == true) - end - - def test_interception_except_conditions - perform_invocation(:no_before) - assert(@service.before_invoked.nil?) - assert(@service.after_first_invoked == :no_before) - assert(@service.after_invoked == :no_before) - assert(@service.invocation_result == 5) - @service.before_invoked = @service.after_invoked = @service.invocation_result = nil - perform_invocation(:no_after) - assert(@service.before_invoked == :no_after) - assert(@service.after_invoked.nil?) - assert(@service.invocation_result.nil?) - end - - def test_interception_only_conditions - assert(@service.only_invoked.nil?) - perform_invocation(:only_one) - assert(@service.only_invoked == :only_one) - assert(@service.block_invoked == :only_one) - assert(InvocationTest::InterceptorClass.args[1] == :only_one) - @service.only_invoked = nil - perform_invocation(:only_two) - assert(@service.only_invoked == :only_two) - end - - private - def perform_invocation(method_name, *args, &block) - @service.perform_invocation(method_name, args, &block) - end -end diff --git a/tracks/vendor/rails/actionwebservice/test/run b/tracks/vendor/rails/actionwebservice/test/run deleted file mode 100644 index c8c03727..00000000 --- a/tracks/vendor/rails/actionwebservice/test/run +++ /dev/null @@ -1,6 +0,0 @@ -#!/usr/bin/env ruby -require 'test/unit' -$:.unshift(File.dirname(__FILE__) + '/../lib') -args = Dir[File.join(File.dirname(__FILE__), '*_test.rb')] + Dir[File.join(File.dirname(__FILE__), 'ws/*_test.rb')] -(r = Test::Unit::AutoRunner.new(true)).process_args(args) -exit r.run diff --git a/tracks/vendor/rails/actionwebservice/test/scaffolded_controller_test.rb b/tracks/vendor/rails/actionwebservice/test/scaffolded_controller_test.rb deleted file mode 100644 index fc617a14..00000000 --- a/tracks/vendor/rails/actionwebservice/test/scaffolded_controller_test.rb +++ /dev/null @@ -1,67 +0,0 @@ -require File.dirname(__FILE__) + '/abstract_unit' - -ActionController::Routing::Routes.draw do |map| - map.connect '', :controller => 'scaffolded' -end - -class ScaffoldPerson < ActionWebService::Struct - member :id, :int - member :name, :string - - def ==(other) - self.id == other.id && self.name == other.name - end -end - -class ScaffoldedControllerTestAPI < ActionWebService::API::Base - api_method :hello, :expects => [{:integer=>:int}, :string], :returns => [:bool] - api_method :bye, :returns => [[ScaffoldPerson]] -end - -class ScaffoldedController < ActionController::Base - web_service_api ScaffoldedControllerTestAPI - web_service_scaffold :scaffold_invoke - - def hello(int, string) - 0 - end - - def bye - [ScaffoldPerson.new(:id => 1, :name => "leon"), ScaffoldPerson.new(:id => 2, :name => "paul")] - end - - def rescue_action(e) - raise e - end -end - -class ScaffoldedControllerTest < Test::Unit::TestCase - def setup - @controller = ScaffoldedController.new - @request = ActionController::TestRequest.new - @response = ActionController::TestResponse.new - end - - def test_scaffold_invoke - get :scaffold_invoke - assert_rendered_file 'methods.rhtml' - end - - def test_scaffold_invoke_method_params - get :scaffold_invoke_method_params, :service => 'scaffolded', :method => 'Hello' - assert_rendered_file 'parameters.rhtml' - end - - def test_scaffold_invoke_submit_hello - post :scaffold_invoke_submit, :service => 'scaffolded', :method => 'Hello', :method_params => {'0' => '5', '1' => 'hello world'} - assert_rendered_file 'result.rhtml' - assert_equal false, @controller.instance_eval{ @method_return_value } - end - - def test_scaffold_invoke_submit_bye - post :scaffold_invoke_submit, :service => 'scaffolded', :method => 'Bye' - assert_rendered_file 'result.rhtml' - persons = [ScaffoldPerson.new(:id => 1, :name => "leon"), ScaffoldPerson.new(:id => 2, :name => "paul")] - assert_equal persons, @controller.instance_eval{ @method_return_value } - end -end diff --git a/tracks/vendor/rails/actionwebservice/test/struct_test.rb b/tracks/vendor/rails/actionwebservice/test/struct_test.rb deleted file mode 100644 index f689746e..00000000 --- a/tracks/vendor/rails/actionwebservice/test/struct_test.rb +++ /dev/null @@ -1,52 +0,0 @@ -require File.dirname(__FILE__) + '/abstract_unit' - -module StructTest - class Struct < ActionWebService::Struct - member :id, Integer - member :name, String - member :items, [String] - member :deleted, :bool - member :emails, [:string] - end -end - -class TC_Struct < Test::Unit::TestCase - include StructTest - - def setup - @struct = Struct.new(:id => 5, - :name => 'hello', - :items => ['one', 'two'], - :deleted => true, - :emails => ['test@test.com']) - end - - def test_members - assert_equal(5, Struct.members.size) - assert_equal(Integer, Struct.members[:id].type_class) - assert_equal(String, Struct.members[:name].type_class) - assert_equal(String, Struct.members[:items].element_type.type_class) - assert_equal(TrueClass, Struct.members[:deleted].type_class) - assert_equal(String, Struct.members[:emails].element_type.type_class) - end - - def test_initializer_and_lookup - assert_equal(5, @struct.id) - assert_equal('hello', @struct.name) - assert_equal(['one', 'two'], @struct.items) - assert_equal(true, @struct.deleted) - assert_equal(['test@test.com'], @struct.emails) - assert_equal(5, @struct['id']) - assert_equal('hello', @struct['name']) - assert_equal(['one', 'two'], @struct['items']) - assert_equal(true, @struct['deleted']) - assert_equal(['test@test.com'], @struct['emails']) - end - - def test_each_pair - @struct.each_pair do |name, value| - assert_equal @struct.__send__(name), value - assert_equal @struct[name], value - end - end -end diff --git a/tracks/vendor/rails/actionwebservice/test/test_invoke_test.rb b/tracks/vendor/rails/actionwebservice/test/test_invoke_test.rb deleted file mode 100644 index 611a0ac2..00000000 --- a/tracks/vendor/rails/actionwebservice/test/test_invoke_test.rb +++ /dev/null @@ -1,79 +0,0 @@ -require File.dirname(__FILE__) + '/abstract_unit' -require 'action_web_service/test_invoke' - -class TestInvokeAPI < ActionWebService::API::Base - api_method :add, :expects => [:int, :int], :returns => [:int] -end - -class TestInvokeService < ActionWebService::Base - web_service_api TestInvokeAPI - - attr :invoked - - def add(a, b) - @invoked = true - a + b - end -end - -class TestController < ActionController::Base - def rescue_action(e); raise e; end -end - -class TestInvokeDirectController < TestController - web_service_api TestInvokeAPI - - attr :invoked - - def add - @invoked = true - @method_params[0] + @method_params[1] - end -end - -class TestInvokeDelegatedController < TestController - web_service_dispatching_mode :delegated - web_service :service, TestInvokeService.new -end - -class TestInvokeLayeredController < TestController - web_service_dispatching_mode :layered - web_service(:one) { @service_one ||= TestInvokeService.new } - web_service(:two) { @service_two ||= TestInvokeService.new } -end - -class TestInvokeTest < Test::Unit::TestCase - def setup - @request = ActionController::TestRequest.new - @response = ActionController::TestResponse.new - end - - def test_direct_add - @controller = TestInvokeDirectController.new - assert_equal nil, @controller.invoked - result = invoke :add, 25, 25 - assert_equal 50, result - assert_equal true, @controller.invoked - end - - def test_delegated_add - @controller = TestInvokeDelegatedController.new - assert_equal nil, @controller.web_service_object(:service).invoked - result = invoke_delegated :service, :add, 100, 50 - assert_equal 150, result - assert_equal true, @controller.web_service_object(:service).invoked - end - - def test_layered_add - [:soap, :xmlrpc].each do |protocol| - @protocol = protocol - [:one, :two].each do |service| - @controller = TestInvokeLayeredController.new - assert_equal nil, @controller.web_service_object(service).invoked - result = invoke_layered service, :add, 200, -50 - assert_equal 150, result - assert_equal true, @controller.web_service_object(service).invoked - end - end - end -end diff --git a/tracks/vendor/rails/activerecord/CHANGELOG b/tracks/vendor/rails/activerecord/CHANGELOG deleted file mode 100644 index 2b00dd91..00000000 --- a/tracks/vendor/rails/activerecord/CHANGELOG +++ /dev/null @@ -1,2083 +0,0 @@ -* -*1.13.2* (December 13th, 2005) - -* Become part of Rails 1.0 - -* MySQL: allow encoding option for mysql.rb driver. [Jeremy Kemper] - -* MySQL: fixes for the bundled mysql.rb driver. #3160 [Justin Forder] - -* MySQL, PostgreSQL: reconnect! also reconfigures the connection. Otherwise, the connection 'loses' its settings if it times out and is reconnected. #2978 [Shugo Maeda] - -* SQLServer: fix obscure optimistic locking bug. #3068 [kajism@yahoo.com] - -* SQLServer: support uniqueidentifier columns. #2930 [keithm@infused.org] - -* SQLServer: cope with tables names qualified by owner. #3067 [jeff@ministrycentered.com] - -* SQLServer: cope with columns with "desc" in the name. #1950 [Ron Lusk, Ryan Tomayko] - -* SQLServer: cope with primary keys with "select" in the name. #3057 [rdifrango@captechventures.com] - -* Oracle: active? performs a select instead of a commit. #3133 [Michael Schoen] - - -*1.13.1* (December 7th, 2005) - -* MySQL: more robust test for nullified result hashes. #3124 [Stefan Kaes] - -* Reloading an instance refreshes its aggregations as well as its associations. #3024 [François Beausolei] - -* Fixed that using :include together with :conditions array in Base.find would cause NoMethodError #2887 [Paul Hammmond] - -* PostgreSQL: more robust sequence name discovery. #3087 [Rick Olson] - -* Oracle: use syntax compatible with Oracle 8. #3131 [Michael Schoen] - -* MySQL: work around ruby-mysql/mysql-ruby inconsistency with mysql.stat. Eliminate usage of mysql.ping because it doesn't guarantee reconnect. Explicitly close and reopen the connection instead. [Jeremy Kemper] - -* When AbstractAdapter#log rescues an exception, attempt to detect and reconnect to an inactive database connection. Connection adapter must respond to the active? and reconnect! instance methods. Initial support for PostgreSQL, MySQL, and SQLite. Make certain that all statements which may need reconnection are performed within a logged block: for example, this means no avoiding log(sql, name) { } if @logger.nil? [Jeremy Kemper] - -* Firebird: active? and reconnect! methods for handling stale connections. #428 [Ken Kunz ] - -* Firebird: updated for FireRuby 0.4.0. #3009 [Ken Kunz ] - -* Introducing the Firebird adapter. Quote columns and use attribute_condition more consistently. Setup guide: http://wiki.rubyonrails.com/rails/pages/Firebird+Adapter #1874 [Ken Kunz ] - -* MySQL and PostgreSQL: active? compatibility with the pure-Ruby driver. #428 [Jeremy Kemper] - -* Oracle: active? check pings the database rather than testing the last command status. #428 [Michael Schoen] - -* SQLServer: resolve column aliasing/quoting collision when using limit or offset in an eager find. #2974 [kajism@yahoo.com] - -* Reloading a model doesn't lose track of its connection. #2996 [junk@miriamtech.com, Jeremy Kemper] - -* Fixed bug where using update_attribute after pushing a record to a habtm association of the object caused duplicate rows in the join table. #2888 [colman@rominato.com, Florian Weber, Michael Schoen] - -* MySQL: introduce :encoding option to specify the character set for client, connection, and results. Only available for MySQL 4.1 and later with the mysql-ruby driver. Do SHOW CHARACTER SET in mysql client to see available encodings. #2975 [Shugo Maeda] - -* Add tasks to create, drop and rebuild the MySQL and PostgreSQL test databases. [Marcel Molina Jr.] - -* Correct boolean handling in generated reader methods. #2945 [don.park@gmail.com, Stefan Kaes] - -* Don't generate read methods for columns whose names are not valid ruby method names. #2946 [Stefan Kaes] - -* Document :force option to create_table. #2921 [Blair Zajac ] - -* Don't add the same conditions twice in has_one finder sql. #2916 [Jeremy Evans] - -* Rename Version constant to VERSION. #2802 [Marcel Molina Jr.] - -* SQLServer: insert uses given primary key value if not nil rather than SELECT @@IDENTITY. #2866 [kajism@yahoo.com, Tom Ward ] - -* Correct documentation for Base.delete_all. #1568 [Newhydra] - -* Oracle: test case for column default parsing. #2788 [Michael Schoen ] - -* Update documentation for Migrations. #2861 [Tom Werner ] - -* Oracle: Much faster column reflection. #2848 [Michael Schoen ] - -* Base.reset_sequence_name analogous to reset_table_name (mostly useful for testing). Base.define_attr_method allows nil values. [Jeremy Kemper] - -* PostgreSQL: smarter sequence name defaults, stricter last_insert_id, warn on pk without sequence. [Jeremy Kemper] - -* PostgreSQL: correctly discover custom primary key sequences. #2594 [Blair Zajac , meadow.nnick@gmail.com, Jeremy Kemper] - -* SQLServer: don't report limits for unsupported field types. #2835 [Ryan Tomayko] - -* Include the Enumerable module in ActiveRecord::Errors. [Rick Bradley ] - -* Add :group option, correspond to GROUP BY, to the find method and to the has_many association. #2818 [rubyonrails@atyp.de] - -* Don't cast nil or empty strings to a dummy date. #2789 [Rick Bradley ] - -* acts_as_list plays nicely with inheritance by remembering the class which declared it. #2811 [rephorm@rephorm.com] - -* Fix sqlite adaptor's detection of missing dbfile or database declaration. [Nicholas Seckar] - -* Fixed acts_as_list for definitions without an explicit :order #2803 [jonathan@bluewire.net.nz] - -* Upgrade bundled ruby-mysql 0.2.4 with mysql411 shim (see #440) to ruby-mysql 0.2.6 with a patchset for 4.1 protocol support. Local change [301] is now a part of the main driver; reapplied local change [2182]. Removed GC.start from Result.free. [tommy@tmtm.org, akuroda@gmail.com, Doug Fales , Jeremy Kemper] - -* Correct handling of complex order clauses with SQL Server limit emulation. #2770 [Tom Ward , Matt B.] - -* Correct whitespace problem in Oracle default column value parsing. #2788 [rick@rickbradley.com] - -* Destroy associated has_and_belongs_to_many records after all before_destroy callbacks but before destroy. This allows you to act on the habtm association as you please while preserving referential integrity. #2065 [larrywilliams1@gmail.com, sam.kirchmeier@gmail.com, elliot@townx.org, Jeremy Kemper] - -* Deprecate the old, confusing :exclusively_dependent option in favor of :dependent => :delete_all. [Jeremy Kemper] - -* More compatible Oracle column reflection. #2771 [Ryan Davis , Michael Schoen ] - - -*1.13.0* (November 7th, 2005) - -* Fixed faulty regex in get_table_name method (SQLServerAdapter) #2639 [Ryan Tomayko] - -* Added :include as an option for association declarations [DHH]. Example: - - has_many :posts, :include => [ :author, :comments ] - -* Rename Base.constrain to Base.with_scope so it doesn't conflict with existing concept of database constraints. Make scoping more robust: uniform method => parameters, validated method names and supported finder parameters, raise exception on nested scopes. [Jeremy Kemper] Example: - - Comment.with_scope(:find => { :conditions => 'active=true' }, :create => { :post_id => 5 }) do - # Find where name = ? and active=true - Comment.find :all, :conditions => ['name = ?', name] - # Create comment associated with :post_id - Comment.create :body => "Hello world" - end - -* Fixed that SQL Server should ignore :size declarations on anything but integer and string in the agnostic schema representation #2756 [Ryan Tomayko] - -* Added constrain scoping for creates using a hash of attributes bound to the :creation key [DHH]. Example: - - Comment.constrain(:creation => { :post_id => 5 }) do - # Associated with :post_id - Comment.create :body => "Hello world" - end - - This is rarely used directly, but allows for find_or_create on associations. So you can do: - - # If the tag doesn't exist, a new one is created that's associated with the person - person.tags.find_or_create_by_name("Summer") - -* Added find_or_create_by_X as a second type of dynamic finder that'll create the record if it doesn't already exist [DHH]. Example: - - # No 'Summer' tag exists - Tag.find_or_create_by_name("Summer") # equal to Tag.create(:name => "Summer") - - # Now the 'Summer' tag does exist - Tag.find_or_create_by_name("Summer") # equal to Tag.find_by_name("Summer") - -* Added extension capabilities to has_many and has_and_belongs_to_many proxies [DHH]. Example: - - class Account < ActiveRecord::Base - has_many :people do - def find_or_create_by_name(name) - first_name, *last_name = name.split - last_name = last_name.join " " - - find_or_create_by_first_name_and_last_name(first_name, last_name) - end - end - end - - person = Account.find(:first).people.find_or_create_by_name("David Heinemeier Hansson") - person.first_name # => "David" - person.last_name # => "Heinemeier Hansson" - - Note that the anoymous module must be declared using brackets, not do/end (due to order of evaluation). - -* Omit internal dtproperties table from SQLServer table list. #2729 [rtomayko@gmail.com] - -* Quote column names in generated SQL. #2728 [rtomayko@gmail.com] - -* Correct the pure-Ruby MySQL 4.1.1 shim's version test. #2718 [Jeremy Kemper] - -* Add Model.create! to match existing model.save! method. When save! raises RecordInvalid, you can catch the exception, retrieve the invalid record (invalid_exception.record), and see its errors (invalid_exception.record.errors). [Jeremy Kemper] - -* Correct fixture behavior when table name pluralization is off. #2719 [Rick Bradley ] - -* Changed :dbfile to :database for SQLite adapter for consistency (old key still works as an alias) #2644 [Dan Peterson] - -* Added migration support for Oracle #2647 [Michael Schoen] - -* Worked around that connection can't be reset if allow_concurrency is off. #2648 [Michael Schoen ] - -* Fixed SQL Server adapter to pass even more tests and do even better #2634 [rtomayko@gmail.com] - -* Fixed SQL Server adapter so it honors options[:conditions] when applying :limits #1978 [Tom Ward] - -* Added migration support to SQL Server adapter (please someone do the same for Oracle and DB2) #2625 [Tom Ward] - -* Use AR::Base.silence rather than AR::Base.logger.silence in fixtures to preserve Log4r compatibility. #2618 [dansketcher@gmail.com] - -* Constraints are cloned so they can't be inadvertently modified while they're -in effect. Added :readonly finder constraint. Calling an association collection's class method (Part.foobar via item.parts.foobar) constrains :readonly => false since the collection's :joins constraint would otherwise force it to true. [Jeremy Kemper ] - -* Added :offset and :limit to the kinds of options that Base.constrain can use #2466 [duane.johnson@gmail.com] - -* Fixed handling of nil number columns on Oracle and cleaned up tests for Oracle in general #2555 [schoenm@earthlink.net] - -* Added quoted_true and quoted_false methods and tables to db2_adapter and cleaned up tests for DB2 #2493, #2624 [maik schmidt] - - -*1.12.2* (October 26th, 2005) - -* Allow symbols to rename columns when using SQLite adapter. #2531 [kevin.clark@gmail.com] - -* Map Active Record time to SQL TIME. #2575, #2576 [Robby Russell ] - -* Clarify semantics of ActiveRecord::Base#respond_to? #2560 [skaes@web.de] - -* Fixed Association#clear for associations which have not yet been accessed. #2524 [Patrick Lenz ] - -* HABTM finders shouldn't return readonly records. #2525 [Patrick Lenz ] - -* Make all tests runnable on their own. #2521. [Blair Zajac ] - - -*1.12.1* (October 19th, 2005) - -* Always parenthesize :conditions options so they may be safely combined with STI and constraints. - -* Correct PostgreSQL primary key sequence detection. #2507 [tmornini@infomania.com] - -* Added support for using limits in eager loads that involve has_many and has_and_belongs_to_many associations - - -*1.12.0* (October 16th, 2005) - -* Update/clean up documentation (rdoc) - -* PostgreSQL sequence support. Use set_sequence_name in your model class to specify its primary key sequence. #2292 [Rick Olson , Robby Russell ] - -* Change default logging colors to work on both white and black backgrounds. [Sam Stephenson] - -* YAML fixtures support ordered hashes for fixtures with foreign key dependencies in the same table. #1896 [purestorm@ggnore.net] - -* :dependent now accepts :nullify option. Sets the foreign key of the related objects to NULL instead of deleting them. #2015 [Robby Russell ] - -* Introduce read-only records. If you call object.readonly! then it will mark the object as read-only and raise ReadOnlyRecord if you call object.save. object.readonly? reports whether the object is read-only. Passing :readonly => true to any finder method will mark returned records as read-only. The :joins option now implies :readonly, so if you use this option, saving the same record will now fail. Use find_by_sql to work around. - -* Avoid memleak in dev mode when using fcgi - -* Simplified .clear on active record associations by using the existing delete_records method. #1906 [Caleb ] - -* Delegate access to a customized primary key to the conventional id method. #2444. [Blair Zajac ] - -* Fix errors caused by assigning a has-one or belongs-to property to itself - -* Add ActiveRecord::Base.schema_format setting which specifies how databases should be dumped [Sam Stephenson] - -* Update DB2 adapter. #2206. [contact@maik-schmidt.de] - -* Corrections to SQLServer native data types. #2267. [rails.20.clarry@spamgourmet.com] - -* Deprecated ActiveRecord::Base.threaded_connection in favor of ActiveRecord::Base.allow_concurrency. - -* Protect id attribute from mass assigment even when the primary key is set to something else. #2438. [Blair Zajac ] - -* Misc doc fixes (typos/grammar/etc.). #2430. [coffee2code] - -* Add test coverage for content_columns. #2432. [coffee2code] - -* Speed up for unthreaded environments. #2431. [skaes@web.de] - -* Optimization for Mysql selects using mysql-ruby extension greater than 2.6.3. #2426. [skaes@web.de] - -* Speed up the setting of table_name. #2428. [skaes@web.de] - -* Optimize instantiation of STI subclass records. In partial fullfilment of #1236. [skaes@web.de] - -* Fix typo of 'constrains' to 'contraints'. #2069. [Michael Schuerig ] - -* Optimization refactoring for add_limit_offset!. In partial fullfilment of #1236. [skaes@web.de] - -* Add ability to get all siblings, including the current child, with acts_as_tree. Recloses #2140. [Michael Schuerig ] - -* Add geometric type for postgresql adapter. #2233 [akaspick@gmail.com] - -* Add option (true by default) to generate reader methods for each attribute of a record to avoid the overhead of calling method missing. In partial fullfilment of #1236. [skaes@web.de] - -* Add convenience predicate methods on Column class. In partial fullfilment of #1236. [skaes@web.de] - -* Raise errors when invalid hash keys are passed to ActiveRecord::Base.find. #2363 [Chad Fowler , Nicholas Seckar] - -* Added :force option to create_table that'll try to drop the table if it already exists before creating - -* Fix transactions so that calling return while inside a transaction will not leave an open transaction on the connection. [Nicholas Seckar] - -* Use foreign_key inflection uniformly. #2156 [Blair Zajac ] - -* model.association.clear should destroy associated objects if :dependent => true instead of nullifying their foreign keys. #2221 [joergd@pobox.com, ObieFernandez ] - -* Returning false from before_destroy should cancel the action. #1829 [Jeremy Huffman] - -* Recognize PostgreSQL NOW() default as equivalent to CURRENT_TIMESTAMP or CURRENT_DATE, depending on the column's type. #2256 [mat ] - -* Extensive documentation for the abstract database adapter. #2250 [François Beausoleil ] - -* Clean up Fixtures.reset_sequences for PostgreSQL. Handle tables with no rows and models with custom primary keys. #2174, #2183 [jay@jay.fm, Blair Zajac ] - -* Improve error message when nil is assigned to an attr which validates_size_of within a range. #2022 [Manuel Holtgrewe ] - -* Make update_attribute use the same writer method that update_attributes uses. - #2237 [trevor@protocool.com] - -* Make migrations honor table name prefixes and suffixes. #2298 [Jakob S, Marcel Molina] - -* Correct and optimize PostgreSQL bytea escaping. #1745, #1837 [dave@cherryville.org, ken@miriamtech.com, bellis@deepthought.org] - -* Fixtures should only reset a PostgreSQL sequence if it corresponds to an integer primary key named id. #1749 [chris@chrisbrinker.com] - -* Standardize the interpretation of boolean columns in the Mysql and Sqlite adapters. (Use MysqlAdapter.emulate_booleans = false to disable this behavior) - -* Added new symbol-driven approach to activating observers with Base#observers= [DHH]. Example: - - ActiveRecord::Base.observers = :cacher, :garbage_collector - -* Added AbstractAdapter#select_value and AbstractAdapter#select_values as convenience methods for selecting single values, instead of hashes, of the first column in a SELECT #2283 [solo@gatelys.com] - -* Wrap :conditions in parentheses to prevent problems with OR's #1871 [Jamis Buck] - -* Allow the postgresql adapter to work with the SchemaDumper. [Jamis Buck] - -* Add ActiveRecord::SchemaDumper for dumping a DB schema to a pure-ruby file, making it easier to consolidate large migration lists and port database schemas between databases. [Jamis Buck] - -* Fixed migrations for Windows when using more than 10 [David Naseby] - -* Fixed that the create_x method from belongs_to wouldn't save the association properly #2042 [Florian Weber] - -* Fixed saving a record with two unsaved belongs_to associations pointing to the same object #2023 [Tobias Luetke] - -* Improved migrations' behavior when the schema_info table is empty. [Nicholas Seckar] - -* Fixed that Observers didn't observe sub-classes #627 [Florian Weber] - -* Fix eager loading error messages, allow :include to specify tables using strings or symbols. Closes #2222 [Marcel Molina] - -* Added check for RAILS_CONNECTION_ADAPTERS on startup and only load the connection adapters specified within if its present (available in Rails through config.connection_adapters using the new config) #1958 [skae] - -* Fixed various problems with has_and_belongs_to_many when using customer finder_sql #2094 [Florian Weber] - -* Added better exception error when unknown column types are used with migrations #1814 [fbeausoleil@ftml.net] - -* Fixed "connection lost" issue with the bundled Ruby/MySQL driver (would kill the app after 8 hours of inactivity) #2163, #428 [kajism@yahoo.com] - -* Fixed comparison of Active Record objects so two new objects are not equal #2099 [deberg] - -* Fixed that the SQL Server adapter would sometimes return DBI::Timestamp objects instead of Time #2127 [Tom Ward] - -* Added the instance methods #root and #ancestors on acts_as_tree and fixed siblings to not include the current node #2142, #2140 [coffee2code] - -* Fixed that Active Record would call SHOW FIELDS twice (or more) for the same model when the cached results were available #1947 [sd@notso.net] - -* Added log_level and use_silence parameter to ActiveRecord::Base.benchmark. The first controls at what level the benchmark statement will be logged (now as debug, instead of info) and the second that can be passed false to include all logging statements during the benchmark block/ - -* Make sure the schema_info table is created before querying the current version #1903 - -* Fixtures ignore table name prefix and suffix #1987 [Jakob S] - -* Add documentation for index_type argument to add_index method for migrations #2005 [blaine@odeo.com] - -* Modify read_attribute to allow a symbol argument #2024 [Ken Kunz] - -* Make destroy return self #1913 [sebastian.kanthak@muehlheim.de] - -* Fix typo in validations documentation #1938 [court3nay] - -* Make acts_as_list work for insert_at(1) #1966 [hensleyl@papermountain.org] - -* Fix typo in count_by_sql documentation #1969 [Alexey Verkhovsky] - -* Allow add_column and create_table to specify NOT NULL #1712 [emptysands@gmail.com] - -* Fix create_table so that id column is implicitly added [Rick Olson] - -* Default sequence names for Oracle changed to #{table_name}_seq, which is the most commonly used standard. In addition, a new method ActiveRecord::Base#set_sequence_name allows the developer to set the sequence name per model. This is a non-backwards-compatible change -- anyone using the old-style "rails_sequence" will need to either create new sequences, or set: ActiveRecord::Base.set_sequence_name = "rails_sequence" #1798 - -* OCIAdapter now properly handles synonyms, which are commonly used to separate out the schema owner from the application user #1798 - -* Fixed the handling of camelCase columns names in Oracle #1798 - -* Implemented for OCI the Rakefile tasks of :clone_structure_to_test, :db_structure_dump, and :purge_test_database, which enable Oracle folks to enjoy all the agile goodness of Rails for testing. Note that the current implementation is fairly limited -- only tables and sequences are cloned, not constraints or indexes. A full clone in Oracle generally requires some manual effort, and is version-specific. Post 9i, Oracle recommends the use of the DBMS_METADATA package, though that approach requires editing of the physical characteristics generated #1798 - -* Fixed the handling of multiple blob columns in Oracle if one or more of them are null #1798 - -* Added support for calling constrained class methods on has_many and has_and_belongs_to_many collections #1764 [Tobias Luetke] - - class Comment < AR:B - def self.search(q) - find(:all, :conditions => ["body = ?", q]) - end - end - - class Post < AR:B - has_many :comments - end - - Post.find(1).comments.search('hi') # => SELECT * from comments WHERE post_id = 1 AND body = 'hi' - - NOTICE: This patch changes the underlying SQL generated by has_and_belongs_to_many queries. If your relying on that, such as - by explicitly referencing the old t and j aliases, you'll need to update your code. Of course, you _shouldn't_ be relying on - details like that no less than you should be diving in to touch private variables. But just in case you do, consider yourself - noticed :) - -* Added migration support for SQLite (using temporary tables to simulate ALTER TABLE) #1771 [Sam Stephenson] - -* Remove extra definition of supports_migrations? from abstract_adaptor.rb [Nicholas Seckar] - -* Fix acts_as_list so that moving next-to-last item to the bottom does not result in duplicate item positions - -* Fixed incompatibility in DB2 adapter with the new limit/offset approach #1718 [Maik Schmidt] - -* Added :select option to find which can specify a different value than the default *, like find(:all, :select => "first_name, last_name"), if you either only want to select part of the columns or exclude columns otherwise included from a join #1338 [Stefan Kaes] - - -*1.11.1* (11 July, 2005) - -* Added support for limit and offset with eager loading of has_one and belongs_to associations. Using the options with has_many and has_and_belongs_to_many associations will now raise an ActiveRecord::ConfigurationError #1692 [Rick Olsen] - -* Fixed that assume_bottom_position (in acts_as_list) could be called on items already last in the list and they would move one position away from the list #1648 [tyler@kianta.com] - -* Added ActiveRecord::Base.threaded_connections flag to turn off 1-connection per thread (required for thread safety). By default it's on, but WEBrick in Rails need it off #1685 [Sam Stephenson] - -* Correct reflected table name for singular associations. #1688 [court3nay@gmail.com] - -* Fixed optimistic locking with SQL Server #1660 [tom@popdog.net] - -* Added ActiveRecord::Migrator.migrate that can figure out whether to go up or down based on the target version and the current - -* Added better error message for "packets out of order" #1630 [courtenay] - -* Fixed first run of "rake migrate" on PostgreSQL by not expecting a return value on the id #1640 - - -*1.11.0* (6 July, 2005) - -* Fixed that Yaml error message in fixtures hid the real error #1623 [Nicholas Seckar] - -* Changed logging of SQL statements to use the DEBUG level instead of INFO - -* Added new Migrations framework for describing schema transformations in a way that can be easily applied across multiple databases #1604 [Tobias Luetke] See documentation under ActiveRecord::Migration and the additional support in the Rails rakefile/generator. - -* Added callback hooks to association collections #1549 [Florian Weber]. Example: - - class Project - has_and_belongs_to_many :developers, :before_add => :evaluate_velocity - - def evaluate_velocity(developer) - ... - end - end - - ..raising an exception will cause the object not to be added (or removed, with before_remove). - - -* Fixed Base.content_columns call for SQL Server adapter #1450 [DeLynn Berry] - -* Fixed Base#write_attribute to work with both symbols and strings #1190 [Paul Legato] - -* Fixed that has_and_belongs_to_many didn't respect single table inheritance types #1081 [Florian Weber] - -* Speed up ActiveRecord#method_missing for the common case (read_attribute). - -* Only notify observers on after_find and after_initialize if these methods are defined on the model. #1235 [skaes@web.de] - -* Fixed that single-table inheritance sub-classes couldn't be used to limit the result set with eager loading #1215 [Chris McGrath] - -* Fixed validates_numericality_of to work with overrided getter-method when :allow_nil is on #1316 [raidel@onemail.at] - -* Added roots, root, and siblings to the batch of methods added by acts_as_tree #1541 [michael@schuerig.de] - -* Added support for limit/offset with the MS SQL Server driver so that pagination will now work #1569 [DeLynn Berry] - -* Added support for ODBC connections to MS SQL Server so you can connect from a non-Windows machine #1569 [Mark Imbriaco/DeLynn Berry] - -* Fixed that multiparameter posts ignored attr_protected #1532 [alec+rails@veryclever.net] - -* Fixed problem with eager loading when using a has_and_belongs_to_many association using :association_foreign_key #1504 [flash@vanklinkenbergsoftware.nl] - -* Fixed Base#find to honor the documentation on how :joins work and make them consistent with Base#count #1405 [pritchie@gmail.com]. What used to be: - - Developer.find :all, :joins => 'developers_projects', :conditions => 'id=developer_id AND project_id=1' - - ...should instead be: - - Developer.find( - :all, - :joins => 'LEFT JOIN developers_projects ON developers.id = developers_projects.developer_id', - :conditions => 'project_id=1' - ) - -* Fixed that validations didn't respecting custom setting for too_short, too_long messages #1437 [Marcel Molina] - -* Fixed that clear_association_cache doesn't delete new associations on new records (so you can safely place new records in the session with Action Pack without having new associations wiped) #1494 [cluon] - -* Fixed that calling Model.find([]) returns [] and doesn't throw an exception #1379 - -* Fixed that adding a record to a has_and_belongs_to collection would always save it -- now it only saves if its a new record #1203 [Alisdair McDiarmid] - -* Fixed saving of in-memory association structures to happen as a after_create/after_update callback instead of after_save -- that way you can add new associations in after_create/after_update callbacks without getting them saved twice - -* Allow any Enumerable, not just Array, to work as bind variables #1344 [Jeremy Kemper] - -* Added actual database-changing behavior to collection assigment for has_many and has_and_belongs_to_many #1425 [Sebastian Kanthak]. - Example: - - david.projects = [Project.find(1), Project.new("name" => "ActionWebSearch")] - david.save - - If david.projects already contain the project with ID 1, this is left unchanged. Any other projects are dropped. And the new - project is saved when david.save is called. - - Also included is a way to do assignments through IDs, which is perfect for checkbox updating, so you get to do: - - david.project_ids = [1, 5, 7] - -* Corrected typo in find SQL for has_and_belongs_to_many. #1312 [ben@bensinclair.com] - -* Fixed sanitized conditions for has_many finder method. #1281 [jackc@hylesanderson.com, pragdave, Tobias Luetke] - -* Comprehensive PostgreSQL schema support. Use the optional schema_search_path directive in database.yml to give a comma-separated list of schemas to search for your tables. This allows you, for example, to have tables in a shared schema without having to use a custom table name. See http://www.postgresql.org/docs/8.0/interactive/ddl-schemas.html to learn more. #827 [dave@cherryville.org] - -* Corrected @@configurations typo #1410 [david@ruppconsulting.com] - -* Return PostgreSQL columns in the order they were declared #1374 [perlguy@gmail.com] - -* Allow before/after update hooks to work on models using optimistic locking - -* Eager loading of dependent has_one associations won't delete the association #1212 - -* Added a second parameter to the build and create method for has_one that controls whether the existing association should be replaced (which means nullifying its foreign key as well). By default this is true, but false can be passed to prevent it. - -* Using transactional fixtures now causes the data to be loaded only once. - -* Added fixture accessor methods that can be used when instantiated fixtures are disabled. - - fixtures :web_sites - - def test_something - assert_equal "Ruby on Rails", web_sites(:rubyonrails).name - end - -* Added DoubleRenderError exception that'll be raised if render* is called twice #518 [Nicholas Seckar] - -* Fixed exceptions occuring after render has been called #1096 [Nicholas Seckar] - -* CHANGED: validates_presence_of now uses Errors#add_on_blank, which will make " " fail the validation where it didn't before #1309 - -* Added Errors#add_on_blank which works like Errors#add_on_empty, but uses Object#blank? instead - -* Added the :if option to all validations that can either use a block or a method pointer to determine whether the validation should be run or not. #1324 [Duane Johnson/jhosteny]. Examples: - - Conditional validations such as the following are made possible: - validates_numericality_of :income, :if => :employed? - - Conditional validations can also solve the salted login generator problem: - validates_confirmation_of :password, :if => :new_password? - - Using blocks: - validates_presence_of :username, :if => Proc.new { |user| user.signup_step > 1 } - -* Fixed use of construct_finder_sql when using :join #1288 [dwlt@dwlt.net] - -* Fixed that :delete_sql in has_and_belongs_to_many associations couldn't access record properties #1299 [Rick Olson] - -* Fixed that clone would break when an aggregate had the same name as one of its attributes #1307 [Jeremy Kemper] - -* Changed that destroying an object will only freeze the attributes hash, which keeps the object from having attributes changed (as that wouldn't make sense), but allows for the querying of associations after it has been destroyed. - -* Changed the callbacks such that observers are notified before the in-object callbacks are triggered. Without this change, it wasn't possible to act on the whole object in something like a before_destroy observer without having the objects own callbacks (like deleting associations) called first. - -* Added option for passing an array to the find_all version of the dynamic finders and have it evaluated as an IN fragment. Example: - - # SELECT * FROM topics WHERE title IN ('First', 'Second') - Topic.find_all_by_title(["First", "Second"]) - -* Added compatibility with camelCase column names for dynamic finders #533 [Dee.Zsombor] - -* Fixed extraneous comma in count() function that made it not work with joins #1156 [jarkko/Dee.Zsombor] - -* Fixed incompatibility with Base#find with an array of ids that would fail when using eager loading #1186 [Alisdair McDiarmid] - -* Fixed that validate_length_of lost :on option when :within was specified #1195 [jhosteny@mac.com] - -* Added encoding and min_messages options for PostgreSQL #1205 [shugo]. Configuration example: - - development: - adapter: postgresql - database: rails_development - host: localhost - username: postgres - password: - encoding: UTF8 - min_messages: ERROR - -* Fixed acts_as_list where deleting an item that was removed from the list would ruin the positioning of other list items #1197 [Jamis Buck] - -* Added validates_exclusion_of as a negative of validates_inclusion_of - -* Optimized counting of has_many associations by setting the association to empty if the count is 0 so repeated calls doesn't trigger database calls - - -*1.10.1* (20th April, 2005) - -* Fixed frivilous database queries being triggered with eager loading on empty associations and other things - -* Fixed order of loading in eager associations - -* Fixed stray comma when using eager loading and ordering together from has_many associations #1143 - - -*1.10.0* (19th April, 2005) - -* Added eager loading of associations as a way to solve the N+1 problem more gracefully without piggy-back queries. Example: - - for post in Post.find(:all, :limit => 100) - puts "Post: " + post.title - puts "Written by: " + post.author.name - puts "Last comment on: " + post.comments.first.created_on - end - - This used to generate 301 database queries if all 100 posts had both author and comments. It can now be written as: - - for post in Post.find(:all, :limit => 100, :include => [ :author, :comments ]) - - ...and the number of database queries needed is now 1. - -* Added new unified Base.find API and deprecated the use of find_first and find_all. See the documentation for Base.find. Examples: - - Person.find(1, :conditions => "administrator = 1", :order => "created_on DESC") - Person.find(1, 5, 6, :conditions => "administrator = 1", :order => "created_on DESC") - Person.find(:first, :order => "created_on DESC", :offset => 5) - Person.find(:all, :conditions => [ "category IN (?)", categories], :limit => 50) - Person.find(:all, :offset => 10, :limit => 10) - -* Added acts_as_nested_set #1000 [wschenk]. Introduction: - - This acts provides Nested Set functionality. Nested Set is similiar to Tree, but with - the added feature that you can select the children and all of it's descendants with - a single query. A good use case for this is a threaded post system, where you want - to display every reply to a comment without multiple selects. - -* Added Base.save! that attempts to save the record just like Base.save but will raise a RecordInvalid exception instead of returning false if the record is not valid [After much pestering from Dave Thomas] - -* Fixed PostgreSQL usage of fixtures with regards to public schemas and table names with dots #962 [gnuman1@gmail.com] - -* Fixed that fixtures were being deleted in the same order as inserts causing FK errors #890 [andrew.john.peters@gmail.com] - -* Fixed loading of fixtures in to be in the right order (or PostgreSQL would bark) #1047 [stephenh@chase3000.com] - -* Fixed page caching for non-vhost applications living underneath the root #1004 [Ben Schumacher] - -* Fixes a problem with the SQL Adapter which was resulting in IDENTITY_INSERT not being set to ON when it should be #1104 [adelle] - -* Added the option to specify the acceptance string in validates_acceptance_of #1106 [caleb@aei-tech.com] - -* Added insert_at(position) to acts_as_list #1083 [DeLynnB] - -* Removed the default order by id on has_and_belongs_to_many queries as it could kill performance on large sets (you can still specify by hand with :order) - -* Fixed that Base.silence should restore the old logger level when done, not just set it to DEBUG #1084 [yon@milliped.com] - -* Fixed boolean saving on Oracle #1093 [mparrish@pearware.org] - -* Moved build_association and create_association for has_one and belongs_to out of deprecation as they work when the association is nil unlike association.build and association.create, which require the association to be already in place #864 - -* Added rollbacks of transactions if they're active as the dispatcher is killed gracefully (TERM signal) #1054 [Leon Bredt] - -* Added quoting of column names for fixtures #997 [jcfischer@gmail.com] - -* Fixed counter_sql when no records exist in database for PostgreSQL (would give error, not 0) #1039 [Caleb Tennis] - -* Fixed that benchmarking times for rendering included db runtimes #987 [skaes@web.de] - -* Fixed boolean queries for t/f fields in PostgreSQL #995 [dave@cherryville.org] - -* Added that model.items.delete(child) will delete the child, not just set the foreign key to nil, if the child is dependent on the model #978 [Jeremy Kemper] - -* Fixed auto-stamping of dates (created_on/updated_on) for PostgreSQL #985 [dave@cherryville.org] - -* Fixed Base.silence/benchmark to only log if a logger has been configured #986 [skaes@web.de] - -* Added a join parameter as the third argument to Base.find_first and as the second to Base.count #426, #988 [skaes@web.de] - -* Fixed bug in Base#hash method that would treat records with the same string-based id as different [Dave Thomas] - -* Renamed DateHelper#distance_of_time_in_words_to_now to DateHelper#time_ago_in_words (old method name is still available as a deprecated alias) - - -*1.9.1* (27th March, 2005) - -* Fixed that Active Record objects with float attribute could not be cloned #808 - -* Fixed that MissingSourceFile's wasn't properly detected in production mode #925 [Nicholas Seckar] - -* Fixed that :counter_cache option would look for a line_items_count column for a LineItem object instead of lineitems_count - -* Fixed that AR exists?() would explode on postgresql if the passed id did not match the PK type #900 [Scott Barron] - -* Fixed the MS SQL adapter to work with the new limit/offset approach and with binary data (still suffering from 7KB limit, though) #901 [delynnb] - - -*1.9.0* (22th March, 2005) - -* Added adapter independent limit clause as a two-element array with the first being the limit, the second being the offset #795 [Sam Stephenson]. Example: - - Developer.find_all nil, 'id ASC', 5 # return the first five developers - Developer.find_all nil, 'id ASC', [3, 8] # return three developers, starting from #8 and forward - - This doesn't yet work with the DB2 or MS SQL adapters. Patches to make that happen are encouraged. - -* Added alias_method :to_param, :id to Base, such that Active Record objects to be used as URL parameters in Action Pack automatically #812 [Nicholas Seckar/Sam Stephenson] - -* Improved the performance of the OCI8 adapter for Oracle #723 [pilx/gjenkins] - -* Added type conversion before saving a record, so string-based values like "10.0" aren't left for the database to convert #820 [dave@cherryville.org] - -* Added with additional settings for working with transactional fixtures and pre-loaded test databases #865 [mindel] - -* Fixed acts_as_list to trigger remove_from_list on destroy after the fact, not before, so a unique position can be maintained #871 [Alisdair McDiarmid] - -* Added the possibility of specifying fixtures in multiple calls #816 [kim@tinker.com] - -* Added Base.exists?(id) that'll return true if an object of the class with the given id exists #854 [stian@grytoyr.net] - -* Added optionally allow for nil or empty strings with validates_numericality_of #801 [Sebastian Kanthak] - -* Fixed problem with using slashes in validates_format_of regular expressions #801 [Sebastian Kanthak] - -* Fixed that SQLite3 exceptions are caught and reported properly #823 [yerejm] - -* Added that all types of after_find/after_initialized callbacks are triggered if the explicit implementation is present, not only the explicit implementation itself - -* Fixed that symbols can be used on attribute assignment, like page.emails.create(:subject => data.subject, :body => data.body) - - -*1.8.0* (7th March, 2005) - -* Added ActiveRecord::Base.colorize_logging to control whether to use colors in logs or not (on by default) - -* Added support for timestamp with time zone in PostgreSQL #560 [Scott Barron] - -* Added MultiparameterAssignmentErrors and AttributeAssignmentError exceptions #777 [demetrius]. Documentation: - - * +MultiparameterAssignmentErrors+ -- collection of errors that occurred during a mass assignment using the - +attributes=+ method. The +errors+ property of this exception contains an array of +AttributeAssignmentError+ - objects that should be inspected to determine which attributes triggered the errors. - * +AttributeAssignmentError+ -- an error occurred while doing a mass assignment through the +attributes=+ method. - You can inspect the +attribute+ property of the exception object to determine which attribute triggered the error. - -* Fixed that postgresql adapter would fails when reading bytea fields with null value #771 [rodrigo k] - -* Added transactional fixtures that uses rollback to undo changes to fixtures instead of DELETE/INSERT -- it's much faster. See documentation under Fixtures #760 [Jeremy Kemper] - -* Added destruction of dependent objects in has_one associations when a new assignment happens #742 [mindel]. Example: - - class Account < ActiveRecord::Base - has_one :credit_card, :dependent => true - end - class CreditCard < ActiveRecord::Base - belongs_to :account - end - - account.credit_card # => returns existing credit card, lets say id = 12 - account.credit_card = CreditCard.create("number" => "123") - account.save # => CC with id = 12 is destroyed - - -* Added validates_numericality_of #716 [skanthak/c.r.mcgrath]. Docuemntation: - - Validates whether the value of the specified attribute is numeric by trying to convert it to - a float with Kernel.Float (if integer is false) or applying it to the regular expression - /^[\+\-]?\d+$/ (if integer is set to true). - - class Person < ActiveRecord::Base - validates_numericality_of :value, :on => :create - end - - Configuration options: - * message - A custom error message (default is: "is not a number") - * on Specifies when this validation is active (default is :save, other options :create, :update) - * only_integer Specifies whether the value has to be an integer, e.g. an integral value (default is false) - - -* Fixed that HasManyAssociation#count was using :finder_sql rather than :counter_sql if it was available #445 [Scott Barron] - -* Added better defaults for composed_of, so statements like composed_of :time_zone, :mapping => %w( time_zone time_zone ) can be written without the mapping part (it's now assumed) - -* Added MacroReflection#macro which will return a symbol describing the macro used (like :composed_of or :has_many) #718, #248 [james@slashetc.com] - - -*1.7.0* (24th February, 2005) - -* Changed the auto-timestamping feature to use ActiveRecord::Base.default_timezone instead of entertaining the parallel ActiveRecord::Base.timestamps_gmt method. The latter is now deprecated and will throw a warning on use (but still work) #710 [Jamis Buck] - -* Added a OCI8-based Oracle adapter that has been verified to work with Oracle 8 and 9 #629 [Graham Jenkins]. Usage notes: - - 1. Key generation uses a sequence "rails_sequence" for all tables. (I couldn't find a simple - and safe way of passing table-specific sequence information to the adapter.) - 2. Oracle uses DATE or TIMESTAMP datatypes for both dates and times. Consequently I have had to - resort to some hacks to get data converted to Date or Time in Ruby. - If the column_name ends in _at (like created_at, updated_at) it's created as a Ruby Time. Else if the - hours/minutes/seconds are 0, I make it a Ruby Date. Else it's a Ruby Time. - This is nasty - but if you use Duck Typing you'll probably not care very much. - In 9i it's tempting to map DATE to Date and TIMESTAMP to Time but I don't think that is - valid - too many databases use DATE for both. - Timezones and sub-second precision on timestamps are not supported. - 3. Default values that are functions (such as "SYSDATE") are not supported. This is a - restriction of the way active record supports default values. - 4. Referential integrity constraints are not fully supported. Under at least - some circumstances, active record appears to delete parent and child records out of - sequence and out of transaction scope. (Or this may just be a problem of test setup.) - - The OCI8 driver can be retrieved from http://rubyforge.org/projects/ruby-oci8/ - -* Added option :schema_order to the PostgreSQL adapter to support the use of multiple schemas per database #697 [YuriSchimke] - -* Optimized the SQL used to generate has_and_belongs_to_many queries by listing the join table first #693 [yerejm] - -* Fixed that when using validation macros with a custom message, if you happened to use single quotes in the message string you would get a parsing error #657 [tonka] - -* Fixed that Active Record would throw Broken Pipe errors with FCGI when the MySQL connection timed out instead of reconnecting #428 [Nicholas Seckar] - -* Added options to specify an SSL connection for MySQL. Define the following attributes in the connection config (config/database.yml in Rails) to use it: sslkey, sslcert, sslca, sslcapath, sslcipher. To use SSL with no client certs, just set :sslca = '/dev/null'. http://dev.mysql.com/doc/mysql/en/secure-connections.html #604 [daniel@nightrunner.com] - -* Added automatic dropping/creating of test tables for running the unit tests on all databases #587 [adelle@bullet.net.au] - -* Fixed that find_by_* would fail when column names had numbers #670 [demetrius] - -* Fixed the SQL Server adapter on a bunch of issues #667 [DeLynn] - - 1. Created a new columns method that is much cleaner. - 2. Corrected a problem with the select and select_all methods - that didn't account for the LIMIT clause being passed into raw SQL statements. - 3. Implemented the string_to_time method in order to create proper instances of the time class. - 4. Added logic to the simplified_type method that allows the database to specify the scale of float data. - 5. Adjusted the quote_column_name to account for the fact that MS SQL is bothered by a forward slash in the data string. - -* Fixed that the dynamic finder like find_all_by_something_boolean(false) didn't work #649 [lmarlow@yahoo.com] - -* Added validates_each that validates each specified attribute against a block #610 [Jeremy Kemper]. Example: - - class Person < ActiveRecord::Base - validates_each :first_name, :last_name do |record, attr| - record.errors.add attr, 'starts with z.' if attr[0] == ?z - end - end - -* Added :allow_nil as an explicit option for validates_length_of, so unless that's set to true having the attribute as nil will also return an error if a range is specified as :within #610 [Jeremy Kemper] - -* Added that validates_* now accept blocks to perform validations #618 [Tim Bates]. Example: - - class Person < ActiveRecord::Base - validate { |person| person.errors.add("title", "will never be valid") if SHOULD_NEVER_BE_VALID } - end - -* Addded validation for validate all the associated objects before declaring failure with validates_associated #618 [Tim Bates] - -* Added keyword-style approach to defining the custom relational bindings #545 [Jamis Buck]. Example: - - class Project < ActiveRecord::Base - primary_key "sysid" - table_name "XYZ_PROJECT" - inheritance_column { original_inheritance_column + "_id" } - end - -* Fixed Base#clone for use with PostgreSQL #565 [hanson@surgery.wisc.edu] - - -*1.6.0* (January 25th, 2005) - -* Added that has_many association build and create methods can take arrays of record data like Base#create and Base#build to build/create multiple records at once. - -* Added that Base#delete and Base#destroy both can take an array of ids to delete/destroy #336 - -* Added the option of supplying an array of attributes to Base#create, so that multiple records can be created at once. - -* Added the option of supplying an array of ids and attributes to Base#update, so that multiple records can be updated at once (inspired by #526/Duane Johnson). Example - - people = { 1 => { "first_name" => "David" }, 2 => { "first_name" => "Jeremy"} } - Person.update(people.keys, people.values) - -* Added ActiveRecord::Base.timestamps_gmt that can be set to true to make the automated timestamping use GMT instead of local time #520 [Scott Baron] - -* Added that update_all calls sanitize_sql on its updates argument, so stuff like MyRecord.update_all(['time = ?', Time.now]) works #519 [notahat] - -* Fixed that the dynamic finders didn't treat nil as a "IS NULL" but rather "= NULL" case #515 [Demetrius] - -* Added bind-named arrays for interpolating a group of ids or strings in conditions #528 [Jeremy Kemper] - -* Added that has_and_belongs_to_many associations with additional attributes also can be created between unsaved objects and only committed to the database when Base#save is called on the associator #524 [Eric Anderson] - -* Fixed that records fetched with piggy-back attributes or through rich has_and_belongs_to_many associations couldn't be saved due to the extra attributes not part of the table #522 [Eric Anderson] - -* Added mass-assignment protection for the inheritance column -- regardless of a custom column is used or not - -* Fixed that association proxies would fail === tests like PremiumSubscription === @account.subscription - -* Fixed that column aliases didn't work as expected with the new MySql411 driver #507 [Demetrius] - -* Fixed that find_all would produce invalid sql when called sequentialy #490 [Scott Baron] - - -*1.5.1* (January 18th, 2005) - -* Fixed that the belongs_to and has_one proxy would fail a test like 'if project.manager' -- this unfortunately also means that you can't call methods like project.manager.build unless there already is a manager on the project #492 [Tim Bates] - -* Fixed that the Ruby/MySQL adapter wouldn't connect if the password was empty #503 [Pelle] - - -*1.5.0* (January 17th, 2005) - -* Fixed that unit tests for MySQL are now run as the "rails" user instead of root #455 [Eric Hodel] - -* Added validates_associated that enables validation of objects in an unsaved association #398 [Tim Bates]. Example: - - class Book < ActiveRecord::Base - has_many :pages - belongs_to :library - - validates_associated :pages, :library - end - -* Added support for associating unsaved objects #402 [Tim Bates]. Rules that govern this addition: - - == Unsaved objects and associations - - You can manipulate objects and associations before they are saved to the database, but there is some special behaviour you should be - aware of, mostly involving the saving of associated objects. - - === One-to-one associations - - * Assigning an object to a has_one association automatically saves that object, and the object being replaced (if there is one), in - order to update their primary keys - except if the parent object is unsaved (new_record? == true). - * If either of these saves fail (due to one of the objects being invalid) the assignment statement returns false and the assignment - is cancelled. - * If you wish to assign an object to a has_one association without saving it, use the #association.build method (documented below). - * Assigning an object to a belongs_to association does not save the object, since the foreign key field belongs on the parent. It does - not save the parent either. - - === Collections - - * Adding an object to a collection (has_many or has_and_belongs_to_many) automatically saves that object, except if the parent object - (the owner of the collection) is not yet stored in the database. - * If saving any of the objects being added to a collection (via #push or similar) fails, then #push returns false. - * You can add an object to a collection without automatically saving it by using the #collection.build method (documented below). - * All unsaved (new_record? == true) members of the collection are automatically saved when the parent is saved. - -* Added replace to associations, so you can do project.manager.replace(new_manager) or project.milestones.replace(new_milestones) #402 [Tim Bates] - -* Added build and create methods to has_one and belongs_to associations, so you can now do project.manager.build(attributes) #402 [Tim Bates] - -* Added that if a before_* callback returns false, all the later callbacks and the associated action are cancelled. If an after_* callback returns false, all the later callbacks are cancelled. Callbacks are generally run in the order they are defined, with the exception of callbacks defined as methods on the model, which are called last. #402 [Tim Bates] - -* Fixed that Base#== wouldn't work for multiple references to the same unsaved object #402 [Tim Bates] - -* Fixed binary support for PostgreSQL #444 [alex@byzantine.no] - -* Added a differenciation between AssociationCollection#size and -length. Now AssociationCollection#size returns the size of the - collection by executing a SELECT COUNT(*) query if the collection hasn't been loaded and calling collection.size if it has. If - it's more likely than not that the collection does have a size larger than zero and you need to fetch that collection afterwards, - it'll take one less SELECT query if you use length. - -* Added Base#attributes that returns a hash of all the attributes with their names as keys and clones of their objects as values #433 [atyp.de] - -* Fixed that foreign keys named the same as the association would cause stack overflow #437 [Eric Anderson] - -* Fixed default scope of acts_as_list from "1" to "1 = 1", so it'll work in PostgreSQL (among other places) #427 [Alexey] - -* Added Base#reload that reloads the attributes of an object from the database #422 [Andreas Schwarz] - -* Added SQLite3 compatibility through the sqlite3-ruby adapter by Jamis Buck #381 [Jeremy Kemper] - -* Added support for the new protocol spoken by MySQL 4.1.1+ servers for the Ruby/MySQL adapter that ships with Rails #440 [Matt Mower] - -* Added that Observers can use the observes class method instead of overwriting self.observed_class(). - - Before: - class ListSweeper < ActiveRecord::Base - def self.observed_class() [ List, Item ] - end - - After: - class ListSweeper < ActiveRecord::Base - observes List, Item - end - -* Fixed that conditions in has_many and has_and_belongs_to_many should be interpolated just like the finder_sql is - -* Fixed Base#update_attribute to be indifferent to whether a string or symbol is used to describe the name - -* Added Base#toggle(attribute) and Base#toggle!(attribute) that makes it easier to flip a switch or flag. - - Before: topic.update_attribute(:approved, !approved?) - After : topic.toggle!(:approved) - -* Added Base#increment!(attribute) and Base#decrement!(attribute) that also saves the records. Example: - - page.views # => 1 - page.increment!(:views) # executes an UPDATE statement - page.views # => 2 - - page.increment(:views).increment!(:views) - page.views # => 4 - -* Added Base#increment(attribute) and Base#decrement(attribute) that encapsulates the += 1 and -= 1 patterns. - - -*1.4.0* (January 4th, 2005) - -* Added automated optimistic locking if the field lock_version is present. Each update to the - record increments the lock_version column and the locking facilities ensure that records instantiated twice - will let the last one saved raise a StaleObjectError if the first was also updated. Example: - - p1 = Person.find(1) - p2 = Person.find(1) - - p1.first_name = "Michael" - p1.save - - p2.first_name = "should fail" - p2.save # Raises a ActiveRecord::StaleObjectError - - You're then responsible for dealing with the conflict by rescuing the exception and either rolling back, merging, - or otherwise apply the business logic needed to resolve the conflict. - - #384 [Michael Koziarski] - -* Added dynamic attribute-based finders as a cleaner way of getting objects by simple queries without turning to SQL. - They work by appending the name of an attribute to find_by_, so you get finders like Person.find_by_user_name, - Payment.find_by_transaction_id. So instead of writing Person.find_first(["user_name = ?", user_name]), you just do - Person.find_by_user_name(user_name). - - It's also possible to use multiple attributes in the same find by separating them with "_and_", so you get finders like - Person.find_by_user_name_and_password or even Payment.find_by_purchaser_and_state_and_country. So instead of writing - Person.find_first(["user_name = ? AND password = ?", user_name, password]), you just do - Person.find_by_user_name_and_password(user_name, password). - - While primarily a construct for easier find_firsts, it can also be used as a construct for find_all by using calls like - Payment.find_all_by_amount(50) that is turned into Payment.find_all(["amount = ?", 50]). This is something not as equally useful, - though, as it's not possible to specify the order in which the objects are returned. - -* Added block-style for callbacks #332 [Jeremy Kemper]. - - Before: - before_destroy(Proc.new{ |record| Person.destroy_all "firm_id = #{record.id}" }) - - After: - before_destroy { |record| Person.destroy_all "firm_id = #{record.id}" } - -* Added :counter_cache option to acts_as_tree that works just like the one you can define on belongs_to #371 [Josh] - -* Added Base.default_timezone accessor that determines whether to use Time.local (using :local) or Time.utc (using :utc) when pulling dates - and times from the database. This is set to :local by default. - -* Added the possibility for adapters to overwrite add_limit! to implement a different limiting scheme than "LIMIT X" used by MySQL, PostgreSQL, and SQLite. - -* Added the possibility of having objects with acts_as_list created before their scope is available or... - -* Added a db2 adapter that only depends on the Ruby/DB2 bindings (http://raa.ruby-lang.org/project/ruby-db2/) #386 [Maik Schmidt] - -* Added the final touches to the Microsoft SQL Server adapter by Joey Gibson that makes it suitable for actual use #394 [DeLynn Barry] - -* Added that Base#find takes an optional options hash, including :conditions. Base#find_on_conditions deprecated in favor of #find with :conditions #407 [Jeremy Kemper] - -* Added HasManyAssociation#count that works like Base#count #413 [intinig] - -* Fixed handling of binary content in blobs and similar fields for Ruby/MySQL and SQLite #409 [xal] - -* Fixed a bug in the Ruby/MySQL that caused binary content to be escaped badly and come back mangled #405 [Tobias Luetke] - -* Fixed that the const_missing autoload assumes the requested constant is set by require_association and calls const_get to retrieve it. - If require_association did not set the constant then const_get will call const_missing, resulting in an infinite loop #380 [Jeremy Kemper] - -* Fixed broken transactions that were actually only running object-level and not db level transactions [andreas] - -* Fixed that validates_uniqueness_of used 'id' instead of defined primary key #406 - -* Fixed that the overwritten respond_to? method didn't take two parameters like the original #391 - -* Fixed quoting in validates_format_of that would allow some rules to pass regardless of input #390 [Dmitry V. Sabanin] - - -*1.3.0* (December 23, 2004) - -* Added a require_association hook on const_missing that makes it possible to use any model class without requiring it first. This makes STI look like: - - before: - require_association 'person' - class Employee < Person - end - - after: - class Employee < Person - end - - This also reduces the usefulness of Controller.model in Action Pack to currently only being for documentation purposes. - -* Added that Base.update_all and Base.delete_all return an integer of the number of affected rows #341 - -* Added scope option to validation_uniqueness #349 [Kent Sibilev] - -* Added respondence to *_before_type_cast for all attributes to return their string-state before they were type casted by the column type. - This is helpful for getting "100,000" back on a integer-based validation where the value would normally be "100". - -* Added allow_nil options to validates_inclusion_of so that validation is only triggered if the attribute is not nil [what-a-day] - -* Added work-around for PostgreSQL and the problem of getting fixtures to be created from id 1 on each test case. - This only works for auto-incrementing primary keys called "id" for now #359 [Scott Baron] - -* Added Base#clear_association_cache to empty all the cached associations #347 [Tobias Luetke] - -* Added more informative exceptions in establish_connection #356 [Jeremy Kemper] - -* Added Base#update_attributes that'll accept a hash of attributes and save the record (returning true if it passed validation, false otherwise). - - Before: - person.attributes = @params["person"] - person.save - - Now: - person.update_attributes(@params["person"]) - -* Added Base.destroy and Base.delete to remove records without holding a reference to them first. - -* Added that query benchmarking will only happen if its going to be logged anyway #344 - -* Added higher_item and lower_item as public methods for acts_as_list #342 [Tobias Luetke] - -* Fixed that options[:counter_sql] was overwritten with interpolated sql rather than original sql #355 [Jeremy Kemper] - -* Fixed that overriding an attribute's accessor would be disregarded by add_on_empty and add_on_boundary_breaking because they simply used - the attributes[] hash instead of checking for @base.respond_to?(attr.to_s). [Marten] - -* Fixed that Base.table_name would expect a parameter when used in has_and_belongs_to_many joins [Anna Lissa Cruz] - -* Fixed that nested transactions now work by letting the outer most transaction have the responsibilty of starting and rolling back the transaction. - If any of the inner transactions swallow the exception raised, though, the transaction will not be rolled back. So always let the transaction - bubble up even when you've dealt with local issues. Closes #231 and #340. - -* Fixed validates_{confirmation,acceptance}_of to only happen when the virtual attributes are not nil #348 [dpiddy@gmail.com] - -* Changed the interface on AbstractAdapter to require that adapters return the number of affected rows on delete and update operations. - -* Fixed the automated timestamping feature when running under Rails' development environment that resets the inheritable attributes on each request. - - - -*1.2.0* - -* Added Base.validates_inclusion_of that validates whether the value of the specified attribute is available in a particular enumerable - object. [what-a-day] - - class Person < ActiveRecord::Base - validates_inclusion_of :gender, :in=>%w( m f ), :message=>"woah! what are you then!??!!" - validates_inclusion_of :age, :in=>0..99 - end - -* Added acts_as_list that can decorates an existing class with methods like move_higher/lower, move_to_top/bottom. [Tobias Luetke] Example: - - class TodoItem < ActiveRecord::Base - acts_as_list :scope => :todo_list_id - belongs_to :todo_list - end - -* Added acts_as_tree that can decorates an existing class with a many to many relationship with itself. Perfect for categories in - categories and the likes. [Tobias Luetke] - -* Added that Active Records will automatically record creation and/or update timestamps of database objects if fields of the names - created_at/created_on or updated_at/updated_on are present. [Tobias Luetke] - -* Added Base.default_error_messages as a hash of all the error messages used in the validates_*_of so they can be changed in one place [Tobias Luetke] - -* Added automatic transaction block around AssociationCollection.<<, AssociationCollection.delete, and AssociationCollection.destroy_all - -* Fixed that Base#find will return an array if given an array -- regardless of the number of elements #270 [Marten] - -* Fixed that has_and_belongs_to_many would generate bad sql when naming conventions differed from using vanilla "id" everywhere [RedTerror] - -* Added a better exception for when a type column is used in a table without the intention of triggering single-table inheritance. Example: - - ActiveRecord::SubclassNotFound: The single-table inheritance mechanism failed to locate the subclass: 'bad_class!'. - This error is raised because the column 'type' is reserved for storing the class in case of inheritance. - Please rename this column if you didn't intend it to be used for storing the inheritance class or - overwrite Company.inheritance_column to use another column for that information. - -* Added that single-table inheritance will only kick in if the inheritance_column (by default "type") is present. Otherwise, inheritance won't - have any magic side effects. - -* Added the possibility of marking fields as being in error without adding a message (using nil) to it that'll get displayed wth full_messages #208 [mjobin] - -* Fixed Base.errors to be indifferent as to whether strings or symbols are used. Examples: - - Before: - errors.add(:name, "must be shorter") if name.size > 10 - errors.on(:name) # => "must be shorter" - errors.on("name") # => nil - - After: - errors.add(:name, "must be shorter") if name.size > 10 - errors.on(:name) # => "must be shorter" - errors.on("name") # => "must be shorter" - -* Added Base.validates_format_of that Validates whether the value of the specified attribute is of the correct form by matching - it against the regular expression provided. [Marcel] - - class Person < ActiveRecord::Base - validates_format_of :email, :with => /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/, :on => :create - end - -* Added Base.validates_length_of that delegates to add_on_boundary_breaking #312 [Tobias Luetke]. Example: - - Validates that the specified attribute matches the length restrictions supplied in either: - - - configuration[:minimum] - - configuration[:maximum] - - configuration[:is] - - configuration[:within] (aka. configuration[:in]) - - Only one option can be used at a time. - - class Person < ActiveRecord::Base - validates_length_of :first_name, :maximum=>30 - validates_length_of :last_name, :maximum=>30, :message=>"less than %d if you don't mind" - validates_length_of :user_name, :within => 6..20, :too_long => "pick a shorter name", :too_short => "pick a longer name" - validates_length_of :fav_bra_size, :minimum=>1, :too_short=>"please enter at least %d character" - validates_length_of :smurf_leader, :is=>4, :message=>"papa is spelled with %d characters... don't play me." - end - -* Added Base.validate_presence as an alternative to implementing validate and doing errors.add_on_empty yourself. - -* Added Base.validates_uniqueness_of that alidates whether the value of the specified attributes are unique across the system. - Useful for making sure that only one user can be named "davidhh". - - class Person < ActiveRecord::Base - validates_uniqueness_of :user_name - end - - When the record is created, a check is performed to make sure that no record exist in the database with the given value for the specified - attribute (that maps to a column). When the record is updated, the same check is made but disregarding the record itself. - - -* Added Base.validates_confirmation_of that encapsulates the pattern of wanting to validate a password or email address field with a confirmation. Example: - - Model: - class Person < ActiveRecord::Base - validates_confirmation_of :password - end - - View: - <%= password_field "person", "password" %> - <%= password_field "person", "password_confirmation" %> - - The person has to already have a password attribute (a column in the people table), but the password_confirmation is virtual. - It exists only as an in-memory variable for validating the password. This check is performed both on create and update. - - -* Added Base.validates_acceptance_of that encapsulates the pattern of wanting to validate the acceptance of a terms of service check box (or similar agreement). Example: - - class Person < ActiveRecord::Base - validates_acceptance_of :terms_of_service - end - - The terms_of_service attribute is entirely virtual. No database column is needed. This check is performed both on create and update. - - NOTE: The agreement is considered valid if it's set to the string "1". This makes it easy to relate it to an HTML checkbox. - - -* Added validation macros to make the stackable just like the lifecycle callbacks. Examples: - - class Person < ActiveRecord::Base - validate { |record| record.errors.add("name", "too short") unless name.size > 10 } - validate { |record| record.errors.add("name", "too long") unless name.size < 20 } - validate_on_create :validate_password - - private - def validate_password - errors.add("password", "too short") unless password.size > 6 - end - end - -* Added the option for sanitizing find_by_sql and the offset parts in regular finds [Sam Stephenson]. Examples: - - Project.find_all ["category = ?", category_name], "created ASC", ["? OFFSET ?", 15, 20] - Post.find_by_sql ["SELECT * FROM posts WHERE author = ? AND created > ?", author_id, start_date] - -* Fixed value quoting in all generated SQL statements, so that integers are not surrounded in quotes and that all sanitation are happening - through the database's own quoting routine. This should hopefully make it lots easier for new adapters that doesn't accept '1' for integer - columns. - -* Fixed has_and_belongs_to_many guessing of foreign key so that keys are generated correctly for models like SomeVerySpecialClient - [Florian Weber] - -* Added counter_sql option for has_many associations [Jeremy Kemper]. Documentation: - - :counter_sql - specify a complete SQL statement to fetch the size of the association. If +:finder_sql+ is - specified but +:counter_sql+, +:counter_sql+ will be generated by replacing SELECT ... FROM with SELECT COUNT(*) FROM. - -* Fixed that methods wrapped in callbacks still return their original result #260 [Jeremy Kemper] - -* Fixed the Inflector to handle the movie/movies pair correctly #261 [Scott Baron] - -* Added named bind-style variable interpolation #281 [Michael Koziarski]. Example: - - Person.find(["id = :id and first_name = :first_name", { :id => 5, :first_name = "bob' or 1=1" }]) - -* Added bind-style variable interpolation for the condition arrays that uses the adapter's quote method [Michael Koziarski] - - Before: - find_first([ "user_name = '%s' AND password = '%s'", user_name, password ])] - find_first([ "firm_id = %s", firm_id ])] # unsafe! - - After: - find_first([ "user_name = ? AND password = ?", user_name, password ])] - find_first([ "firm_id = ?", firm_id ])] - -* Added CSV format for fixtures #272 [what-a-day]. (See the new and expanded documentation on fixtures for more information) - -* Fixed fixtures using primary key fields called something else than "id" [dave] - -* Added proper handling of time fields that are turned into Time objects with the dummy date of 2000/1/1 [HariSeldon] - -* Added reverse order of deleting fixtures, so referential keys can be maintained #247 [Tim Bates] - -* Added relative path search for sqlite dbfiles in database.yml (if RAILS_ROOT is defined) #233 [Jeremy Kemper] - -* Added option to establish_connection where you'll be able to leave out the parameter to have it use the RAILS_ENV environment variable - -* Fixed problems with primary keys and postgresql sequences (#230) [Tim Bates] - -* Added reloading for associations under cached environments like FastCGI and mod_ruby. This makes it possible to use those environments for development. - This is turned on by default, but can be turned off with ActiveRecord::Base.reload_dependencies = false in production environments. - - NOTE: This will only have an effect if you let the associations manage the requiring of model classes. All libraries loaded through - require will be "forever" cached. You can, however, use ActiveRecord::Base.load_or_require("library") to get this behavior outside of the - auto-loading associations. - -* Added ERB capabilities to the fixture files for dynamic fixture generation. You don't need to do anything, just include ERB blocks like: - - david: - id: 1 - name: David - - jamis: - id: 2 - name: Jamis - - <% for digit in 3..10 %> - dev_<%= digit %>: - id: <%= digit %> - name: fixture_<%= digit %> - <% end %> - -* Changed the yaml fixture searcher to look in the root of the fixtures directory, so when you before could have something like: - - fixtures/developers/fixtures.yaml - fixtures/accounts/fixtures.yaml - - ...you now need to do: - - fixtures/developers.yaml - fixtures/accounts.yaml - -* Changed the fixture format from: - - name: david - data: - id: 1 - name: David Heinemeier Hansson - birthday: 1979-10-15 - profession: Systems development - --- - name: steve - data: - id: 2 - name: Steve Ross Kellock - birthday: 1974-09-27 - profession: guy with keyboard - - ...to: - - david: - id: 1 - name: David Heinemeier Hansson - birthday: 1979-10-15 - profession: Systems development - - steve: - id: 2 - name: Steve Ross Kellock - birthday: 1974-09-27 - profession: guy with keyboard - - The change is NOT backwards compatible. Fixtures written in the old YAML style needs to be rewritten! - -* All associations will now attempt to require the classes that they associate to. Relieving the need for most explicit 'require' statements. - - -*1.1.0* (34) - -* Added automatic fixture setup and instance variable availability. Fixtures can also be automatically - instantiated in instance variables relating to their names using the following style: - - class FixturesTest < Test::Unit::TestCase - fixtures :developers # you can add more with comma separation - - def test_developers - assert_equal 3, @developers.size # the container for all the fixtures is automatically set - assert_kind_of Developer, @david # works like @developers["david"].find - assert_equal "David Heinemeier Hansson", @david.name - end - end - -* Added HasAndBelongsToManyAssociation#push_with_attributes(object, join_attributes) that can create associations in the join table with additional - attributes. This is really useful when you have information that's only relevant to the join itself, such as a "added_on" column for an association - between post and category. The added attributes will automatically be injected into objects retrieved through the association similar to the piggy-back - approach: - - post.categories.push_with_attributes(category, :added_on => Date.today) - post.categories.first.added_on # => Date.today - - NOTE: The categories table doesn't have a added_on column, it's the categories_post join table that does! - -* Fixed that :exclusively_dependent and :dependent can't be activated at the same time on has_many associations [Jeremy Kemper] - -* Fixed that database passwords couldn't be all numeric [Jeremy Kemper] - -* Fixed that calling id would create the instance variable for new_records preventing them from being saved correctly [Jeremy Kemper] - -* Added sanitization feature to HasManyAssociation#find_all so it works just like Base.find_all [Sam Stephenson/bitsweat] - -* Added that you can pass overlapping ids to find without getting duplicated records back [Jeremy Kemper] - -* Added that Base.benchmark returns the result of the block [Jeremy Kemper] - -* Fixed problem with unit tests on Windows with SQLite [paterno] - -* Fixed that quotes would break regular non-yaml fixtures [Dmitry Sabanin/daft] - -* Fixed fixtures on windows with line endings cause problems under unix / mac [Tobias Luetke] - -* Added HasAndBelongsToManyAssociation#find(id) that'll search inside the collection and find the object or record with that id - -* Added :conditions option to has_and_belongs_to_many that works just like the one on all the other associations - -* Added AssociationCollection#clear to remove all associations from has_many and has_and_belongs_to_many associations without destroying the records [geech] - -* Added type-checking and remove in 1-instead-of-N sql statements to AssociationCollection#delete [geech] - -* Added a return of self to AssociationCollection#<< so appending can be chained, like project << Milestone.create << Milestone.create [geech] - -* Added Base#hash and Base#eql? which means that all of the equality using features of array and other containers now works: - - [ Person.find(1), Person.find(2), Person.find(3) ] & [ Person.find(1), Person.find(4) ] # => [ Person.find(1) ] - -* Added :uniq as an option to has_and_belongs_to_many which will automatically ensure that AssociateCollection#uniq is called - before pulling records out of the association. This is especially useful for three-way (and above) has_and_belongs_to_many associations. - -* Added AssociateCollection#uniq which is especially useful for has_and_belongs_to_many associations that can include duplicates, - which is common on associations that also use metadata. Usage: post.categories.uniq - -* Fixed respond_to? to use a subclass specific hash instead of an Active Record-wide one - -* Fixed has_and_belongs_to_many to treat associations between classes in modules properly [Florian Weber] - -* Added a NoMethod exception to be raised when query and writer methods are called for attributes that doesn't exist [geech] - -* Added a more robust version of Fixtures that throws meaningful errors when on formatting issues [geech] - -* Added Base#transaction as a compliment to Base.transaction for prettier use in instance methods [geech] - -* Improved the speed of respond_to? by placing the dynamic methods lookup table in a hash [geech] - -* Added that any additional fields added to the join table in a has_and_belongs_to_many association - will be placed as attributes when pulling records out through has_and_belongs_to_many associations. - This is helpful when have information about the association itself that you want available on retrival. - -* Added better loading exception catching and RubyGems retries to the database adapters [alexeyv] - -* Fixed bug with per-model transactions [daniel] - -* Fixed Base#transaction so that it returns the result of the last expression in the transaction block [alexeyv] - -* Added Fixture#find to find the record corresponding to the fixture id. The record - class name is guessed by using Inflector#classify (also new) on the fixture directory name. - - Before: Document.find(@documents["first"]["id"]) - After : @documents["first"].find - -* Fixed that the table name part of column names ("TABLE.COLUMN") wasn't removed properly [Andreas Schwarz] - -* Fixed a bug with Base#size when a finder_sql was used that didn't capitalize SELECT and FROM [geech] - -* Fixed quoting problems on SQLite by adding quote_string to the AbstractAdapter that can be overwritten by the concrete - adapters for a call to the dbm. [Andreas Schwarz] - -* Removed RubyGems backup strategy for requiring SQLite-adapter -- if people want to use gems, they're already doing it with AR. - - -*1.0.0 (35)* - -* Added OO-style associations methods [Florian Weber]. Examples: - - Project#milestones_count => Project#milestones.size - Project#build_to_milestones => Project#milestones.build - Project#create_for_milestones => Project#milestones.create - Project#find_in_milestones => Project#milestones.find - Project#find_all_in_milestones => Project#milestones.find_all - -* Added serialize as a new class method to control when text attributes should be YAMLized or not. This means that automated - serialization of hashes, arrays, and so on WILL NO LONGER HAPPEN (#10). You need to do something like this: - - class User < ActiveRecord::Base - serialize :settings - end - - This will assume that settings is a text column and will now YAMLize any object put in that attribute. You can also specify - an optional :class_name option that'll raise an exception if a serialized object is retrieved as a descendent of a class not in - the hierarchy. Example: - - class User < ActiveRecord::Base - serialize :settings, :class_name => "Hash" - end - - user = User.create("settings" => %w( one two three )) - User.find(user.id).settings # => raises SerializationTypeMismatch - -* Added the option to connect to a different database for one model at a time. Just call establish_connection on the class - you want to have connected to another database than Base. This will automatically also connect decendents of that class - to the different database [Renald Buter]. - -* Added transactional protection for Base#save. Validations can now check for values knowing that it happens in a transaction and callbacks - can raise exceptions knowing that the save will be rolled back. [Suggested by Alexey Verkhovsky] - -* Added column name quoting so reserved words, such as "references", can be used as column names [Ryan Platte] - -* Added the possibility to chain the return of what happened inside a logged block [geech]: - - This now works: - log { ... }.map { ... } - - Instead of doing: - result = [] - log { result = ... } - result.map { ... } - -* Added "socket" option for the MySQL adapter, so you can change it to something else than "/tmp/mysql.sock" [Anna Lissa Cruz] - -* Added respond_to? answers for all the attribute methods. So if Person has a name attribute retrieved from the table schema, - person.respond_to? "name" will return true. - -* Added Base.benchmark which can be used to aggregate logging and benchmark, so you can measure and represent multiple statements in a single block. - Usage (hides all the SQL calls for the individual actions and calculates total runtime for them all): - - Project.benchmark("Creating project") do - project = Project.create("name" => "stuff") - project.create_manager("name" => "David") - project.milestones << Milestone.find_all - end - -* Added logging of invalid SQL statements [Suggested by Daniel Von Fange] - -* Added alias Errors#[] for Errors#on, so you can now say person.errors["name"] to retrieve the errors for name [Andreas Schwarz] - -* Added RubyGems require attempt if sqlite-ruby is not available through regular methods. - -* Added compatibility with 2.x series of sqlite-ruby drivers. [Jamis Buck] - -* Added type safety for association assignments, so a ActiveRecord::AssociationTypeMismatch will be raised if you attempt to - assign an object that's not of the associated class. This cures the problem with nil giving id = 4 and fixnums giving id = 1 on - mistaken association assignments. [Reported by Andreas Schwarz] - -* Added the option to keep many fixtures in one single YAML document [what-a-day] - -* Added the class method "inheritance_column" that can be overwritten to return the name of an alternative column than "type" for storing - the type for inheritance hierarchies. [Dave Steinberg] - -* Added [] and []= as an alternative way to access attributes when the regular methods have been overwritten [Dave Steinberg] - -* Added the option to observer more than one class at the time by specifying observed_class as an array - -* Added auto-id propagation support for tables with arbitrary primary keys that have autogenerated sequences associated with them - on PostgreSQL. [Dave Steinberg] - -* Changed that integer and floats set to "" through attributes= remain as NULL. This was especially a problem for scaffolding and postgresql. (#49) - -* Changed the MySQL Adapter to rely on MySQL for its defaults for socket, host, and port [Andreas Schwarz] - -* Changed ActionControllerError to decent from StandardError instead of Exception. It can now be caught by a generic rescue. - -* Changed class inheritable attributes to not use eval [Caio Chassot] - -* Changed Errors#add to now use "invalid" as the default message instead of true, which means full_messages work with those [Marcel Molina Jr] - -* Fixed spelling on Base#add_on_boundry_breaking to Base#add_on_boundary_breaking (old naming still works) [Marcel Molina Jr.] - -* Fixed that entries in the has_and_belongs_to_many join table didn't get removed when an associated object was destroyed. - -* Fixed unnecessary calls to SET AUTOCOMMIT=0/1 for MySQL adapter [Andreas Schwarz] - -* Fixed PostgreSQL defaults are now handled gracefully [Dave Steinberg] - -* Fixed increment/decrement_counter are now atomic updates [Andreas Schwarz] - -* Fixed the problems the Inflector had turning Attachment into attuchments and Cases into Casis [radsaq/Florian Gross] - -* Fixed that cloned records would point attribute references on the parent object [Andreas Schwarz] - -* Fixed SQL for type call on inheritance hierarchies [Caio Chassot] - -* Fixed bug with typed inheritance [Florian Weber] - -* Fixed a bug where has_many collection_count wouldn't use the conditions specified for that association - - -*0.9.5* - -* Expanded the table_name guessing rules immensely [Florian Green]. Documentation: - - Guesses the table name (in forced lower-case) based on the name of the class in the inheritance hierarchy descending - directly from ActiveRecord. So if the hierarchy looks like: Reply < Message < ActiveRecord, then Message is used - to guess the table name from even when called on Reply. The guessing rules are as follows: - * Class name ends in "x", "ch" or "ss": "es" is appended, so a Search class becomes a searches table. - * Class name ends in "y" preceded by a consonant or "qu": The "y" is replaced with "ies", - so a Category class becomes a categories table. - * Class name ends in "fe": The "fe" is replaced with "ves", so a Wife class becomes a wives table. - * Class name ends in "lf" or "rf": The "f" is replaced with "ves", so a Half class becomes a halves table. - * Class name ends in "person": The "person" is replaced with "people", so a Salesperson class becomes a salespeople table. - * Class name ends in "man": The "man" is replaced with "men", so a Spokesman class becomes a spokesmen table. - * Class name ends in "sis": The "i" is replaced with an "e", so a Basis class becomes a bases table. - * Class name ends in "tum" or "ium": The "um" is replaced with an "a", so a Datum class becomes a data table. - * Class name ends in "child": The "child" is replaced with "children", so a NodeChild class becomes a node_children table. - * Class name ends in an "s": No additional characters are added or removed. - * Class name doesn't end in "s": An "s" is appended, so a Comment class becomes a comments table. - * Class name with word compositions: Compositions are underscored, so CreditCard class becomes a credit_cards table. - Additionally, the class-level table_name_prefix is prepended to the table_name and the table_name_suffix is appended. - So if you have "myapp_" as a prefix, the table name guess for an Account class becomes "myapp_accounts". - - You can also overwrite this class method to allow for unguessable links, such as a Mouse class with a link to a - "mice" table. Example: - - class Mouse < ActiveRecord::Base - def self.table_name() "mice" end - end - - This conversion is now done through an external class called Inflector residing in lib/active_record/support/inflector.rb. - -* Added find_all_in_collection to has_many defined collections. Works like this: - - class Firm < ActiveRecord::Base - has_many :clients - end - - firm.id # => 1 - firm.find_all_in_clients "revenue > 1000" # SELECT * FROM clients WHERE firm_id = 1 AND revenue > 1000 - - [Requested by Dave Thomas] - -* Fixed finders for inheritance hierarchies deeper than one level [Florian Weber] - -* Added add_on_boundry_breaking to errors to accompany add_on_empty as a default validation method. It's used like this: - - class Person < ActiveRecord::Base - protected - def validation - errors.add_on_boundry_breaking "password", 3..20 - end - end - - This will add an error to the tune of "is too short (min is 3 characters)" or "is too long (min is 20 characters)" if - the password is outside the boundry. The messages can be changed by passing a third and forth parameter as message strings. - -* Implemented a clone method that works properly with AR. It returns a clone of the record that - hasn't been assigned an id yet and is treated as a new record. - -* Allow for domain sockets in PostgreSQL by not assuming localhost when no host is specified [Scott Barron] - -* Fixed that bignums are saved properly instead of attempted to be YAMLized [Andreas Schwartz] - -* Fixed a bug in the GEM where the rdoc options weren't being passed according to spec [Chad Fowler] - -* Fixed a bug with the exclusively_dependent option for has_many - - -*0.9.4* - -* Correctly guesses the primary key when the class is inside a module [Dave Steinberg]. - -* Added [] and []= as alternatives to read_attribute and write_attribute [Dave Steinberg] - -* has_and_belongs_to_many now accepts an :order key to determine in which order the collection is returned [radsaq]. - -* The ids passed to find and find_on_conditions are now automatically sanitized. - -* Added escaping of plings in YAML content. - -* Multi-parameter assigns where all the parameters are empty will now be set to nil instead of a new instance of their class. - -* Proper type within an inheritance hierarchy is now ensured already at object initialization (instead of first at create) - - -*0.9.3* - -* Fixed bug with using a different primary key name together with has_and_belongs_to_many [Investigation by Scott] - -* Added :exclusively_dependent option to the has_many association macro. The doc reads: - - If set to true all the associated object are deleted in one SQL statement without having their - before_destroy callback run. This should only be used on associations that depend solely on - this class and don't need to do any clean-up in before_destroy. The upside is that it's much - faster, especially if there's a counter_cache involved. - -* Added :port key to connection options, so the PostgreSQL and MySQL adapters can connect to a database server - running on another port than the default. - -* Converted the new natural singleton methods that prevented AR objects from being saved by PStore - (and hence be placed in a Rails session) to a module. [Florian Weber] - -* Fixed the use of floats (was broken since 0.9.0+) - -* Fixed PostgreSQL adapter so default values are displayed properly when used in conjunction with - Action Pack scaffolding. - -* Fixed booleans support for PostgreSQL (use real true/false on boolean fields instead of 0/1 on tinyints) [radsaq] - - -*0.9.2* - -* Added static method for instantly updating a record - -* Treat decimal and numeric as Ruby floats [Andreas Schwartz] - -* Treat chars as Ruby strings (fixes problem for Action Pack form helpers too) - -* Removed debugging output accidently left in (which would screw web applications) - - -*0.9.1* - -* Added MIT license - -* Added natural object-style assignment for has_and_belongs_to_many associations. Consider the following model: - - class Event < ActiveRecord::Base - has_one_and_belongs_to_many :sponsors - end - - class Sponsor < ActiveRecord::Base - has_one_and_belongs_to_many :sponsors - end - - Earlier, you'd have to use synthetic methods for creating associations between two objects of the above class: - - roskilde_festival.add_to_sponsors(carlsberg) - roskilde_festival.remove_from_sponsors(carlsberg) - - nike.add_to_events(world_cup) - nike.remove_from_events(world_cup) - - Now you can use regular array-styled methods: - - roskilde_festival.sponsors << carlsberg - roskilde_festival.sponsors.delete(carlsberg) - - nike.events << world_cup - nike.events.delete(world_cup) - -* Added delete method for has_many associations. Using this will nullify an association between the has_many and the belonging - object by setting the foreign key to null. Consider this model: - - class Post < ActiveRecord::Base - has_many :comments - end - - class Comment < ActiveRecord::Base - belongs_to :post - end - - You could do something like: - - funny_comment.has_post? # => true - announcement.comments.delete(funny_comment) - funny_comment.has_post? # => false - - -*0.9.0* - -* Active Record is now thread safe! (So you can use it with Cerise and WEBrick applications) - [Implementation idea by Michael Neumann, debugging assistance by Jamis Buck] - -* Improved performance by roughly 400% on a basic test case of pulling 100 records and querying one attribute. - This brings the tax for using Active Record instead of "riding on the metal" (using MySQL-ruby C-driver directly) down to ~50%. - Done by doing lazy type conversions and caching column information on the class-level. - -* Added callback objects and procs as options for implementing the target for callback macros. - -* Added "counter_cache" option to belongs_to that automates the usage of increment_counter and decrement_counter. Consider: - - class Post < ActiveRecord::Base - has_many :comments - end - - class Comment < ActiveRecord::Base - belongs_to :post - end - - Iterating over 100 posts like this: - - <% for post in @posts %> - <%= post.title %> has <%= post.comments_count %> comments - <% end %> - - Will generate 100 SQL count queries -- one for each call to post.comments_count. If you instead add a "comments_count" int column - to the posts table and rewrite the comments association macro with: - - class Comment < ActiveRecord::Base - belongs_to :post, :counter_cache => true - end - - Those 100 SQL count queries will be reduced to zero. Beware that counter caching is only appropriate for objects that begin life - with the object it's specified to belong with and is destroyed like that as well. Typically objects where you would also specify - :dependent => true. If your objects switch from one belonging to another (like a post that can be move from one category to another), - you'll have to manage the counter yourself. - -* Added natural object-style assignment for has_one and belongs_to associations. Consider the following model: - - class Project < ActiveRecord::Base - has_one :manager - end - - class Manager < ActiveRecord::Base - belongs_to :project - end - - Earlier, assignments would work like following regardless of which way the assignment told the best story: - - active_record.manager_id = david.id - - Now you can do it either from the belonging side: - - david.project = active_record - - ...or from the having side: - - active_record.manager = david - - If the assignment happens from the having side, the assigned object is automatically saved. So in the example above, the - project_id attribute on david would be set to the id of active_record, then david would be saved. - -* Added natural object-style assignment for has_many associations [Florian Weber]. Consider the following model: - - class Project < ActiveRecord::Base - has_many :milestones - end - - class Milestone < ActiveRecord::Base - belongs_to :project - end - - Earlier, assignments would work like following regardless of which way the assignment told the best story: - - deadline.project_id = active_record.id - - Now you can do it either from the belonging side: - - deadline.project = active_record - - ...or from the having side: - - active_record.milestones << deadline - - The milestone is automatically saved with the new foreign key. - -* API CHANGE: Attributes for text (or blob or similar) columns will now have unknown classes stored using YAML instead of using - to_s. (Known classes that won't be yamelized are: String, NilClass, TrueClass, FalseClass, Fixnum, Date, and Time). - Likewise, data pulled out of text-based attributes will be attempted converged using Yaml if they have the "--- " header. - This was primarily done to be enable the storage of hashes and arrays without wrapping them in aggregations, so now you can do: - - user = User.find(1) - user.preferences = { "background" => "black", "display" => large } - user.save - - User.find(1).preferences # => { "background" => "black", "display" => large } - - Please note that this method should only be used when you don't care about representing the object in proper columns in - the database. A money object consisting of an amount and a currency is still a much better fit for a value object done through - aggregations than this new option. - -* POSSIBLE CODE BREAKAGE: As a consequence of the lazy type conversions, it's a bad idea to reference the @attributes hash - directly (it always was, but now it's paramount that you don't). If you do, you won't get the type conversion. So to implement - new accessors for existing attributes, use read_attribute(attr_name) and write_attribute(attr_name, value) instead. Like this: - - class Song < ActiveRecord::Base - # Uses an integer of seconds to hold the length of the song - - def length=(minutes) - write_attribute("length", minutes * 60) - end - - def length - read_attribute("length") / 60 - end - end - - The clever kid will notice that this opens a door to sidestep the automated type conversion by using @attributes directly. - This is not recommended as read/write_attribute may be granted additional responsibilities in the future, but if you think - you know what you're doing and aren't afraid of future consequences, this is an option. - -* Applied a few minor bug fixes reported by Daniel Von Fange. - - -*0.8.4* - -_Reflection_ - -* Added ActiveRecord::Reflection with a bunch of methods and classes for reflecting in aggregations and associations. - -* Added Base.columns and Base.content_columns which returns arrays of column description (type, default, etc) objects. - -* Added Base#attribute_names which returns an array of names for the attributes available on the object. - -* Added Base#column_for_attribute(name) which returns the column description object for the named attribute. - - -_Misc_ - -* Added multi-parameter assignment: - - # Instantiate objects for all attribute classes that needs more than one constructor parameter. This is done - # by calling new on the column type or aggregation type (through composed_of) object with these parameters. - # So having the pairs written_on(1) = "2004", written_on(2) = "6", written_on(3) = "24", will instantiate - # written_on (a date type) with Date.new("2004", "6", "24"). You can also specify a typecast character in the - # parenteses to have the parameters typecasted before they're used in the constructor. Use i for Fixnum, f for Float, - # s for String, and a for Array. - - This is incredibly useful for assigning dates from HTML drop-downs of month, year, and day. - -* Fixed bug with custom primary key column name and Base.find on multiple parameters. - -* Fixed bug with dependent option on has_one associations if there was no associated object. - - -*0.8.3* - -_Transactions_ - -* Added transactional protection for destroy (important for the new :dependent option) [Suggested by Carl Youngblood] - -* Fixed so transactions are ignored on MyISAM tables for MySQL (use InnoDB to get transactions) - -* Changed transactions so only exceptions will cause a rollback, not returned false. - - -_Mapping_ - -* Added support for non-integer primary keys [Aredridel/earlier work by Michael Neumann] - - User.find "jdoe" - Product.find "PDKEY-INT-12" - -* Added option to specify naming method for primary key column. ActiveRecord::Base.primary_key_prefix_type can either - be set to nil, :table_name, or :table_name_with_underscore. :table_name will assume that Product class has a primary key - of "productid" and :table_name_with_underscore will assume "product_id". The default nil will just give "id". - -* Added an overwriteable primary_key method that'll instruct AR to the name of the - id column [Aredridele/earlier work by Guan Yang] - - class Project < ActiveRecord::Base - def self.primary_key() "project_id" end - end - -* Fixed that Active Records can safely associate inside and out of modules. - - class MyApplication::Account < ActiveRecord::Base - has_many :clients # will look for MyApplication::Client - has_many :interests, :class_name => "Business::Interest" # will look for Business::Interest - end - -* Fixed that Active Records can safely live inside modules [Aredridel] - - class MyApplication::Account < ActiveRecord::Base - end - - -_Misc_ - -* Added freeze call to value object assignments to ensure they remain immutable [Spotted by Gavin Sinclair] - -* Changed interface for specifying observed class in observers. Was OBSERVED_CLASS constant, now is - observed_class() class method. This is more consistant with things like self.table_name(). Works like this: - - class AuditObserver < ActiveRecord::Observer - def self.observed_class() Account end - def after_update(account) - AuditTrail.new(account, "UPDATED") - end - end - - [Suggested by Gavin Sinclair] - -* Create new Active Record objects by setting the attributes through a block. Like this: - - person = Person.new do |p| - p.name = 'Freddy' - p.age = 19 - end - - [Suggested by Gavin Sinclair] - - -*0.8.2* - -* Added inheritable callback queues that can ensure that certain callback methods or inline fragments are - run throughout the entire inheritance hierarchy. Regardless of whether a descendent overwrites the callback - method: - - class Topic < ActiveRecord::Base - before_destroy :destroy_author, 'puts "I'm an inline fragment"' - end - - Learn more in link:classes/ActiveRecord/Callbacks.html - -* Added :dependent option to has_many and has_one, which will automatically destroy associated objects when - the holder is destroyed: - - class Album < ActiveRecord::Base - has_many :tracks, :dependent => true - end - - All the associated tracks are destroyed when the album is. - -* Added Base.create as a factory that'll create, save, and return a new object in one step. - -* Automatically convert strings in config hashes to symbols for the _connection methods. This allows you - to pass the argument hashes directly from yaml. (Luke) - -* Fixed the install.rb to include simple.rb [Spotted by Kevin Bullock] - -* Modified block syntax to better follow our code standards outlined in - http://www.rubyonrails.org/CodingStandards - - -*0.8.1* - -* Added object-level transactions [Thanks to Austin Ziegler for Transaction::Simple] - -* Changed adapter-specific connection methods to use centralized ActiveRecord::Base.establish_connection, - which is parametized through a config hash with symbol keys instead of a regular parameter list. - This will allow for database connections to be opened in a more generic fashion. (Luke) - - NOTE: This requires all *_connections to be updated! Read more in: - http://ar.rubyonrails.org/classes/ActiveRecord/Base.html#M000081 - -* Fixed SQLite adapter so objects fetched from has_and_belongs_to_many have proper attributes - (t.name is now name). [Spotted by Garrett Rooney] - -* Fixed SQLite adapter so dates are returned as Date objects, not Time objects [Spotted by Gavin Sinclair] - -* Fixed requirement of date class, so date conversions are succesful regardless of whether you - manually require date or not. - - -*0.8.0* - -* Added transactions - -* Changed Base.find to also accept either a list (1, 5, 6) or an array of ids ([5, 7]) - as parameter and then return an array of objects instead of just an object - -* Fixed method has_collection? for has_and_belongs_to_many macro to behave as a - collection, not an association - -* Fixed SQLite adapter so empty or nil values in columns of datetime, date, or time type - aren't treated as current time [Spotted by Gavin Sinclair] - - -*0.7.6* - -* Fixed the install.rb to create the lib/active_record/support directory [Spotted by Gavin Sinclair] -* Fixed that has_association? would always return true [Spotted by Daniel Von Fange] diff --git a/tracks/vendor/rails/activerecord/README b/tracks/vendor/rails/activerecord/README deleted file mode 100644 index 1be4df61..00000000 --- a/tracks/vendor/rails/activerecord/README +++ /dev/null @@ -1,360 +0,0 @@ -= Active Record -- Object-relation mapping put on rails - -Active Record connects business objects and database tables to create a persistable -domain model where logic and data are presented in one wrapping. It's an implementation -of the object-relational mapping (ORM) pattern[http://www.martinfowler.com/eaaCatalog/activeRecord.html] -by the same name as described by Martin Fowler: - - "An object that wraps a row in a database table or view, encapsulates - the database access, and adds domain logic on that data." - -Active Record's main contribution to the pattern is to relieve the original of two stunting problems: -lack of associations and inheritance. By adding a simple domain language-like set of macros to describe -the former and integrating the Single Table Inheritance pattern for the latter, Active Record narrows the -gap of functionality between the data mapper and active record approach. - -A short rundown of the major features: - -* Automated mapping between classes and tables, attributes and columns. - - class Product < ActiveRecord::Base; end - - ...is automatically mapped to the table named "products", such as: - - CREATE TABLE products ( - id int(11) NOT NULL auto_increment, - name varchar(255), - PRIMARY KEY (id) - ); - - ...which again gives Product#name and Product#name=(new_name) - - {Learn more}[link:classes/ActiveRecord/Base.html] - - -* Associations between objects controlled by simple meta-programming macros. - - class Firm < ActiveRecord::Base - has_many :clients - has_one :account - belongs_to :conglomorate - end - - {Learn more}[link:classes/ActiveRecord/Associations/ClassMethods.html] - - -* Aggregations of value objects controlled by simple meta-programming macros. - - class Account < ActiveRecord::Base - composed_of :balance, :class_name => "Money", - :mapping => %w(balance amount) - composed_of :address, - :mapping => [%w(address_street street), %w(address_city city)] - end - - {Learn more}[link:classes/ActiveRecord/Aggregations/ClassMethods.html] - - -* Validation rules that can differ for new or existing objects. - - class Account < ActiveRecord::Base - validates_presence_of :subdomain, :name, :email_address, :password - validates_uniqueness_of :subdomain - validates_acceptance_of :terms_of_service, :on => :create - validates_confirmation_of :password, :email_address, :on => :create - end - - {Learn more}[link:classes/ActiveRecord/Validations.html] - - -* Acts that can make records work as lists or trees: - - class Item < ActiveRecord::Base - belongs_to :list - acts_as_list :scope => :list - end - - item.move_higher - item.move_to_bottom - - Learn about {acts_as_list}[link:classes/ActiveRecord/Acts/List/ClassMethods.html], {the instance methods acts_as_list provides}[link:classes/ActiveRecord/Acts/List/InstanceMethods.html], and - {acts_as_tree}[link:classes/ActiveRecord/Acts/Tree/ClassMethods.html] - -* Callbacks as methods or queues on the entire lifecycle (instantiation, saving, destroying, validating, etc). - - class Person < ActiveRecord::Base - def before_destroy # is called just before Person#destroy - CreditCard.find(credit_card_id).destroy - end - end - - class Account < ActiveRecord::Base - after_find :eager_load, 'self.class.announce(#{id})' - end - - {Learn more}[link:classes/ActiveRecord/Callbacks.html] - - -* Observers for the entire lifecycle - - class CommentObserver < ActiveRecord::Observer - def after_create(comment) # is called just after Comment#save - Notifications.deliver_new_comment("david@loudthinking.com", comment) - end - end - - {Learn more}[link:classes/ActiveRecord/Observer.html] - - -* Inheritance hierarchies - - class Company < ActiveRecord::Base; end - class Firm < Company; end - class Client < Company; end - class PriorityClient < Client; end - - {Learn more}[link:classes/ActiveRecord/Base.html] - - -* Transaction support on both a database and object level. The latter is implemented - by using Transaction::Simple[http://www.halostatue.ca/ruby/Transaction__Simple.html] - - # Just database transaction - Account.transaction do - david.withdrawal(100) - mary.deposit(100) - end - - # Database and object transaction - Account.transaction(david, mary) do - david.withdrawal(100) - mary.deposit(100) - end - - {Learn more}[link:classes/ActiveRecord/Transactions/ClassMethods.html] - - -* Reflections on columns, associations, and aggregations - - reflection = Firm.reflect_on_association(:clients) - reflection.klass # => Client (class) - Firm.columns # Returns an array of column descriptors for the firms table - - {Learn more}[link:classes/ActiveRecord/Reflection/ClassMethods.html] - - -* Direct manipulation (instead of service invocation) - - So instead of (Hibernate[http://www.hibernate.org/] example): - - long pkId = 1234; - DomesticCat pk = (DomesticCat) sess.load( Cat.class, new Long(pkId) ); - // something interesting involving a cat... - sess.save(cat); - sess.flush(); // force the SQL INSERT - - Active Record lets you: - - pkId = 1234 - cat = Cat.find(pkId) - # something even more interesting involving the same cat... - cat.save - - {Learn more}[link:classes/ActiveRecord/Base.html] - - -* Database abstraction through simple adapters (~100 lines) with a shared connector - - ActiveRecord::Base.establish_connection(:adapter => "sqlite", :database => "dbfile") - - ActiveRecord::Base.establish_connection( - :adapter => "mysql", - :host => "localhost", - :username => "me", - :password => "secret", - :database => "activerecord" - ) - - {Learn more}[link:classes/ActiveRecord/Base.html#M000081] and read about the built-in support for - MySQL[link:classes/ActiveRecord/ConnectionAdapters/MysqlAdapter.html], PostgreSQL[link:classes/ActiveRecord/ConnectionAdapters/PostgreSQLAdapter.html], SQLite[link:classes/ActiveRecord/ConnectionAdapters/SQLiteAdapter.html], Oracle[link:classes/ActiveRecord/ConnectionAdapters/OCIAdapter.html], SQLServer[link:classes/ActiveRecord/ConnectionAdapters/SQLServerAdapter.html], and DB2[link:classes/ActiveRecord/ConnectionAdapters/DB2Adapter.html]. - - -* Logging support for Log4r[http://log4r.sourceforge.net] and Logger[http://www.ruby-doc.org/stdlib/libdoc/logger/rdoc] - - ActiveRecord::Base.logger = Logger.new(STDOUT) - ActiveRecord::Base.logger = Log4r::Logger.new("Application Log") - - -== Simple example (1/2): Defining tables and classes (using MySQL) - -Data definitions are specified only in the database. Active Record queries the database for -the column names (that then serves to determine which attributes are valid) on regular -object instantiation through the new constructor and relies on the column names in the rows -with the finders. - - # CREATE TABLE companies ( - # id int(11) unsigned NOT NULL auto_increment, - # client_of int(11), - # name varchar(255), - # type varchar(100), - # PRIMARY KEY (id) - # ) - -Active Record automatically links the "Company" object to the "companies" table - - class Company < ActiveRecord::Base - has_many :people, :class_name => "Person" - end - - class Firm < Company - has_many :clients - - def people_with_all_clients - clients.inject([]) { |people, client| people + client.people } - end - end - -The foreign_key is only necessary because we didn't use "firm_id" in the data definition - - class Client < Company - belongs_to :firm, :foreign_key => "client_of" - end - - # CREATE TABLE people ( - # id int(11) unsigned NOT NULL auto_increment, - # name text, - # company_id text, - # PRIMARY KEY (id) - # ) - -Active Record will also automatically link the "Person" object to the "people" table - - class Person < ActiveRecord::Base - belongs_to :company - end - -== Simple example (2/2): Using the domain - -Picking a database connection for all the Active Records - - ActiveRecord::Base.establish_connection( - :adapter => "mysql", - :host => "localhost", - :username => "me", - :password => "secret", - :database => "activerecord" - ) - -Create some fixtures - - firm = Firm.new("name" => "Next Angle") - # SQL: INSERT INTO companies (name, type) VALUES("Next Angle", "Firm") - firm.save - - client = Client.new("name" => "37signals", "client_of" => firm.id) - # SQL: INSERT INTO companies (name, client_of, type) VALUES("37signals", 1, "Firm") - client.save - -Lots of different finders - - # SQL: SELECT * FROM companies WHERE id = 1 - next_angle = Company.find(1) - - # SQL: SELECT * FROM companies WHERE id = 1 AND type = 'Firm' - next_angle = Firm.find(1) - - # SQL: SELECT * FROM companies WHERE id = 1 AND name = 'Next Angle' - next_angle = Company.find_first "name = 'Next Angle'" - - next_angle = Firm.find_by_sql("SELECT * FROM companies WHERE id = 1").first - -The supertype, Company, will return subtype instances - - Firm === next_angle - -All the dynamic methods added by the has_many macro - - next_angle.clients.empty? # true - next_angle.clients.size # total number of clients - all_clients = next_angle.clients - -Constrained finds makes access security easier when ID comes from a web-app - - # SQL: SELECT * FROM companies WHERE client_of = 1 AND type = 'Client' AND id = 2 - thirty_seven_signals = next_angle.clients.find(2) - -Bi-directional associations thanks to the "belongs_to" macro - - thirty_seven_signals.firm.nil? # true - - -== Examples - -Active Record ships with a couple of examples that should give you a good feel for -operating usage. Be sure to edit the examples/shared_setup.rb file for your -own database before running the examples. Possibly also the table definition SQL in -the examples themselves. - -It's also highly recommended to have a look at the unit tests. Read more in link:files/RUNNING_UNIT_TESTS.html - - -== Philosophy - -Active Record attempts to provide a coherent wrapper as a solution for the inconvenience that is -object-relational mapping. The prime directive for this mapping has been to minimize -the amount of code needed to build a real-world domain model. This is made possible -by relying on a number of conventions that make it easy for Active Record to infer -complex relations and structures from a minimal amount of explicit direction. - -Convention over Configuration: -* No XML-files! -* Lots of reflection and run-time extension -* Magic is not inherently a bad word - -Admit the Database: -* Lets you drop down to SQL for odd cases and performance -* Doesn't attempt to duplicate or replace data definitions - - -== Download - -The latest version of Active Record can be found at - -* http://rubyforge.org/project/showfiles.php?group_id=182 - -Documentation can be found at - -* http://ar.rubyonrails.com - - -== Installation - -The prefered method of installing Active Record is through its GEM file. You'll need to have -RubyGems[http://rubygems.rubyforge.org/wiki/wiki.pl] installed for that, though. If you have, -then use: - - % [sudo] gem install activerecord-1.10.0.gem - -You can also install Active Record the old-fashion way with the following command: - - % [sudo] ruby install.rb - -from its distribution directory. - - -== License - -Active Record is released under the MIT license. - - -== Support - -The Active Record homepage is http://www.rubyonrails.com. You can find the Active Record -RubyForge page at http://rubyforge.org/projects/activerecord. And as Jim from Rake says: - - Feel free to submit commits or feature requests. If you send a patch, - remember to update the corresponding unit tests. If fact, I prefer - new feature to be submitted in the form of new unit tests. - -For other information, feel free to ask on the ruby-talk mailing list -(which is mirrored to comp.lang.ruby) or contact mailto:david@loudthinking.com. diff --git a/tracks/vendor/rails/activerecord/RUNNING_UNIT_TESTS b/tracks/vendor/rails/activerecord/RUNNING_UNIT_TESTS deleted file mode 100644 index 2d47078c..00000000 --- a/tracks/vendor/rails/activerecord/RUNNING_UNIT_TESTS +++ /dev/null @@ -1,46 +0,0 @@ -== Creating the test database - -The default names for the test databases are "activerecord_unittest" and -"activerecord_unittest2". If you want to use another database name then be sure -to update the connection adapter setups you want to test with in -test/connections//connection.rb. -When you have the database online, you can import the fixture tables with -the test/fixtures/db_definitions/*.sql files. - -Make sure that you create database objects with the same user that you specified in i -connection.rb otherwise (on Postgres, at least) tests for default values will fail. - -== Running with Rake - -The easiest way to run the unit tests is through Rake. The default task runs -the entire test suite for all the adapters. You can also run the suite on just -one adapter by using the tasks test_mysql_ruby, test_ruby_mysql, test_sqlite, -or test_postresql. For more information, checkout the full array of rake tasks with "rake -T" - -Rake can be found at http://rake.rubyforge.org - -== Running by hand - -Unit tests are located in test directory. If you only want to run a single test suite, -or don't want to bother with Rake, you can do so with something like: - - cd test; ruby -I "connections/native_mysql" base_test.rb - -That'll run the base suite using the MySQL-Ruby adapter. Change the adapter -and test suite name as needed. - -You can also run all the suites on a specific adapter with: - - cd test; all.sh "connections/native_mysql" - -== Faster tests - -If you are using a database that supports transactions, you can set the -"AR_TX_FIXTURES" environment variable to "yes" to use transactional fixtures. -This gives a very large speed boost. With rake: - - rake AR_TX_FIXTURES=yes - -Or, by hand: - - AR_TX_FIXTURES=yes ruby -I connections/native_sqlite3 base_test.rb diff --git a/tracks/vendor/rails/activerecord/examples/associations.png b/tracks/vendor/rails/activerecord/examples/associations.png deleted file mode 100644 index 661c7a8b..00000000 Binary files a/tracks/vendor/rails/activerecord/examples/associations.png and /dev/null differ diff --git a/tracks/vendor/rails/activerecord/examples/associations.rb b/tracks/vendor/rails/activerecord/examples/associations.rb deleted file mode 100644 index b0df3673..00000000 --- a/tracks/vendor/rails/activerecord/examples/associations.rb +++ /dev/null @@ -1,87 +0,0 @@ -require File.dirname(__FILE__) + '/shared_setup' - -logger = Logger.new(STDOUT) - -# Database setup --------------- - -logger.info "\nCreate tables" - -[ "DROP TABLE companies", "DROP TABLE people", "DROP TABLE people_companies", - "CREATE TABLE companies (id int(11) auto_increment, client_of int(11), name varchar(255), type varchar(100), PRIMARY KEY (id))", - "CREATE TABLE people (id int(11) auto_increment, name varchar(100), PRIMARY KEY (id))", - "CREATE TABLE people_companies (person_id int(11), company_id int(11), PRIMARY KEY (person_id, company_id))", -].each { |statement| - # Tables doesn't necessarily already exist - begin; ActiveRecord::Base.connection.execute(statement); rescue ActiveRecord::StatementInvalid; end -} - - -# Class setup --------------- - -class Company < ActiveRecord::Base - has_and_belongs_to_many :people, :class_name => "Person", :join_table => "people_companies", :table_name => "people" -end - -class Firm < Company - has_many :clients, :foreign_key => "client_of" - - def people_with_all_clients - clients.inject([]) { |people, client| people + client.people } - end -end - -class Client < Company - belongs_to :firm, :foreign_key => "client_of" -end - -class Person < ActiveRecord::Base - has_and_belongs_to_many :companies, :join_table => "people_companies" - def self.table_name() "people" end -end - - -# Usage --------------- - -logger.info "\nCreate fixtures" - -Firm.new("name" => "Next Angle").save -Client.new("name" => "37signals", "client_of" => 1).save -Person.new("name" => "David").save - - -logger.info "\nUsing Finders" - -next_angle = Company.find(1) -next_angle = Firm.find(1) -next_angle = Company.find_first "name = 'Next Angle'" -next_angle = Firm.find_by_sql("SELECT * FROM companies WHERE id = 1").first - -Firm === next_angle - - -logger.info "\nUsing has_many association" - -next_angle.has_clients? -next_angle.clients_count -all_clients = next_angle.clients - -thirty_seven_signals = next_angle.find_in_clients(2) - - -logger.info "\nUsing belongs_to association" - -thirty_seven_signals.has_firm? -thirty_seven_signals.firm?(next_angle) - - -logger.info "\nUsing has_and_belongs_to_many association" - -david = Person.find(1) -david.add_companies(thirty_seven_signals, next_angle) -david.companies.include?(next_angle) -david.companies_count == 2 - -david.remove_companies(next_angle) -david.companies_count == 1 - -thirty_seven_signals.people.include?(david) \ No newline at end of file diff --git a/tracks/vendor/rails/activerecord/examples/shared_setup.rb b/tracks/vendor/rails/activerecord/examples/shared_setup.rb deleted file mode 100644 index 6ede4b1d..00000000 --- a/tracks/vendor/rails/activerecord/examples/shared_setup.rb +++ /dev/null @@ -1,15 +0,0 @@ -# Be sure to change the mysql_connection details and create a database for the example - -$: << File.dirname(__FILE__) + '/../lib' - -require 'active_record' -require 'logger'; class Logger; def format_message(severity, timestamp, msg, progname) "#{msg}\n" end; end - -ActiveRecord::Base.logger = Logger.new(STDOUT) -ActiveRecord::Base.establish_connection( - :adapter => "mysql", - :host => "localhost", - :username => "root", - :password => "", - :database => "activerecord_examples" -) diff --git a/tracks/vendor/rails/activerecord/examples/validation.rb b/tracks/vendor/rails/activerecord/examples/validation.rb deleted file mode 100644 index e6a448af..00000000 --- a/tracks/vendor/rails/activerecord/examples/validation.rb +++ /dev/null @@ -1,85 +0,0 @@ -require File.dirname(__FILE__) + '/shared_setup' - -logger = Logger.new(STDOUT) - -# Database setup --------------- - -logger.info "\nCreate tables" - -[ "DROP TABLE people", - "CREATE TABLE people (id int(11) auto_increment, name varchar(100), pass varchar(100), email varchar(100), PRIMARY KEY (id))" -].each { |statement| - begin; ActiveRecord::Base.connection.execute(statement); rescue ActiveRecord::StatementInvalid; end # Tables doesn't necessarily already exist -} - - -# Class setup --------------- - -class Person < ActiveRecord::Base - # Using - def self.authenticate(name, pass) - # find_first "name = '#{name}' AND pass = '#{pass}'" would be open to sql-injection (in a web-app scenario) - find_first [ "name = '%s' AND pass = '%s'", name, pass ] - end - - def self.name_exists?(name, id = nil) - if id.nil? - condition = [ "name = '%s'", name ] - else - # Check if anyone else than the person identified by person_id has that user_name - condition = [ "name = '%s' AND id <> %d", name, id ] - end - - !find_first(condition).nil? - end - - def email_address_with_name - "\"#{name}\" <#{email}>" - end - - protected - def validate - errors.add_on_empty(%w(name pass email)) - errors.add("email", "must be valid") unless email_address_valid? - end - - def validate_on_create - if attribute_present?("name") && Person.name_exists?(name) - errors.add("name", "is already taken by another person") - end - end - - def validate_on_update - if attribute_present?("name") && Person.name_exists?(name, id) - errors.add("name", "is already taken by another person") - end - end - - private - def email_address_valid?() email =~ /\w[-.\w]*\@[-\w]+[-.\w]*\.\w+/ end -end - -# Usage --------------- - -logger.info "\nCreate fixtures" -david = Person.new("name" => "David Heinemeier Hansson", "pass" => "", "email" => "") -unless david.save - puts "There was #{david.errors.count} error(s)" - david.errors.each_full { |error| puts error } -end - -david.pass = "something" -david.email = "invalid_address" -unless david.save - puts "There was #{david.errors.count} error(s)" - puts "It was email with: " + david.errors.on("email") -end - -david.email = "david@loudthinking.com" -if david.save then puts "David finally made it!" end - - -another_david = Person.new("name" => "David Heinemeier Hansson", "pass" => "xc", "email" => "david@loudthinking") -unless another_david.save - puts "Error on name: " + another_david.errors.on("name") -end \ No newline at end of file diff --git a/tracks/vendor/rails/activerecord/install.rb b/tracks/vendor/rails/activerecord/install.rb deleted file mode 100644 index 592c4b9d..00000000 --- a/tracks/vendor/rails/activerecord/install.rb +++ /dev/null @@ -1,30 +0,0 @@ -require 'rbconfig' -require 'find' -require 'ftools' - -include Config - -# this was adapted from rdoc's install.rb by ways of Log4r - -$sitedir = CONFIG["sitelibdir"] -unless $sitedir - version = CONFIG["MAJOR"] + "." + CONFIG["MINOR"] - $libdir = File.join(CONFIG["libdir"], "ruby", version) - $sitedir = $:.find {|x| x =~ /site_ruby/ } - if !$sitedir - $sitedir = File.join($libdir, "site_ruby") - elsif $sitedir !~ Regexp.quote(version) - $sitedir = File.join($sitedir, version) - end -end - -# the acual gruntwork -Dir.chdir("lib") - -Find.find("active_record", "active_record.rb") { |f| - if f[-3..-1] == ".rb" - File::install(f, File.join($sitedir, *f.split(/\//)), 0644, true) - else - File::makedirs(File.join($sitedir, *f.split(/\//))) - end -} diff --git a/tracks/vendor/rails/activerecord/lib/active_record.rb b/tracks/vendor/rails/activerecord/lib/active_record.rb deleted file mode 100644 index 7cf54560..00000000 --- a/tracks/vendor/rails/activerecord/lib/active_record.rb +++ /dev/null @@ -1,76 +0,0 @@ -#-- -# Copyright (c) 2004 David Heinemeier Hansson -# -# 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. -#++ - -$:.unshift(File.dirname(__FILE__)) unless - $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__))) - -unless defined?(ActiveSupport) - begin - $:.unshift(File.dirname(__FILE__) + "/../../activesupport/lib") - require 'active_support' - rescue LoadError - require 'rubygems' - require_gem 'activesupport' - end -end - -require 'active_record/base' -require 'active_record/observer' -require 'active_record/validations' -require 'active_record/callbacks' -require 'active_record/associations' -require 'active_record/aggregations' -require 'active_record/transactions' -require 'active_record/reflection' -require 'active_record/timestamp' -require 'active_record/acts/list' -require 'active_record/acts/tree' -require 'active_record/acts/nested_set' -require 'active_record/locking' -require 'active_record/migration' -require 'active_record/schema' - -ActiveRecord::Base.class_eval do - include ActiveRecord::Validations - include ActiveRecord::Locking - include ActiveRecord::Callbacks - include ActiveRecord::Observing - include ActiveRecord::Timestamp - include ActiveRecord::Associations - include ActiveRecord::Aggregations - include ActiveRecord::Transactions - include ActiveRecord::Reflection - include ActiveRecord::Acts::Tree - include ActiveRecord::Acts::List - include ActiveRecord::Acts::NestedSet -end - -unless defined?(RAILS_CONNECTION_ADAPTERS) - RAILS_CONNECTION_ADAPTERS = %w(mysql postgresql sqlite firebird sqlserver db2 oci) -end - -RAILS_CONNECTION_ADAPTERS.each do |adapter| - require "active_record/connection_adapters/" + adapter + "_adapter" -end - -require 'active_record/query_cache' diff --git a/tracks/vendor/rails/activerecord/lib/active_record/acts/list.rb b/tracks/vendor/rails/activerecord/lib/active_record/acts/list.rb deleted file mode 100644 index ce1c59d4..00000000 --- a/tracks/vendor/rails/activerecord/lib/active_record/acts/list.rb +++ /dev/null @@ -1,233 +0,0 @@ -module ActiveRecord - module Acts #:nodoc: - module List #:nodoc: - def self.append_features(base) - super - base.extend(ClassMethods) - end - - # This act provides the capabilities for sorting and reordering a number of objects in a list. - # The class that has this specified needs to have a "position" column defined as an integer on - # the mapped database table. - # - # Todo list example: - # - # class TodoList < ActiveRecord::Base - # has_many :todo_items, :order => "position" - # end - # - # class TodoItem < ActiveRecord::Base - # belongs_to :todo_list - # acts_as_list :scope => :todo_list - # end - # - # todo_list.first.move_to_bottom - # todo_list.last.move_higher - module ClassMethods - # Configuration options are: - # - # * +column+ - specifies the column name to use for keeping the position integer (default: position) - # * +scope+ - restricts what is to be considered a list. Given a symbol, it'll attach "_id" - # (if that hasn't been already) and use that as the foreign key restriction. It's also possible - # to give it an entire string that is interpolated if you need a tighter scope than just a foreign key. - # Example: acts_as_list :scope => 'todo_list_id = #{todo_list_id} AND completed = 0' - def acts_as_list(options = {}) - configuration = { :column => "position", :scope => "1 = 1" } - configuration.update(options) if options.is_a?(Hash) - - configuration[:scope] = "#{configuration[:scope]}_id".intern if configuration[:scope].is_a?(Symbol) && configuration[:scope].to_s !~ /_id$/ - - if configuration[:scope].is_a?(Symbol) - scope_condition_method = %( - def scope_condition - if #{configuration[:scope].to_s}.nil? - "#{configuration[:scope].to_s} IS NULL" - else - "#{configuration[:scope].to_s} = \#{#{configuration[:scope].to_s}}" - end - end - ) - else - scope_condition_method = "def scope_condition() \"#{configuration[:scope]}\" end" - end - - class_eval <<-EOV - include ActiveRecord::Acts::List::InstanceMethods - - def acts_as_list_class - ::#{self.name} - end - - def position_column - '#{configuration[:column]}' - end - - #{scope_condition_method} - - after_destroy :remove_from_list - before_create :add_to_list_bottom - EOV - end - end - - # All the methods available to a record that has had acts_as_list specified. Each method works - # by assuming the object to be the item in the list, so chapter.move_lower would move that chapter - # lower in the list of all chapters. Likewise, chapter.first? would return true if that chapter is - # the first in the list of all chapters. - module InstanceMethods - def insert_at(position = 1) - insert_at_position(position) - end - - def move_lower - return unless lower_item - - acts_as_list_class.transaction do - lower_item.decrement_position - increment_position - end - end - - def move_higher - return unless higher_item - - acts_as_list_class.transaction do - higher_item.increment_position - decrement_position - end - end - - def move_to_bottom - return unless in_list? - acts_as_list_class.transaction do - decrement_positions_on_lower_items - assume_bottom_position - end - end - - def move_to_top - return unless in_list? - acts_as_list_class.transaction do - increment_positions_on_higher_items - assume_top_position - end - end - - def remove_from_list - decrement_positions_on_lower_items if in_list? - end - - def increment_position - return unless in_list? - update_attribute position_column, self.send(position_column).to_i + 1 - end - - def decrement_position - return unless in_list? - update_attribute position_column, self.send(position_column).to_i - 1 - end - - def first? - return false unless in_list? - self.send(position_column) == 1 - end - - def last? - return false unless in_list? - self.send(position_column) == bottom_position_in_list - end - - def higher_item - return nil unless in_list? - acts_as_list_class.find(:first, :conditions => - "#{scope_condition} AND #{position_column} = #{(send(position_column).to_i - 1).to_s}" - ) - end - - def lower_item - return nil unless in_list? - acts_as_list_class.find(:first, :conditions => - "#{scope_condition} AND #{position_column} = #{(send(position_column).to_i + 1).to_s}" - ) - end - - def in_list? - !send(position_column).nil? - end - - private - def add_to_list_top - increment_positions_on_all_items - end - - def add_to_list_bottom - self[position_column] = bottom_position_in_list.to_i + 1 - end - - # Overwrite this method to define the scope of the list changes - def scope_condition() "1" end - - def bottom_position_in_list(except = nil) - item = bottom_item(except) - item ? item.send(position_column) : 0 - end - - def bottom_item(except = nil) - conditions = scope_condition - conditions = "#{conditions} AND id != #{except.id}" if except - acts_as_list_class.find(:first, :conditions => conditions, :order => "#{position_column} DESC") - end - - def assume_bottom_position - update_attribute(position_column, bottom_position_in_list(self).to_i + 1) - end - - def assume_top_position - update_attribute(position_column, 1) - end - - # This has the effect of moving all the higher items up one. - def decrement_positions_on_higher_items(position) - acts_as_list_class.update_all( - "#{position_column} = (#{position_column} - 1)", "#{scope_condition} AND #{position_column} <= #{position}" - ) - end - - # This has the effect of moving all the lower items up one. - def decrement_positions_on_lower_items - return unless in_list? - acts_as_list_class.update_all( - "#{position_column} = (#{position_column} - 1)", "#{scope_condition} AND #{position_column} > #{send(position_column).to_i}" - ) - end - - # This has the effect of moving all the higher items down one. - def increment_positions_on_higher_items - return unless in_list? - acts_as_list_class.update_all( - "#{position_column} = (#{position_column} + 1)", "#{scope_condition} AND #{position_column} < #{send(position_column).to_i}" - ) - end - - # This has the effect of moving all the lower items down one. - def increment_positions_on_lower_items(position) - acts_as_list_class.update_all( - "#{position_column} = (#{position_column} + 1)", "#{scope_condition} AND #{position_column} >= #{position}" - ) - end - - def increment_positions_on_all_items - acts_as_list_class.update_all( - "#{position_column} = (#{position_column} + 1)", "#{scope_condition}" - ) - end - - def insert_at_position(position) - remove_from_list - increment_positions_on_lower_items(position) - self.update_attribute(position_column, position) - end - end - end - end -end diff --git a/tracks/vendor/rails/activerecord/lib/active_record/acts/nested_set.rb b/tracks/vendor/rails/activerecord/lib/active_record/acts/nested_set.rb deleted file mode 100644 index 8b02b358..00000000 --- a/tracks/vendor/rails/activerecord/lib/active_record/acts/nested_set.rb +++ /dev/null @@ -1,212 +0,0 @@ -module ActiveRecord - module Acts #:nodoc: - module NestedSet #:nodoc: - def self.append_features(base) - super - base.extend(ClassMethods) - end - - # This acts provides Nested Set functionality. Nested Set is similiar to Tree, but with - # the added feature that you can select the children and all of their descendents with - # a single query. A good use case for this is a threaded post system, where you want - # to display every reply to a comment without multiple selects. - # - # A google search for "Nested Set" should point you in the direction to explain the - # database theory. I figured out a bunch of this from - # http://threebit.net/tutorials/nestedset/tutorial1.html - # - # Instead of picturing a leaf node structure with children pointing back to their parent, - # the best way to imagine how this works is to think of the parent entity surrounding all - # of its children, and its parent surrounding it, etc. Assuming that they are lined up - # horizontally, we store the left and right boundries in the database. - # - # Imagine: - # root - # |_ Child 1 - # |_ Child 1.1 - # |_ Child 1.2 - # |_ Child 2 - # |_ Child 2.1 - # |_ Child 2.2 - # - # If my cirlces in circles description didn't make sense, check out this sweet - # ASCII art: - # - # ___________________________________________________________________ - # | Root | - # | ____________________________ ____________________________ | - # | | Child 1 | | Child 2 | | - # | | __________ _________ | | __________ _________ | | - # | | | C 1.1 | | C 1.2 | | | | C 2.1 | | C 2.2 | | | - # 1 2 3_________4 5________6 7 8 9_________10 11_______12 13 14 - # | |___________________________| |___________________________| | - # |___________________________________________________________________| - # - # The numbers represent the left and right boundries. The table then might - # look like this: - # ID | PARENT | LEFT | RIGHT | DATA - # 1 | 0 | 1 | 14 | root - # 2 | 1 | 2 | 7 | Child 1 - # 3 | 2 | 3 | 4 | Child 1.1 - # 4 | 2 | 5 | 6 | Child 1.2 - # 5 | 1 | 8 | 13 | Child 2 - # 6 | 5 | 9 | 10 | Child 2.1 - # 7 | 5 | 11 | 12 | Child 2.2 - # - # So, to get all children of an entry, you - # SELECT * WHERE CHILD.LEFT IS BETWEEN PARENT.LEFT AND PARENT.RIGHT - # - # To get the count, it's (LEFT - RIGHT + 1)/2, etc. - # - # To get the direct parent, it falls back to using the PARENT_ID field. - # - # There are instance methods for all of these. - # - # The structure is good if you need to group things together; the downside is that - # keeping data integrity is a pain, and both adding and removing an entry - # require a full table write. - # - # This sets up a before_destroy trigger to prune the tree correctly if one of its - # elements gets deleted. - # - module ClassMethods - # Configuration options are: - # - # * +parent_column+ - specifies the column name to use for keeping the position integer (default: parent_id) - # * +left_column+ - column name for left boundry data, default "lft" - # * +right_column+ - column name for right boundry data, default "rgt" - # * +scope+ - restricts what is to be considered a list. Given a symbol, it'll attach "_id" - # (if that hasn't been already) and use that as the foreign key restriction. It's also possible - # to give it an entire string that is interpolated if you need a tighter scope than just a foreign key. - # Example: acts_as_list :scope => 'todo_list_id = #{todo_list_id} AND completed = 0' - def acts_as_nested_set(options = {}) - configuration = { :parent_column => "parent_id", :left_column => "lft", :right_column => "rgt", :scope => "1 = 1" } - - configuration.update(options) if options.is_a?(Hash) - - configuration[:scope] = "#{configuration[:scope]}_id".intern if configuration[:scope].is_a?(Symbol) && configuration[:scope].to_s !~ /_id$/ - - if configuration[:scope].is_a?(Symbol) - scope_condition_method = %( - def scope_condition - if #{configuration[:scope].to_s}.nil? - "#{configuration[:scope].to_s} IS NULL" - else - "#{configuration[:scope].to_s} = \#{#{configuration[:scope].to_s}}" - end - end - ) - else - scope_condition_method = "def scope_condition() \"#{configuration[:scope]}\" end" - end - - class_eval <<-EOV - include ActiveRecord::Acts::NestedSet::InstanceMethods - - #{scope_condition_method} - - def left_col_name() "#{configuration[:left_column]}" end - - def right_col_name() "#{configuration[:right_column]}" end - - def parent_column() "#{configuration[:parent_column]}" end - - EOV - end - end - - module InstanceMethods - # Returns true is this is a root node. - def root? - parent_id = self[parent_column] - (parent_id == 0 || parent_id.nil?) && (self[left_col_name] == 1) && (self[right_col_name] > self[left_col_name]) - end - - # Returns true is this is a child node - def child? - parent_id = self[parent_column] - !(parent_id == 0 || parent_id.nil?) && (self[left_col_name] > 1) && (self[right_col_name] > self[left_col_name]) - end - - # Returns true if we have no idea what this is - def unknown? - !root? && !child? - end - - - # Adds a child to this object in the tree. If this object hasn't been initialized, - # it gets set up as a root node. Otherwise, this method will update all of the - # other elements in the tree and shift them to the right, keeping everything - # balanced. - def add_child( child ) - self.reload - child.reload - - if child.root? - raise "Adding sub-tree isn\'t currently supported" - else - if ( (self[left_col_name] == nil) || (self[right_col_name] == nil) ) - # Looks like we're now the root node! Woo - self[left_col_name] = 1 - self[right_col_name] = 4 - - # What do to do about validation? - return nil unless self.save - - child[parent_column] = self.id - child[left_col_name] = 2 - child[right_col_name]= 3 - return child.save - else - # OK, we need to add and shift everything else to the right - child[parent_column] = self.id - right_bound = self[right_col_name] - child[left_col_name] = right_bound - child[right_col_name] = right_bound + 1 - self[right_col_name] += 2 - self.class.transaction { - self.class.update_all( "#{left_col_name} = (#{left_col_name} + 2)", "#{scope_condition} AND #{left_col_name} >= #{right_bound}" ) - self.class.update_all( "#{right_col_name} = (#{right_col_name} + 2)", "#{scope_condition} AND #{right_col_name} >= #{right_bound}" ) - self.save - child.save - } - end - end - end - - # Returns the number of nested children of this object. - def children_count - return (self[right_col_name] - self[left_col_name] - 1)/2 - end - - # Returns a set of itself and all of its nested children - def full_set - self.class.find(:all, :conditions => "#{scope_condition} AND (#{left_col_name} BETWEEN #{self[left_col_name]} and #{self[right_col_name]})" ) - end - - # Returns a set of all of its children and nested children - def all_children - self.class.find(:all, :conditions => "#{scope_condition} AND (#{left_col_name} > #{self[left_col_name]}) and (#{right_col_name} < #{self[right_col_name]})" ) - end - - # Returns a set of only this entry's immediate children - def direct_children - self.class.find(:all, :conditions => "#{scope_condition} and #{parent_column} = #{self.id}") - end - - # Prunes a branch off of the tree, shifting all of the elements on the right - # back to the left so the counts still work. - def before_destroy - return if self[right_col_name].nil? || self[left_col_name].nil? - dif = self[right_col_name] - self[left_col_name] + 1 - - self.class.transaction { - self.class.delete_all( "#{scope_condition} and #{left_col_name} > #{self[left_col_name]} and #{right_col_name} < #{self[right_col_name]}" ) - self.class.update_all( "#{left_col_name} = (#{left_col_name} - #{dif})", "#{scope_condition} AND #{left_col_name} >= #{self[right_col_name]}" ) - self.class.update_all( "#{right_col_name} = (#{right_col_name} - #{dif} )", "#{scope_condition} AND #{right_col_name} >= #{self[right_col_name]}" ) - } - end - end - end - end -end diff --git a/tracks/vendor/rails/activerecord/lib/active_record/acts/tree.rb b/tracks/vendor/rails/activerecord/lib/active_record/acts/tree.rb deleted file mode 100644 index e4ab8cd7..00000000 --- a/tracks/vendor/rails/activerecord/lib/active_record/acts/tree.rb +++ /dev/null @@ -1,86 +0,0 @@ -module ActiveRecord - module Acts #:nodoc: - module Tree #:nodoc: - def self.append_features(base) - super - base.extend(ClassMethods) - end - - # Specify this act if you want to model a tree structure by providing a parent association and a children - # association. This act requires that you have a foreign key column, which by default is called parent_id. - # - # class Category < ActiveRecord::Base - # acts_as_tree :order => "name" - # end - # - # Example : - # root - # \_ child1 - # \_ subchild1 - # \_ subchild2 - # - # root = Category.create("name" => "root") - # child1 = root.children.create("name" => "child1") - # subchild1 = child1.children.create("name" => "subchild1") - # - # root.parent # => nil - # child1.parent # => root - # root.children # => [child1] - # root.children.first.children.first # => subchild1 - # - # In addition to the parent and children associations, the following instance methods are added to the class - # after specifying the act: - # * siblings : Returns all the children of the parent, excluding the current node ([ subchild2 ] when called from subchild1) - # * self_and_siblings : Returns all the children of the parent, including the current node ([ subchild1, subchild2 ] when called from subchild1) - # * ancestors : Returns all the ancestors of the current node ([child1, root] when called from subchild2) - # * root : Returns the root of the current node (root when called from subchild2) - module ClassMethods - # Configuration options are: - # - # * foreign_key - specifies the column name to use for tracking of the tree (default: parent_id) - # * order - makes it possible to sort the children according to this SQL snippet. - # * counter_cache - keeps a count in a children_count column if set to true (default: false). - def acts_as_tree(options = {}) - configuration = { :foreign_key => "parent_id", :order => nil, :counter_cache => nil } - configuration.update(options) if options.is_a?(Hash) - - belongs_to :parent, :class_name => name, :foreign_key => configuration[:foreign_key], :counter_cache => configuration[:counter_cache] - has_many :children, :class_name => name, :foreign_key => configuration[:foreign_key], :order => configuration[:order], :dependent => true - - module_eval <<-END - def self.roots - self.find(:all, :conditions => "#{configuration[:foreign_key]} IS NULL", :order => #{configuration[:order].nil? ? "nil" : %Q{"#{configuration[:order]}"}}) - end - def self.root - self.find(:first, :conditions => "#{configuration[:foreign_key]} IS NULL", :order => #{configuration[:order].nil? ? "nil" : %Q{"#{configuration[:order]}"}}) - end - END - - # Returns list of ancestors, starting from parent until root. - # - # subchild1.ancestors # => [child1, root] - define_method(:ancestors) do - node, nodes = self, [] - nodes << node = node.parent until not node.has_parent? - nodes - end - - define_method(:root) do - node = self - node = node.parent until not node.has_parent? - node - end - - define_method(:siblings) do - self_and_siblings - [self] - end - - define_method(:self_and_siblings) do - has_parent? ? parent.children : self.class.roots - end - - end - end - end - end -end diff --git a/tracks/vendor/rails/activerecord/lib/active_record/aggregations.rb b/tracks/vendor/rails/activerecord/lib/active_record/aggregations.rb deleted file mode 100644 index 5739fcd8..00000000 --- a/tracks/vendor/rails/activerecord/lib/active_record/aggregations.rb +++ /dev/null @@ -1,166 +0,0 @@ -module ActiveRecord - module Aggregations # :nodoc: - def self.append_features(base) - super - base.extend(ClassMethods) - end - - def clear_aggregation_cache #:nodoc: - self.class.reflect_on_all_aggregations.to_a.each do |assoc| - instance_variable_set "@#{assoc.name}", nil - end unless self.new_record? - end - - # Active Record implements aggregation through a macro-like class method called +composed_of+ for representing attributes - # as value objects. It expresses relationships like "Account [is] composed of Money [among other things]" or "Person [is] - # composed of [an] address". Each call to the macro adds a description of how the value objects are created from the - # attributes of the entity object (when the entity is initialized either as a new object or from finding an existing object) - # and how it can be turned back into attributes (when the entity is saved to the database). Example: - # - # class Customer < ActiveRecord::Base - # composed_of :balance, :class_name => "Money", :mapping => %w(balance amount) - # composed_of :address, :mapping => [ %w(address_street street), %w(address_city city) ] - # end - # - # The customer class now has the following methods to manipulate the value objects: - # * Customer#balance, Customer#balance=(money) - # * Customer#address, Customer#address=(address) - # - # These methods will operate with value objects like the ones described below: - # - # class Money - # include Comparable - # attr_reader :amount, :currency - # EXCHANGE_RATES = { "USD_TO_DKK" => 6 } - # - # def initialize(amount, currency = "USD") - # @amount, @currency = amount, currency - # end - # - # def exchange_to(other_currency) - # exchanged_amount = (amount * EXCHANGE_RATES["#{currency}_TO_#{other_currency}"]).floor - # Money.new(exchanged_amount, other_currency) - # end - # - # def ==(other_money) - # amount == other_money.amount && currency == other_money.currency - # end - # - # def <=>(other_money) - # if currency == other_money.currency - # amount <=> amount - # else - # amount <=> other_money.exchange_to(currency).amount - # end - # end - # end - # - # class Address - # attr_reader :street, :city - # def initialize(street, city) - # @street, @city = street, city - # end - # - # def close_to?(other_address) - # city == other_address.city - # end - # - # def ==(other_address) - # city == other_address.city && street == other_address.street - # end - # end - # - # Now it's possible to access attributes from the database through the value objects instead. If you choose to name the - # composition the same as the attributes name, it will be the only way to access that attribute. That's the case with our - # +balance+ attribute. You interact with the value objects just like you would any other attribute, though: - # - # customer.balance = Money.new(20) # sets the Money value object and the attribute - # customer.balance # => Money value object - # customer.balance.exchanged_to("DKK") # => Money.new(120, "DKK") - # customer.balance > Money.new(10) # => true - # customer.balance == Money.new(20) # => true - # customer.balance < Money.new(5) # => false - # - # Value objects can also be composed of multiple attributes, such as the case of Address. The order of the mappings will - # determine the order of the parameters. Example: - # - # customer.address_street = "Hyancintvej" - # customer.address_city = "Copenhagen" - # customer.address # => Address.new("Hyancintvej", "Copenhagen") - # customer.address = Address.new("May Street", "Chicago") - # customer.address_street # => "May Street" - # customer.address_city # => "Chicago" - # - # == Writing value objects - # - # Value objects are immutable and interchangeable objects that represent a given value, such as a Money object representing - # $5. Two Money objects both representing $5 should be equal (through methods such as == and <=> from Comparable if ranking - # makes sense). This is unlike entity objects where equality is determined by identity. An entity class such as Customer can - # easily have two different objects that both have an address on Hyancintvej. Entity identity is determined by object or - # relational unique identifiers (such as primary keys). Normal ActiveRecord::Base classes are entity objects. - # - # It's also important to treat the value objects as immutable. Don't allow the Money object to have its amount changed after - # creation. Create a new money object with the new value instead. This is exemplified by the Money#exchanged_to method that - # returns a new value object instead of changing its own values. Active Record won't persist value objects that have been - # changed through other means than the writer method. - # - # The immutable requirement is enforced by Active Record by freezing any object assigned as a value object. Attempting to - # change it afterwards will result in a TypeError. - # - # Read more about value objects on http://c2.com/cgi/wiki?ValueObject and on the dangers of not keeping value objects - # immutable on http://c2.com/cgi/wiki?ValueObjectsShouldBeImmutable - module ClassMethods - # Adds the a reader and writer method for manipulating a value object, so - # composed_of :address would add address and address=(new_address). - # - # Options are: - # * :class_name - specify the class name of the association. Use it only if that name can't be inferred - # from the part id. So composed_of :address will by default be linked to the +Address+ class, but - # if the real class name is +CompanyAddress+, you'll have to specify it with this option. - # * :mapping - specifies a number of mapping arrays (attribute, parameter) that bind an attribute name - # to a constructor parameter on the value class. - # - # Option examples: - # composed_of :temperature, :mapping => %w(reading celsius) - # composed_of :balance, :class_name => "Money", :mapping => %w(balance amount) - # composed_of :address, :mapping => [ %w(address_street street), %w(address_city city) ] - # composed_of :gps_location - def composed_of(part_id, options = {}) - options.assert_valid_keys(:class_name, :mapping) - - name = part_id.id2name - class_name = options[:class_name] || name_to_class_name(name) - mapping = options[:mapping] || [ name, name ] - - reader_method(name, class_name, mapping) - writer_method(name, class_name, mapping) - end - - private - def name_to_class_name(name) - name.capitalize.gsub(/_(.)/) { |s| $1.capitalize } - end - - def reader_method(name, class_name, mapping) - module_eval <<-end_eval - def #{name}(force_reload = false) - if @#{name}.nil? || force_reload - @#{name} = #{class_name}.new(#{(Array === mapping.first ? mapping : [ mapping ]).collect{ |pair| "read_attribute(\"#{pair.first}\")"}.join(", ")}) - end - - return @#{name} - end - end_eval - end - - def writer_method(name, class_name, mapping) - module_eval <<-end_eval - def #{name}=(part) - @#{name} = part.freeze - #{(Array === mapping.first ? mapping : [ mapping ]).collect{ |pair| "@attributes[\"#{pair.first}\"] = part.#{pair.last}" }.join("\n")} - end - end_eval - end - end - end -end diff --git a/tracks/vendor/rails/activerecord/lib/active_record/associations.rb b/tracks/vendor/rails/activerecord/lib/active_record/associations.rb deleted file mode 100644 index d8abe822..00000000 --- a/tracks/vendor/rails/activerecord/lib/active_record/associations.rb +++ /dev/null @@ -1,1067 +0,0 @@ -require 'active_record/associations/association_proxy' -require 'active_record/associations/association_collection' -require 'active_record/associations/belongs_to_association' -require 'active_record/associations/has_one_association' -require 'active_record/associations/has_many_association' -require 'active_record/associations/has_and_belongs_to_many_association' -require 'active_record/deprecated_associations' - -module ActiveRecord - module Associations # :nodoc: - def self.append_features(base) - super - base.extend(ClassMethods) - end - - # Clears out the association cache - def clear_association_cache #:nodoc: - self.class.reflect_on_all_associations.to_a.each do |assoc| - instance_variable_set "@#{assoc.name}", nil - end unless self.new_record? - end - - # Associations are a set of macro-like class methods for tying objects together through foreign keys. They express relationships like - # "Project has one Project Manager" or "Project belongs to a Portfolio". Each macro adds a number of methods to the class which are - # specialized according to the collection or association symbol and the options hash. It works much the same way as Ruby's own attr* - # methods. Example: - # - # class Project < ActiveRecord::Base - # belongs_to :portfolio - # has_one :project_manager - # has_many :milestones - # has_and_belongs_to_many :categories - # end - # - # The project class now has the following methods (and more) to ease the traversal and manipulation of its relationships: - # * Project#portfolio, Project#portfolio=(portfolio), Project#portfolio.nil? - # * Project#project_manager, Project#project_manager=(project_manager), Project#project_manager.nil?, - # * Project#milestones.empty?, Project#milestones.size, Project#milestones, Project#milestones<<(milestone), - # Project#milestones.delete(milestone), Project#milestones.find(milestone_id), Project#milestones.find_all(conditions), - # Project#milestones.build, Project#milestones.create - # * Project#categories.empty?, Project#categories.size, Project#categories, Project#categories<<(category1), - # Project#categories.delete(category1) - # - # == Example - # - # link:files/examples/associations.png - # - # == Is it belongs_to or has_one? - # - # Both express a 1-1 relationship, the difference is mostly where to place the foreign key, which goes on the table for the class - # saying belongs_to. Example: - # - # class Post < ActiveRecord::Base - # has_one :author - # end - # - # class Author < ActiveRecord::Base - # belongs_to :post - # end - # - # The tables for these classes could look something like: - # - # CREATE TABLE posts ( - # id int(11) NOT NULL auto_increment, - # title varchar default NULL, - # PRIMARY KEY (id) - # ) - # - # CREATE TABLE authors ( - # id int(11) NOT NULL auto_increment, - # post_id int(11) default NULL, - # name varchar default NULL, - # PRIMARY KEY (id) - # ) - # - # == Unsaved objects and associations - # - # You can manipulate objects and associations before they are saved to the database, but there is some special behaviour you should be - # aware of, mostly involving the saving of associated objects. - # - # === One-to-one associations - # - # * Assigning an object to a has_one association automatically saves that object and the object being replaced (if there is one), in - # order to update their primary keys - except if the parent object is unsaved (new_record? == true). - # * If either of these saves fail (due to one of the objects being invalid) the assignment statement returns false and the assignment - # is cancelled. - # * If you wish to assign an object to a has_one association without saving it, use the #association.build method (documented below). - # * Assigning an object to a belongs_to association does not save the object, since the foreign key field belongs on the parent. It does - # not save the parent either. - # - # === Collections - # - # * Adding an object to a collection (has_many or has_and_belongs_to_many) automatically saves that object, except if the parent object - # (the owner of the collection) is not yet stored in the database. - # * If saving any of the objects being added to a collection (via #push or similar) fails, then #push returns false. - # * You can add an object to a collection without automatically saving it by using the #collection.build method (documented below). - # * All unsaved (new_record? == true) members of the collection are automatically saved when the parent is saved. - # - # === Association callbacks - # - # Similiar to the normal callbacks that hook into the lifecycle of an Active Record object, you can also define callbacks that get - # trigged when you add an object to or removing an object from a association collection. Example: - # - # class Project - # has_and_belongs_to_many :developers, :after_add => :evaluate_velocity - # - # def evaluate_velocity(developer) - # ... - # end - # end - # - # It's possible to stack callbacks by passing them as an array. Example: - # - # class Project - # has_and_belongs_to_many :developers, :after_add => [:evaluate_velocity, Proc.new { |p, d| p.shipping_date = Time.now}] - # end - # - # Possible callbacks are: before_add, after_add, before_remove and after_remove. - # - # Should any of the before_add callbacks throw an exception, the object does not get added to the collection. Same with - # the before_remove callbacks, if an exception is thrown the object doesn't get removed. - # - # === Association extensions - # - # The proxy objects that controls the access to associations can be extended through anonymous modules. This is especially - # beneficial for adding new finders, creators, and other factory-type methods that are only used as part of this associatio. - # Example: - # - # class Account < ActiveRecord::Base - # has_many :people do - # def find_or_create_by_name(name) - # first_name, *last_name = name.split - # last_name = last_name.join " " - # - # find_or_create_by_first_name_and_last_name(first_name, last_name) - # end - # end - # end - # - # person = Account.find(:first).people.find_or_create_by_name("David Heinemeier Hansson") - # person.first_name # => "David" - # person.last_name # => "Heinemeier Hansson" - # - # If you need to share the same extensions between many associations, you can use a named extension module. Example: - # - # module FindOrCreateByNameExtension - # def find_or_create_by_name(name) - # first_name, *last_name = name.split - # last_name = last_name.join " " - # - # find_or_create_by_first_name_and_last_name(first_name, last_name) - # end - # end - # - # class Account < ActiveRecord::Base - # has_many :people, :extend => FindOrCreateByNameExtension - # end - # - # class Company < ActiveRecord::Base - # has_many :people, :extend => FindOrCreateByNameExtension - # end - # - # == Caching - # - # All of the methods are built on a simple caching principle that will keep the result of the last query around unless specifically - # instructed not to. The cache is even shared across methods to make it even cheaper to use the macro-added methods without - # worrying too much about performance at the first go. Example: - # - # project.milestones # fetches milestones from the database - # project.milestones.size # uses the milestone cache - # project.milestones.empty? # uses the milestone cache - # project.milestones(true).size # fetches milestones from the database - # project.milestones # uses the milestone cache - # - # == Eager loading of associations - # - # Eager loading is a way to find objects of a certain class and a number of named associations along with it in a single SQL call. This is - # one of the easiest ways of to prevent the dreaded 1+N problem in which fetching 100 posts that each needs to display their author - # triggers 101 database queries. Through the use of eager loading, the 101 queries can be reduced to 1. Example: - # - # class Post < ActiveRecord::Base - # belongs_to :author - # has_many :comments - # end - # - # Consider the following loop using the class above: - # - # for post in Post.find(:all) - # puts "Post: " + post.title - # puts "Written by: " + post.author.name - # puts "Last comment on: " + post.comments.first.created_on - # end - # - # To iterate over these one hundred posts, we'll generate 201 database queries. Let's first just optimize it for retrieving the author: - # - # for post in Post.find(:all, :include => :author) - # - # This references the name of the belongs_to association that also used the :author symbol, so the find will now weave in a join something - # like this: LEFT OUTER JOIN authors ON authors.id = posts.author_id. Doing so will cut down the number of queries from 201 to 101. - # - # We can improve upon the situation further by referencing both associations in the finder with: - # - # for post in Post.find(:all, :include => [ :author, :comments ]) - # - # That'll add another join along the lines of: LEFT OUTER JOIN comments ON comments.post_id = posts.id. And we'll be down to 1 query. - # But that shouldn't fool you to think that you can pull out huge amounts of data with no performance penalty just because you've reduced - # the number of queries. The database still needs to send all the data to Active Record and it still needs to be processed. So it's no - # catch-all for performance problems, but it's a great way to cut down on the number of queries in a situation as the one described above. - # - # Please note that limited eager loading with has_many and has_and_belongs_to_many associations is not compatible with describing conditions - # on these eager tables. This will work: - # - # Post.find(:all, :include => :comments, :conditions => "posts.title = 'magic forest'", :limit => 2) - # - # ...but this will not (and an ArgumentError will be raised): - # - # Post.find(:all, :include => :comments, :conditions => "comments.body like 'Normal%'", :limit => 2) - # - # Also have in mind that since the eager loading is pulling from multiple tables, you'll have to disambiguate any column references - # in both conditions and orders. So :order => "posts.id DESC" will work while :order => "id DESC" will not. This may require that - # you alter the :order and :conditions on the association definitions themselves. - # - # It's currently not possible to use eager loading on multiple associations from the same table. Eager loading will also not pull - # additional attributes on join tables, so "rich associations" with has_and_belongs_to_many is not a good fit for eager loading. - # - # == Modules - # - # By default, associations will look for objects within the current module scope. Consider: - # - # module MyApplication - # module Business - # class Firm < ActiveRecord::Base - # has_many :clients - # end - # - # class Company < ActiveRecord::Base; end - # end - # end - # - # When Firm#clients is called, it'll in turn call MyApplication::Business::Company.find(firm.id). If you want to associate - # with a class in another module scope this can be done by specifying the complete class name, such as: - # - # module MyApplication - # module Business - # class Firm < ActiveRecord::Base; end - # end - # - # module Billing - # class Account < ActiveRecord::Base - # belongs_to :firm, :class_name => "MyApplication::Business::Firm" - # end - # end - # end - # - # == Type safety with ActiveRecord::AssociationTypeMismatch - # - # If you attempt to assign an object to an association that doesn't match the inferred or specified :class_name, you'll - # get a ActiveRecord::AssociationTypeMismatch. - # - # == Options - # - # All of the association macros can be specialized through options which makes more complex cases than the simple and guessable ones - # possible. - module ClassMethods - # Adds the following methods for retrieval and query of collections of associated objects. - # +collection+ is replaced with the symbol passed as the first argument, so - # has_many :clients would add among others clients.empty?. - # * collection(force_reload = false) - returns an array of all the associated objects. - # An empty array is returned if none are found. - # * collection<<(object, ...) - adds one or more objects to the collection by setting their foreign keys to the collection's primary key. - # * collection.delete(object, ...) - removes one or more objects from the collection by setting their foreign keys to NULL. - # This will also destroy the objects if they're declared as belongs_to and dependent on this model. - # * collection=objects - replaces the collections content by deleting and adding objects as appropriate. - # * collection_singular_ids=ids - replace the collection by the objects identified by the primary keys in +ids+ - # * collection.clear - removes every object from the collection. This destroys the associated objects if they - # are :dependent, deletes them directly from the database if they are :exclusively_dependent, - # and sets their foreign keys to NULL otherwise. - # * collection.empty? - returns true if there are no associated objects. - # * collection.size - returns the number of associated objects. - # * collection.find - finds an associated object according to the same rules as Base.find. - # * collection.build(attributes = {}) - returns a new object of the collection type that has been instantiated - # with +attributes+ and linked to this object through a foreign key but has not yet been saved. *Note:* This only works if an - # associated object already exists, not if it's nil! - # * collection.create(attributes = {}) - returns a new object of the collection type that has been instantiated - # with +attributes+ and linked to this object through a foreign key and that has already been saved (if it passed the validation). - # *Note:* This only works if an associated object already exists, not if it's nil! - # - # Example: A Firm class declares has_many :clients, which will add: - # * Firm#clients (similar to Clients.find :all, :conditions => "firm_id = #{id}") - # * Firm#clients<< - # * Firm#clients.delete - # * Firm#clients= - # * Firm#client_ids= - # * Firm#clients.clear - # * Firm#clients.empty? (similar to firm.clients.size == 0) - # * Firm#clients.size (similar to Client.count "firm_id = #{id}") - # * Firm#clients.find (similar to Client.find(id, :conditions => "firm_id = #{id}")) - # * Firm#clients.build (similar to Client.new("firm_id" => id)) - # * Firm#clients.create (similar to c = Client.new("firm_id" => id); c.save; c) - # The declaration can also include an options hash to specialize the behavior of the association. - # - # Options are: - # * :class_name - specify the class name of the association. Use it only if that name can't be inferred - # from the association name. So has_many :products will by default be linked to the +Product+ class, but - # if the real class name is +SpecialProduct+, you'll have to specify it with this option. - # * :conditions - specify the conditions that the associated objects must meet in order to be included as a "WHERE" - # sql fragment, such as "price > 5 AND name LIKE 'B%'". - # * :order - specify the order in which the associated objects are returned as a "ORDER BY" sql fragment, - # such as "last_name, first_name DESC" - # * :group - specify the attribute by which the associated objects are returned as a "GROUP BY" sql fragment, - # such as "category" - # * :foreign_key - specify the foreign key used for the association. By default this is guessed to be the name - # of this class in lower-case and "_id" suffixed. So a +Person+ class that makes a has_many association will use "person_id" - # as the default foreign_key. - # * :dependent - if set to :destroy (or true) all the associated objects are destroyed - # alongside this object by calling their destroy method. If set to :delete_all all associated - # objects are deleted *without* calling their destroy method. If set to :nullify all associated - # objects' foreign keys are set to NULL *without* calling their save callbacks. - # May not be set if :exclusively_dependent is also set. - # * :exclusively_dependent - Deprecated; equivalent to :dependent => :delete_all. If set to true all - # the associated object are deleted in one SQL statement without having their - # before_destroy callback run. This should only be used on associations that depend solely on this class and don't need to do any - # clean-up in before_destroy. The upside is that it's much faster, especially if there's a counter_cache involved. - # May not be set if :dependent is also set. - # * :finder_sql - specify a complete SQL statement to fetch the association. This is a good way to go for complex - # associations that depend on multiple tables. Note: When this option is used, +find_in_collection+ is _not_ added. - # * :counter_sql - specify a complete SQL statement to fetch the size of the association. If +:finder_sql+ is - # specified but +:counter_sql+, +:counter_sql+ will be generated by replacing SELECT ... FROM with SELECT COUNT(*) FROM. - # * :extend - specify a named module for extending the proxy, see "Association extensions". - # * :include - specify second-order associations that should be eager loaded when the collection is loaded. - # - # Option examples: - # has_many :comments, :order => "posted_on" - # has_many :comments, :include => :author - # has_many :people, :class_name => "Person", :conditions => "deleted = 0", :order => "name" - # has_many :tracks, :order => "position", :dependent => true - # has_many :subscribers, :class_name => "Person", :finder_sql => - # 'SELECT DISTINCT people.* ' + - # 'FROM people p, post_subscriptions ps ' + - # 'WHERE ps.post_id = #{id} AND ps.person_id = p.id ' + - # 'ORDER BY p.first_name' - def has_many(association_id, options = {}, &extension) - options.assert_valid_keys( - :foreign_key, :class_name, :exclusively_dependent, :dependent, - :conditions, :order, :include, :finder_sql, :counter_sql, - :before_add, :after_add, :before_remove, :after_remove, :extend, - :group - ) - - options[:extend] = create_extension_module(association_id, extension) if block_given? - - association_name, association_class_name, association_class_primary_key_name = - associate_identification(association_id, options[:class_name], options[:foreign_key]) - - require_association_class(association_class_name) - - raise ArgumentError, ':dependent and :exclusively_dependent are mutually exclusive options. You may specify one or the other.' if options[:dependent] and options[:exclusively_dependent] - - if options[:exclusively_dependent] - options[:dependent] = :delete_all - #warn "The :exclusively_dependent option is deprecated. Please use :dependent => :delete_all instead.") - end - - # See HasManyAssociation#delete_records. Dependent associations - # delete children, otherwise foreign key is set to NULL. - case options[:dependent] - when :destroy, true - module_eval "before_destroy '#{association_name}.each { |o| o.destroy }'" - when :delete_all - module_eval "before_destroy { |record| #{association_class_name}.delete_all(%(#{association_class_primary_key_name} = \#{record.quoted_id})) }" - when :nullify - module_eval "before_destroy { |record| #{association_class_name}.update_all(%(#{association_class_primary_key_name} = NULL), %(#{association_class_primary_key_name} = \#{record.quoted_id})) }" - when nil, false - # pass - else - raise ArgumentError, 'The :dependent option expects either true, :destroy, :delete_all, or :nullify' - end - - - add_multiple_associated_save_callbacks(association_name) - add_association_callbacks(association_name, options) - - collection_accessor_methods(association_name, association_class_name, association_class_primary_key_name, options, HasManyAssociation) - - # deprecated api - deprecated_collection_count_method(association_name) - deprecated_add_association_relation(association_name) - deprecated_remove_association_relation(association_name) - deprecated_has_collection_method(association_name) - deprecated_find_in_collection_method(association_name) - deprecated_find_all_in_collection_method(association_name) - deprecated_collection_create_method(association_name) - deprecated_collection_build_method(association_name) - end - - # Adds the following methods for retrieval and query of a single associated object. - # +association+ is replaced with the symbol passed as the first argument, so - # has_one :manager would add among others manager.nil?. - # * association(force_reload = false) - returns the associated object. Nil is returned if none is found. - # * association=(associate) - assigns the associate object, extracts the primary key, sets it as the foreign key, - # and saves the associate object. - # * association.nil? - returns true if there is no associated object. - # * build_association(attributes = {}) - returns a new object of the associated type that has been instantiated - # with +attributes+ and linked to this object through a foreign key but has not yet been saved. Note: This ONLY works if - # an association already exists. It will NOT work if the association is nil. - # * create_association(attributes = {}) - returns a new object of the associated type that has been instantiated - # with +attributes+ and linked to this object through a foreign key and that has already been saved (if it passed the validation). - # - # Example: An Account class declares has_one :beneficiary, which will add: - # * Account#beneficiary (similar to Beneficiary.find(:first, :conditions => "account_id = #{id}")) - # * Account#beneficiary=(beneficiary) (similar to beneficiary.account_id = account.id; beneficiary.save) - # * Account#beneficiary.nil? - # * Account#build_beneficiary (similar to Beneficiary.new("account_id" => id)) - # * Account#create_beneficiary (similar to b = Beneficiary.new("account_id" => id); b.save; b) - # - # The declaration can also include an options hash to specialize the behavior of the association. - # - # Options are: - # * :class_name - specify the class name of the association. Use it only if that name can't be inferred - # from the association name. So has_one :manager will by default be linked to the +Manager+ class, but - # if the real class name is +Person+, you'll have to specify it with this option. - # * :conditions - specify the conditions that the associated object must meet in order to be included as a "WHERE" - # sql fragment, such as "rank = 5". - # * :order - specify the order from which the associated object will be picked at the top. Specified as - # an "ORDER BY" sql fragment, such as "last_name, first_name DESC" - # * :dependent - if set to :destroy (or true) all the associated objects are destroyed when this object is. Also, - # association is assigned. - # * :foreign_key - specify the foreign key used for the association. By default this is guessed to be the name - # of this class in lower-case and "_id" suffixed. So a +Person+ class that makes a has_one association will use "person_id" - # as the default foreign_key. - # * :include - specify second-order associations that should be eager loaded when this object is loaded. - # - # Option examples: - # has_one :credit_card, :dependent => true - # has_one :last_comment, :class_name => "Comment", :order => "posted_on" - # has_one :project_manager, :class_name => "Person", :conditions => "role = 'project_manager'" - def has_one(association_id, options = {}) - options.assert_valid_keys(:class_name, :foreign_key, :remote, :conditions, :order, :include, :dependent, :counter_cache, :extend) - - association_name, association_class_name, association_class_primary_key_name = - associate_identification(association_id, options[:class_name], options[:foreign_key], false) - - require_association_class(association_class_name) - - module_eval do - after_save <<-EOF - association = instance_variable_get("@#{association_name}") - unless association.nil? - association["#{association_class_primary_key_name}"] = id - association.save(true) - association.send(:construct_sql) - end - EOF - end - - association_accessor_methods(association_name, association_class_name, association_class_primary_key_name, options, HasOneAssociation) - association_constructor_method(:build, association_name, association_class_name, association_class_primary_key_name, options, HasOneAssociation) - association_constructor_method(:create, association_name, association_class_name, association_class_primary_key_name, options, HasOneAssociation) - - case options[:dependent] - when :destroy, true - module_eval "before_destroy '#{association_name}.destroy unless #{association_name}.nil?'" - when :nullify - module_eval "before_destroy '#{association_name}.update_attribute(\"#{association_class_primary_key_name}\", nil)'" - when nil, false - # pass - else - raise ArgumentError, "The :dependent option expects either :destroy or :nullify." - end - - # deprecated api - deprecated_has_association_method(association_name) - deprecated_association_comparison_method(association_name, association_class_name) - end - - # Adds the following methods for retrieval and query for a single associated object that this object holds an id to. - # +association+ is replaced with the symbol passed as the first argument, so - # belongs_to :author would add among others author.nil?. - # * association(force_reload = false) - returns the associated object. Nil is returned if none is found. - # * association=(associate) - assigns the associate object, extracts the primary key, and sets it as the foreign key. - # * association.nil? - returns true if there is no associated object. - # * build_association(attributes = {}) - returns a new object of the associated type that has been instantiated - # with +attributes+ and linked to this object through a foreign key but has not yet been saved. - # * create_association(attributes = {}) - returns a new object of the associated type that has been instantiated - # with +attributes+ and linked to this object through a foreign key and that has already been saved (if it passed the validation). - # - # Example: A Post class declares belongs_to :author, which will add: - # * Post#author (similar to Author.find(author_id)) - # * Post#author=(author) (similar to post.author_id = author.id) - # * Post#author? (similar to post.author == some_author) - # * Post#author.nil? - # * Post#build_author (similar to post.author = Author.new) - # * Post#create_author (similar to post.author = Author.new; post.author.save; post.author) - # The declaration can also include an options hash to specialize the behavior of the association. - # - # Options are: - # * :class_name - specify the class name of the association. Use it only if that name can't be inferred - # from the association name. So has_one :author will by default be linked to the +Author+ class, but - # if the real class name is +Person+, you'll have to specify it with this option. - # * :conditions - specify the conditions that the associated object must meet in order to be included as a "WHERE" - # sql fragment, such as "authorized = 1". - # * :order - specify the order from which the associated object will be picked at the top. Specified as - # an "ORDER BY" sql fragment, such as "last_name, first_name DESC" - # * :foreign_key - specify the foreign key used for the association. By default this is guessed to be the name - # of the associated class in lower-case and "_id" suffixed. So a +Person+ class that makes a belongs_to association to a - # +Boss+ class will use "boss_id" as the default foreign_key. - # * :counter_cache - caches the number of belonging objects on the associate class through use of increment_counter - # and decrement_counter. The counter cache is incremented when an object of this class is created and decremented when it's - # destroyed. This requires that a column named "#{table_name}_count" (such as comments_count for a belonging Comment class) - # is used on the associate class (such as a Post class). - # * :include - specify second-order associations that should be eager loaded when this object is loaded. - # - # Option examples: - # belongs_to :firm, :foreign_key => "client_of" - # belongs_to :author, :class_name => "Person", :foreign_key => "author_id" - # belongs_to :valid_coupon, :class_name => "Coupon", :foreign_key => "coupon_id", - # :conditions => 'discounts > #{payments_count}' - def belongs_to(association_id, options = {}) - options.assert_valid_keys(:class_name, :foreign_key, :remote, :conditions, :order, :include, :dependent, :counter_cache, :extend) - - association_name, association_class_name, class_primary_key_name = - associate_identification(association_id, options[:class_name], options[:foreign_key], false) - - require_association_class(association_class_name) - - association_class_primary_key_name = options[:foreign_key] || association_class_name.foreign_key - - association_accessor_methods(association_name, association_class_name, association_class_primary_key_name, options, BelongsToAssociation) - association_constructor_method(:build, association_name, association_class_name, association_class_primary_key_name, options, BelongsToAssociation) - association_constructor_method(:create, association_name, association_class_name, association_class_primary_key_name, options, BelongsToAssociation) - - module_eval do - before_save <<-EOF - association = instance_variable_get("@#{association_name}") - if not association.nil? - if association.new_record? - association.save(true) - association.send(:construct_sql) - end - self["#{association_class_primary_key_name}"] = association.id if association.updated? - end - EOF - end - - if options[:counter_cache] - module_eval( - "after_create '#{association_class_name}.increment_counter(\"#{self.to_s.underscore.pluralize + "_count"}\", #{association_class_primary_key_name})" + - " unless #{association_name}.nil?'" - ) - - module_eval( - "before_destroy '#{association_class_name}.decrement_counter(\"#{self.to_s.underscore.pluralize + "_count"}\", #{association_class_primary_key_name})" + - " unless #{association_name}.nil?'" - ) - end - - # deprecated api - deprecated_has_association_method(association_name) - deprecated_association_comparison_method(association_name, association_class_name) - end - - # Associates two classes via an intermediate join table. Unless the join table is explicitly specified as - # an option, it is guessed using the lexical order of the class names. So a join between Developer and Project - # will give the default join table name of "developers_projects" because "D" outranks "P". - # - # Any additional fields added to the join table will be placed as attributes when pulling records out through - # has_and_belongs_to_many associations. This is helpful when have information about the association itself - # that you want available on retrieval. Note that any fields in the join table will override matching field names - # in the two joined tables. As a consequence, having an "id" field in the join table usually has the undesirable - # result of clobbering the "id" fields in either of the other two tables. - # - # Adds the following methods for retrieval and query. - # +collection+ is replaced with the symbol passed as the first argument, so - # has_and_belongs_to_many :categories would add among others categories.empty?. - # * collection(force_reload = false) - returns an array of all the associated objects. - # An empty array is returned if none is found. - # * collection<<(object, ...) - adds one or more objects to the collection by creating associations in the join table - # (collection.push and collection.concat are aliases to this method). - # * collection.push_with_attributes(object, join_attributes) - adds one to the collection by creating an association in the join table that - # also holds the attributes from join_attributes (should be a hash with the column names as keys). This can be used to have additional - # attributes on the join, which will be injected into the associated objects when they are retrieved through the collection. - # (collection.concat_with_attributes is an alias to this method). - # * collection.delete(object, ...) - removes one or more objects from the collection by removing their associations from the join table. - # This does not destroy the objects. - # * collection=objects - replaces the collections content by deleting and adding objects as appropriate. - # * collection_singular_ids=ids - replace the collection by the objects identified by the primary keys in +ids+ - # * collection.clear - removes every object from the collection. This does not destroy the objects. - # * collection.empty? - returns true if there are no associated objects. - # * collection.size - returns the number of associated objects. - # * collection.find(id) - finds an associated object responding to the +id+ and that - # meets the condition that it has to be associated with this object. - # - # Example: An Developer class declares has_and_belongs_to_many :projects, which will add: - # * Developer#projects - # * Developer#projects<< - # * Developer#projects.push_with_attributes - # * Developer#projects.delete - # * Developer#projects= - # * Developer#project_ids= - # * Developer#projects.clear - # * Developer#projects.empty? - # * Developer#projects.size - # * Developer#projects.find(id) - # The declaration may include an options hash to specialize the behavior of the association. - # - # Options are: - # * :class_name - specify the class name of the association. Use it only if that name can't be inferred - # from the association name. So has_and_belongs_to_many :projects will by default be linked to the - # +Project+ class, but if the real class name is +SuperProject+, you'll have to specify it with this option. - # * :join_table - specify the name of the join table if the default based on lexical order isn't what you want. - # WARNING: If you're overwriting the table name of either class, the table_name method MUST be declared underneath any - # has_and_belongs_to_many declaration in order to work. - # * :foreign_key - specify the foreign key used for the association. By default this is guessed to be the name - # of this class in lower-case and "_id" suffixed. So a +Person+ class that makes a has_and_belongs_to_many association - # will use "person_id" as the default foreign_key. - # * :association_foreign_key - specify the association foreign key used for the association. By default this is - # guessed to be the name of the associated class in lower-case and "_id" suffixed. So if the associated class is +Project+, - # the has_and_belongs_to_many association will use "project_id" as the default association foreign_key. - # * :conditions - specify the conditions that the associated object must meet in order to be included as a "WHERE" - # sql fragment, such as "authorized = 1". - # * :order - specify the order in which the associated objects are returned as a "ORDER BY" sql fragment, such as "last_name, first_name DESC" - # * :uniq - if set to true, duplicate associated objects will be ignored by accessors and query methods - # * :finder_sql - overwrite the default generated SQL used to fetch the association with a manual one - # * :delete_sql - overwrite the default generated SQL used to remove links between the associated - # classes with a manual one - # * :insert_sql - overwrite the default generated SQL used to add links between the associated classes - # with a manual one - # * :extend - anonymous module for extending the proxy, see "Association extensions". - # * :include - specify second-order associations that should be eager loaded when the collection is loaded. - # - # Option examples: - # has_and_belongs_to_many :projects - # has_and_belongs_to_many :projects, :include => [ :milestones, :manager ] - # has_and_belongs_to_many :nations, :class_name => "Country" - # has_and_belongs_to_many :categories, :join_table => "prods_cats" - # has_and_belongs_to_many :active_projects, :join_table => 'developers_projects', :delete_sql => - # 'DELETE FROM developers_projects WHERE active=1 AND developer_id = #{id} AND project_id = #{record.id}' - def has_and_belongs_to_many(association_id, options = {}, &extension) - options.assert_valid_keys( - :class_name, :table_name, :foreign_key, :association_foreign_key, :conditions, :include, - :join_table, :finder_sql, :delete_sql, :insert_sql, :order, :uniq, :before_add, :after_add, - :before_remove, :after_remove, :extend - ) - - options[:extend] = create_extension_module(association_id, extension) if block_given? - - association_name, association_class_name, association_class_primary_key_name = - associate_identification(association_id, options[:class_name], options[:foreign_key]) - - require_association_class(association_class_name) - - options[:join_table] ||= join_table_name(undecorated_table_name(self.to_s), undecorated_table_name(association_class_name)) - - add_multiple_associated_save_callbacks(association_name) - - collection_accessor_methods(association_name, association_class_name, association_class_primary_key_name, options, HasAndBelongsToManyAssociation) - - # Don't use a before_destroy callback since users' before_destroy - # callbacks will be executed after the association is wiped out. - old_method = "destroy_without_habtm_shim_for_#{association_name}" - class_eval <<-end_eval - alias_method :#{old_method}, :destroy_without_callbacks - def destroy_without_callbacks - #{association_name}.clear - #{old_method} - end - end_eval - - add_association_callbacks(association_name, options) - - # deprecated api - deprecated_collection_count_method(association_name) - deprecated_add_association_relation(association_name) - deprecated_remove_association_relation(association_name) - deprecated_has_collection_method(association_name) - end - - private - def join_table_name(first_table_name, second_table_name) - if first_table_name < second_table_name - join_table = "#{first_table_name}_#{second_table_name}" - else - join_table = "#{second_table_name}_#{first_table_name}" - end - - table_name_prefix + join_table + table_name_suffix - end - - def associate_identification(association_id, association_class_name, foreign_key, plural = true) - if association_class_name !~ /::/ - association_class_name = type_name_with_module( - association_class_name || - Inflector.camelize(plural ? Inflector.singularize(association_id.id2name) : association_id.id2name) - ) - end - - primary_key_name = foreign_key || name.foreign_key - - return association_id.id2name, association_class_name, primary_key_name - end - - def association_accessor_methods(association_name, association_class_name, association_class_primary_key_name, options, association_proxy_class) - define_method(association_name) do |*params| - force_reload = params.first unless params.empty? - association = instance_variable_get("@#{association_name}") - if association.nil? or force_reload - association = association_proxy_class.new(self, - association_name, association_class_name, - association_class_primary_key_name, options) - retval = association.reload - unless retval.nil? - instance_variable_set("@#{association_name}", association) - else - instance_variable_set("@#{association_name}", nil) - return nil - end - end - association - end - - define_method("#{association_name}=") do |new_value| - association = instance_variable_get("@#{association_name}") - if association.nil? - association = association_proxy_class.new(self, - association_name, association_class_name, - association_class_primary_key_name, options) - end - association.replace(new_value) - unless new_value.nil? - instance_variable_set("@#{association_name}", association) - else - instance_variable_set("@#{association_name}", nil) - return nil - end - association - end - - define_method("set_#{association_name}_target") do |target| - return if target.nil? - association = association_proxy_class.new(self, - association_name, association_class_name, - association_class_primary_key_name, options) - association.target = target - instance_variable_set("@#{association_name}", association) - end - end - - def collection_accessor_methods(association_name, association_class_name, association_class_primary_key_name, options, association_proxy_class) - define_method(association_name) do |*params| - force_reload = params.first unless params.empty? - association = instance_variable_get("@#{association_name}") - unless association.respond_to?(:loaded?) - association = association_proxy_class.new(self, - association_name, association_class_name, - association_class_primary_key_name, options) - instance_variable_set("@#{association_name}", association) - end - association.reload if force_reload - association - end - - define_method("#{association_name}=") do |new_value| - association = instance_variable_get("@#{association_name}") - unless association.respond_to?(:loaded?) - association = association_proxy_class.new(self, - association_name, association_class_name, - association_class_primary_key_name, options) - instance_variable_set("@#{association_name}", association) - end - association.replace(new_value) - association - end - - define_method("#{Inflector.singularize(association_name)}_ids=") do |new_value| - send("#{association_name}=", association_class_name.constantize.find(new_value)) - end - end - - def require_association_class(class_name) - require_association(Inflector.underscore(class_name)) if class_name - end - - def add_multiple_associated_save_callbacks(association_name) - method_name = "validate_associated_records_for_#{association_name}".to_sym - define_method(method_name) do - @new_record_before_save = new_record? - association = instance_variable_get("@#{association_name}") - if association.respond_to?(:loaded?) - if new_record? - association - else - association.select { |record| record.new_record? } - end.each do |record| - errors.add "#{association_name}" unless record.valid? - end - end - end - - validate method_name - - after_callback = <<-end_eval - association = instance_variable_get("@#{association_name}") - if association.respond_to?(:loaded?) - if @new_record_before_save - records_to_save = association - else - records_to_save = association.select { |record| record.new_record? } - end - records_to_save.each { |record| association.send(:insert_record, record) } - association.send(:construct_sql) # reconstruct the SQL queries now that we know the owner's id - end - - @new_record_before_save = false - true - end_eval - - # Doesn't use after_save as that would save associations added in after_create/after_update twice - after_create(after_callback) - after_update(after_callback) - end - - def association_constructor_method(constructor, association_name, association_class_name, association_class_primary_key_name, options, association_proxy_class) - define_method("#{constructor}_#{association_name}") do |*params| - attributees = params.first unless params.empty? - replace_existing = params[1].nil? ? true : params[1] - association = instance_variable_get("@#{association_name}") - - if association.nil? - association = association_proxy_class.new(self, - association_name, association_class_name, - association_class_primary_key_name, options) - instance_variable_set("@#{association_name}", association) - end - - if association_proxy_class == HasOneAssociation - association.send(constructor, attributees, replace_existing) - else - association.send(constructor, attributees) - end - end - end - - def find_with_associations(options = {}) - reflections = reflect_on_included_associations(options[:include]) - - guard_against_missing_reflections(reflections, options) - - schema_abbreviations = generate_schema_abbreviations(reflections) - primary_key_table = generate_primary_key_table(reflections, schema_abbreviations) - - rows = select_all_rows(options, schema_abbreviations, reflections) - records, records_in_order = { }, [] - primary_key = primary_key_table[table_name] - - for row in rows - id = row[primary_key] - records_in_order << (records[id] = instantiate(extract_record(schema_abbreviations, table_name, row))) unless records[id] - record = records[id] - - reflections.each do |reflection| - case reflection.macro - when :has_many, :has_and_belongs_to_many - collection = record.send(reflection.name) - collection.loaded - - next unless row[primary_key_table[reflection.table_name]] - - association = reflection.klass.send(:instantiate, extract_record(schema_abbreviations, reflection.table_name, row)) - collection.target.push(association) unless collection.target.include?(association) - when :has_one, :belongs_to - next unless row[primary_key_table[reflection.table_name]] - - record.send( - "set_#{reflection.name}_target", - reflection.klass.send(:instantiate, extract_record(schema_abbreviations, reflection.table_name, row)) - ) - end - end - end - - return records_in_order - end - - - def reflect_on_included_associations(associations) - [ associations ].flatten.collect { |association| reflect_on_association(association.to_s.intern) } - end - - def guard_against_missing_reflections(reflections, options) - reflections.each do |r| - raise( - ConfigurationError, - "Association was not found; perhaps you misspelled it? " + - "You specified :include => :#{[options[:include]].flatten.join(', :')}" - ) if r.nil? - end - end - - def guard_against_unlimitable_reflections(reflections, options) - if (options[:offset] || options[:limit]) && !using_limitable_reflections?(reflections) - raise( - ConfigurationError, - "You can not use offset and limit together with has_many or has_and_belongs_to_many associations" - ) - end - end - - def generate_schema_abbreviations(reflections) - schema = [ [ table_name, column_names ] ] - schema += reflections.collect { |r| [ r.table_name, r.klass.column_names ] } - - schema_abbreviations = {} - schema.each_with_index do |table_and_columns, i| - table, columns = table_and_columns - columns.each_with_index { |column, j| schema_abbreviations["t#{i}_r#{j}"] = [ table, column ] } - end - - return schema_abbreviations - end - - def generate_primary_key_table(reflections, schema_abbreviations) - primary_key_lookup_table = {} - primary_key_lookup_table[table_name] = - schema_abbreviations.find { |cn, tc| tc == [ table_name, primary_key ] }.first - - reflections.collect do |reflection| - primary_key_lookup_table[reflection.klass.table_name] = schema_abbreviations.find { |cn, tc| - tc == [ reflection.klass.table_name, reflection.klass.primary_key ] - }.first - end - - return primary_key_lookup_table - end - - - def select_all_rows(options, schema_abbreviations, reflections) - connection.select_all( - construct_finder_sql_with_included_associations(options, schema_abbreviations, reflections), - "#{name} Load Including Associations" - ) - end - - def construct_finder_sql_with_included_associations(options, schema_abbreviations, reflections) - sql = "SELECT #{column_aliases(schema_abbreviations)} FROM #{table_name} " - sql << reflections.collect { |reflection| association_join(reflection) }.to_s - sql << "#{options[:joins]} " if options[:joins] - - add_conditions!(sql, options[:conditions]) - add_sti_conditions!(sql, reflections) - add_limited_ids_condition!(sql, options) if !using_limitable_reflections?(reflections) && options[:limit] - - sql << "ORDER BY #{options[:order]} " if options[:order] - - add_limit!(sql, options) if using_limitable_reflections?(reflections) - - return sanitize_sql(sql) - end - - def add_limited_ids_condition!(sql, options) - unless (id_list = select_limited_ids_list(options)).empty? - sql << "#{condition_word(sql)} #{table_name}.#{primary_key} IN (#{id_list}) " - end - end - - def select_limited_ids_list(options) - connection.select_values( - construct_finder_sql_for_association_limiting(options), - "#{name} Load IDs For Limited Eager Loading" - ).collect { |id| connection.quote(id) }.join(", ") - end - - def construct_finder_sql_for_association_limiting(options) - raise(ArgumentError, "Limited eager loads and conditions on the eager tables is incompatible") if include_eager_conditions?(options) - - sql = "SELECT #{primary_key} FROM #{table_name} " - add_conditions!(sql, options[:conditions]) - sql << "ORDER BY #{options[:order]} " if options[:order] - add_limit!(sql, options) - return sanitize_sql(sql) - end - - def include_eager_conditions?(options) - conditions = options[:conditions] - return false unless conditions - conditions = conditions.first if conditions.is_a?(Array) - conditions.scan(/(\w+)\.\w+/).flatten.any? do |condition_table_name| - condition_table_name != table_name - end - end - - def using_limitable_reflections?(reflections) - reflections.reject { |r| [ :belongs_to, :has_one ].include?(r.macro) }.length.zero? - end - - def add_sti_conditions!(sql, reflections) - sti_conditions = reflections.collect do |reflection| - reflection.klass.send(:type_condition) unless reflection.klass.descends_from_active_record? - end.compact - - unless sti_conditions.empty? - sql << condition_word(sql) + sti_conditions.join(" AND ") - end - end - - def column_aliases(schema_abbreviations) - schema_abbreviations.collect { |cn, tc| "#{tc[0]}.#{connection.quote_column_name tc[1]} AS #{cn}" }.join(", ") - end - - def association_join(reflection) - case reflection.macro - when :has_and_belongs_to_many - " LEFT OUTER JOIN #{reflection.options[:join_table]} ON " + - "#{reflection.options[:join_table]}.#{reflection.options[:foreign_key] || table_name.classify.foreign_key} = " + - "#{table_name}.#{primary_key} " + - " LEFT OUTER JOIN #{reflection.klass.table_name} ON " + - "#{reflection.options[:join_table]}.#{reflection.options[:association_foreign_key] || reflection.klass.table_name.classify.foreign_key} = " + - "#{reflection.klass.table_name}.#{reflection.klass.primary_key} " - when :has_many, :has_one - " LEFT OUTER JOIN #{reflection.klass.table_name} ON " + - "#{reflection.klass.table_name}.#{reflection.options[:foreign_key] || table_name.classify.foreign_key} = " + - "#{table_name}.#{primary_key} " - when :belongs_to - " LEFT OUTER JOIN #{reflection.klass.table_name} ON " + - "#{reflection.klass.table_name}.#{reflection.klass.primary_key} = " + - "#{table_name}.#{reflection.options[:foreign_key] || reflection.klass.table_name.classify.foreign_key} " - else - "" - end - end - - def add_association_callbacks(association_name, options) - callbacks = %w(before_add after_add before_remove after_remove) - callbacks.each do |callback_name| - full_callback_name = "#{callback_name.to_s}_for_#{association_name.to_s}" - defined_callbacks = options[callback_name.to_sym] - if options.has_key?(callback_name.to_sym) - class_inheritable_reader full_callback_name.to_sym - write_inheritable_array(full_callback_name.to_sym, [defined_callbacks].flatten) - end - end - end - - def extract_record(schema_abbreviations, table_name, row) - record = {} - row.each do |column, value| - prefix, column_name = schema_abbreviations[column] - record[column_name] = value if prefix == table_name - end - return record - end - - def condition_word(sql) - sql =~ /where/i ? " AND " : "WHERE " - end - - def create_extension_module(association_id, extension) - extension_module_name = "#{self.to_s}#{association_id.to_s.camelize}AssociationExtension" - - silence_warnings do - Object.const_set(extension_module_name, Module.new(&extension)) - end - - extension_module_name.constantize - end - end - end -end diff --git a/tracks/vendor/rails/activerecord/lib/active_record/associations/association_collection.rb b/tracks/vendor/rails/activerecord/lib/active_record/associations/association_collection.rb deleted file mode 100644 index 7ee567e0..00000000 --- a/tracks/vendor/rails/activerecord/lib/active_record/associations/association_collection.rb +++ /dev/null @@ -1,164 +0,0 @@ -require 'set' - -module ActiveRecord - module Associations - class AssociationCollection < AssociationProxy #:nodoc: - def to_ary - load_target - @target.to_ary - end - - def reset - @target = [] - @loaded = false - end - - # Add +records+ to this association. Returns +self+ so method calls may be chained. - # Since << flattens its argument list and inserts each record, +push+ and +concat+ behave identically. - def <<(*records) - result = true - load_target - @owner.transaction do - flatten_deeper(records).each do |record| - raise_on_type_mismatch(record) - callback(:before_add, record) - result &&= insert_record(record) unless @owner.new_record? - @target << record - callback(:after_add, record) - end - end - - result and self - end - - alias_method :push, :<< - alias_method :concat, :<< - - # Remove all records from this association - def delete_all - delete(@target) - @target = [] - end - - # Remove +records+ from this association. Does not destroy +records+. - def delete(*records) - records = flatten_deeper(records) - records.each { |record| raise_on_type_mismatch(record) } - records.reject! { |record| @target.delete(record) if record.new_record? } - return if records.empty? - - @owner.transaction do - records.each { |record| callback(:before_remove, record) } - delete_records(records) - records.each do |record| - @target.delete(record) - callback(:after_remove, record) - end - end - end - - # Removes all records from this association. Returns +self+ so method calls may be chained. - def clear - return self if length.zero? # forces load_target if hasn't happened already - if @options[:exclusively_dependent] - destroy_all - else - delete_all - end - self - end - - def destroy_all - @owner.transaction do - each { |record| record.destroy } - end - - @target = [] - end - - def create(attributes = {}) - # Can't use Base.create since the foreign key may be a protected attribute. - if attributes.is_a?(Array) - attributes.collect { |attr| create(attr) } - else - record = build(attributes) - record.save unless @owner.new_record? - record - end - end - - # Returns the size of the collection by executing a SELECT COUNT(*) query if the collection hasn't been loaded and - # calling collection.size if it has. If it's more likely than not that the collection does have a size larger than zero - # and you need to fetch that collection afterwards, it'll take one less SELECT query if you use length. - def size - if loaded? then @target.size else count_records end - end - - # Returns the size of the collection by loading it and calling size on the array. If you want to use this method to check - # whether the collection is empty, use collection.length.zero? instead of collection.empty? - def length - load_target.size - end - - def empty? - size.zero? - end - - def uniq(collection = self) - collection.inject([]) { |uniq_records, record| uniq_records << record unless uniq_records.include?(record); uniq_records } - end - - # Replace this collection with +other_array+ - # This will perform a diff and delete/add only records that have changed. - def replace(other_array) - other_array.each { |val| raise_on_type_mismatch(val) } - - load_target - other = other_array.size < 100 ? other_array : other_array.to_set - current = @target.size < 100 ? @target : @target.to_set - - @owner.transaction do - delete(@target.select { |v| !other.include?(v) }) - concat(other_array.select { |v| !current.include?(v) }) - end - end - - private - def raise_on_type_mismatch(record) - raise ActiveRecord::AssociationTypeMismatch, "#{@association_class} expected, got #{record.class}" unless record.is_a?(@association_class) - end - - def target_obsolete? - false - end - - # Array#flatten has problems with recursive arrays. Going one level deeper solves the majority of the problems. - def flatten_deeper(array) - array.collect { |element| element.respond_to?(:flatten) ? element.flatten : element }.flatten - end - - def callback(method, record) - callbacks_for(method).each do |callback| - case callback - when Symbol - @owner.send(callback, record) - when Proc, Method - callback.call(@owner, record) - else - if callback.respond_to?(method) - callback.send(method, @owner, record) - else - raise ActiveRecordError, "Callbacks must be a symbol denoting the method to call, a string to be evaluated, a block to be invoked, or an object responding to the callback method." - end - end - end - end - - def callbacks_for(callback_name) - full_callback_name = "#{callback_name.to_s}_for_#{@association_name.to_s}" - @owner.class.read_inheritable_attribute(full_callback_name.to_sym) or [] - end - - end - end -end diff --git a/tracks/vendor/rails/activerecord/lib/active_record/associations/association_proxy.rb b/tracks/vendor/rails/activerecord/lib/active_record/associations/association_proxy.rb deleted file mode 100644 index 82452348..00000000 --- a/tracks/vendor/rails/activerecord/lib/active_record/associations/association_proxy.rb +++ /dev/null @@ -1,101 +0,0 @@ -module ActiveRecord - module Associations - class AssociationProxy #:nodoc: - alias_method :proxy_respond_to?, :respond_to? - alias_method :proxy_extend, :extend - instance_methods.each { |m| undef_method m unless m =~ /(^__|^nil\?|^proxy_respond_to\?|^proxy_extend|^send)/ } - - def initialize(owner, association_name, association_class_name, association_class_primary_key_name, options) - @owner = owner - @options = options - @association_name = association_name - @association_class = eval(association_class_name, nil, __FILE__, __LINE__) - @association_class_primary_key_name = association_class_primary_key_name - - proxy_extend(options[:extend]) if options[:extend] - - reset - end - - def reload - reset - load_target - end - - def respond_to?(symbol, include_priv = false) - proxy_respond_to?(symbol, include_priv) || (load_target && @target.respond_to?(symbol, include_priv)) - end - - def loaded? - @loaded - end - - def loaded - @loaded = true - end - - def target - @target - end - - def target=(t) - @target = t - @loaded = true - end - - protected - def dependent? - @options[:dependent] || false - end - - def quoted_record_ids(records) - records.map { |record| record.quoted_id }.join(',') - end - - def interpolate_sql_options!(options, *keys) - keys.each { |key| options[key] &&= interpolate_sql(options[key]) } - end - - def interpolate_sql(sql, record = nil) - @owner.send(:interpolate_sql, sql, record) - end - - def sanitize_sql(sql) - @association_class.send(:sanitize_sql, sql) - end - - def extract_options_from_args!(args) - @owner.send(:extract_options_from_args!, args) - end - - private - - def method_missing(method, *args, &block) - load_target - @target.send(method, *args, &block) - end - - def load_target - if !@owner.new_record? || foreign_key_present - begin - @target = find_target if not loaded? - rescue ActiveRecord::RecordNotFound - reset - end - end - @loaded = true if @target - @target - end - - # Can be overwritten by associations that might have the foreign key available for an association without - # having the object itself (and still being a new record). Currently, only belongs_to present this scenario. - def foreign_key_present - false - end - - def raise_on_type_mismatch(record) - raise ActiveRecord::AssociationTypeMismatch, "#{@association_class} expected, got #{record.class}" unless record.is_a?(@association_class) - end - end - end -end \ No newline at end of file diff --git a/tracks/vendor/rails/activerecord/lib/active_record/associations/belongs_to_association.rb b/tracks/vendor/rails/activerecord/lib/active_record/associations/belongs_to_association.rb deleted file mode 100644 index 528c42ce..00000000 --- a/tracks/vendor/rails/activerecord/lib/active_record/associations/belongs_to_association.rb +++ /dev/null @@ -1,75 +0,0 @@ -module ActiveRecord - module Associations - class BelongsToAssociation < AssociationProxy #:nodoc: - - def initialize(owner, association_name, association_class_name, association_class_primary_key_name, options) - super - construct_sql - end - - def reset - @target = nil - @loaded = false - end - - def create(attributes = {}) - record = @association_class.create(attributes) - replace(record, true) - record - end - - def build(attributes = {}) - record = @association_class.new(attributes) - replace(record, true) - record - end - - def replace(obj, dont_save = false) - if obj.nil? - @target = @owner[@association_class_primary_key_name] = nil - else - raise_on_type_mismatch(obj) unless obj.nil? - - @target = (AssociationProxy === obj ? obj.target : obj) - @owner[@association_class_primary_key_name] = obj.id unless obj.new_record? - @updated = true - end - @loaded = true - - return (@target.nil? ? nil : self) - end - - def updated? - @updated - end - - protected - - - private - def find_target - if @options[:conditions] - @association_class.find( - @owner[@association_class_primary_key_name], - :conditions => interpolate_sql(@options[:conditions]), - :include => @options[:include] - ) - else - @association_class.find(@owner[@association_class_primary_key_name], :include => @options[:include]) - end - end - - def foreign_key_present - !@owner[@association_class_primary_key_name].nil? - end - - def target_obsolete? - @owner[@association_class_primary_key_name] != @target.id - end - - def construct_sql - @finder_sql = "#{@association_class.table_name}.#{@association_class.primary_key} = #{@owner.id}" - end - end - end -end diff --git a/tracks/vendor/rails/activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb b/tracks/vendor/rails/activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb deleted file mode 100644 index 2a51efb9..00000000 --- a/tracks/vendor/rails/activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb +++ /dev/null @@ -1,163 +0,0 @@ -module ActiveRecord - module Associations - class HasAndBelongsToManyAssociation < AssociationCollection #:nodoc: - def initialize(owner, association_name, association_class_name, association_class_primary_key_name, options) - super - - @association_foreign_key = options[:association_foreign_key] || association_class_name.foreign_key - @association_table_name = options[:table_name] || @association_class.table_name - @join_table = options[:join_table] - @order = options[:order] - - construct_sql - end - - def build(attributes = {}) - load_target - record = @association_class.new(attributes) - @target << record - record - end - - def find_first - load_target.first - end - - def find(*args) - options = Base.send(:extract_options_from_args!, args) - - # If using a custom finder_sql, scan the entire collection. - if @options[:finder_sql] - expects_array = args.first.kind_of?(Array) - ids = args.flatten.compact.uniq - - if ids.size == 1 - id = ids.first.to_i - record = load_target.detect { |record| id == record.id } - expects_array ? [record] : record - else - load_target.select { |record| ids.include?(record.id) } - end - else - conditions = "#{@finder_sql}" - if sanitized_conditions = sanitize_sql(options[:conditions]) - conditions << " AND (#{sanitized_conditions})" - end - options[:conditions] = conditions - options[:joins] = @join_sql - options[:readonly] ||= false - - if options[:order] && @options[:order] - options[:order] = "#{options[:order]}, #{@options[:order]}" - elsif @options[:order] - options[:order] = @options[:order] - end - - # Pass through args exactly as we received them. - args << options - @association_class.find(*args) - end - end - - def push_with_attributes(record, join_attributes = {}) - raise_on_type_mismatch(record) - join_attributes.each { |key, value| record[key.to_s] = value } - callback(:before_add, record) - insert_record(record) unless @owner.new_record? - @target << record - callback(:after_add, record) - self - end - - alias :concat_with_attributes :push_with_attributes - - def size - @options[:uniq] ? count_records : super - end - - protected - def method_missing(method, *args, &block) - if @target.respond_to?(method) || (!@association_class.respond_to?(method) && Class.respond_to?(method)) - super - else - @association_class.with_scope(:find => { :conditions => @finder_sql, :joins => @join_sql, :readonly => false }) do - @association_class.send(method, *args, &block) - end - end - end - - def find_target - if @options[:finder_sql] - records = @association_class.find_by_sql(@finder_sql) - else - records = find(:all, :include => @options[:include]) - end - - @options[:uniq] ? uniq(records) : records - end - - def count_records - load_target.size - end - - def insert_record(record) - if record.new_record? - return false unless record.save - end - - if @options[:insert_sql] - @owner.connection.execute(interpolate_sql(@options[:insert_sql], record)) - else - columns = @owner.connection.columns(@join_table, "#{@join_table} Columns") - - attributes = columns.inject({}) do |attributes, column| - case column.name - when @association_class_primary_key_name - attributes[column.name] = @owner.quoted_id - when @association_foreign_key - attributes[column.name] = record.quoted_id - else - if record.attributes.has_key?(column.name) - value = @owner.send(:quote, record[column.name], column) - attributes[column.name] = value unless value.nil? - end - end - attributes - end - - sql = - "INSERT INTO #{@join_table} (#{@owner.send(:quoted_column_names, attributes).join(', ')}) " + - "VALUES (#{attributes.values.join(', ')})" - - @owner.connection.execute(sql) - end - - return true - end - - def delete_records(records) - if sql = @options[:delete_sql] - records.each { |record| @owner.connection.execute(interpolate_sql(sql, record)) } - else - ids = quoted_record_ids(records) - sql = "DELETE FROM #{@join_table} WHERE #{@association_class_primary_key_name} = #{@owner.quoted_id} AND #{@association_foreign_key} IN (#{ids})" - @owner.connection.execute(sql) - end - end - - def construct_sql - interpolate_sql_options!(@options, :finder_sql) - - if @options[:finder_sql] - @finder_sql = @options[:finder_sql] - else - @finder_sql = "#{@join_table}.#{@association_class_primary_key_name} = #{@owner.quoted_id} " - @finder_sql << " AND (#{interpolate_sql(@options[:conditions])})" if @options[:conditions] - end - - @join_sql = "LEFT JOIN #{@join_table} ON #{@association_class.table_name}.#{@association_class.primary_key} = #{@join_table}.#{@association_foreign_key}" - end - - end - end -end diff --git a/tracks/vendor/rails/activerecord/lib/active_record/associations/has_many_association.rb b/tracks/vendor/rails/activerecord/lib/active_record/associations/has_many_association.rb deleted file mode 100644 index 288742d9..00000000 --- a/tracks/vendor/rails/activerecord/lib/active_record/associations/has_many_association.rb +++ /dev/null @@ -1,185 +0,0 @@ -module ActiveRecord - module Associations - class HasManyAssociation < AssociationCollection #:nodoc: - def initialize(owner, association_name, association_class_name, association_class_primary_key_name, options) - super - @conditions = sanitize_sql(options[:conditions]) - - construct_sql - end - - def build(attributes = {}) - if attributes.is_a?(Array) - attributes.collect { |attr| create(attr) } - else - load_target - record = @association_class.new(attributes) - record[@association_class_primary_key_name] = @owner.id unless @owner.new_record? - @target << record - record - end - end - - # DEPRECATED. - def find_all(runtime_conditions = nil, orderings = nil, limit = nil, joins = nil) - if @options[:finder_sql] - @association_class.find_by_sql(@finder_sql) - else - conditions = @finder_sql - conditions += " AND (#{sanitize_sql(runtime_conditions)})" if runtime_conditions - orderings ||= @options[:order] - @association_class.find_all(conditions, orderings, limit, joins) - end - end - - # DEPRECATED. Find the first associated record. All arguments are optional. - def find_first(conditions = nil, orderings = nil) - find_all(conditions, orderings, 1).first - end - - # Count the number of associated records. All arguments are optional. - def count(runtime_conditions = nil) - if @options[:counter_sql] - @association_class.count_by_sql(@counter_sql) - elsif @options[:finder_sql] - @association_class.count_by_sql(@finder_sql) - else - sql = @finder_sql - sql += " AND (#{sanitize_sql(runtime_conditions)})" if runtime_conditions - @association_class.count(sql) - end - end - - def find(*args) - options = Base.send(:extract_options_from_args!, args) - - # If using a custom finder_sql, scan the entire collection. - if @options[:finder_sql] - expects_array = args.first.kind_of?(Array) - ids = args.flatten.compact.uniq - - if ids.size == 1 - id = ids.first - record = load_target.detect { |record| id == record.id } - expects_array? ? [record] : record - else - load_target.select { |record| ids.include?(record.id) } - end - else - conditions = "#{@finder_sql}" - if sanitized_conditions = sanitize_sql(options[:conditions]) - conditions << " AND (#{sanitized_conditions})" - end - options[:conditions] = conditions - - if options[:order] && @options[:order] - options[:order] = "#{options[:order]}, #{@options[:order]}" - elsif @options[:order] - options[:order] = @options[:order] - end - - # Pass through args exactly as we received them. - args << options - @association_class.find(*args) - end - end - - protected - def method_missing(method, *args, &block) - if @target.respond_to?(method) || (!@association_class.respond_to?(method) && Class.respond_to?(method)) - super - else - @association_class.with_scope( - :find => { - :conditions => @finder_sql, - :joins => @join_sql, - :readonly => false - }, - :create => { - @association_class_primary_key_name => @owner.id - } - ) do - @association_class.send(method, *args, &block) - end - end - end - - def find_target - if @options[:finder_sql] - @association_class.find_by_sql(@finder_sql) - else - @association_class.find(:all, - :conditions => @finder_sql, - :order => @options[:order], - :limit => @options[:limit], - :joins => @options[:joins], - :include => @options[:include], - :group => @options[:group] - ) - end - end - - def count_records - count = if has_cached_counter? - @owner.send(:read_attribute, cached_counter_attribute_name) - elsif @options[:counter_sql] - @association_class.count_by_sql(@counter_sql) - else - @association_class.count(@counter_sql) - end - - @target = [] and loaded if count == 0 - - return count - end - - def has_cached_counter? - @owner.attribute_present?(cached_counter_attribute_name) - end - - def cached_counter_attribute_name - "#{@association_name}_count" - end - - def insert_record(record) - record[@association_class_primary_key_name] = @owner.id - record.save - end - - def delete_records(records) - if @options[:dependent] - records.each { |r| r.destroy } - else - ids = quoted_record_ids(records) - @association_class.update_all( - "#{@association_class_primary_key_name} = NULL", - "#{@association_class_primary_key_name} = #{@owner.quoted_id} AND #{@association_class.primary_key} IN (#{ids})" - ) - end - end - - def target_obsolete? - false - end - - def construct_sql - if @options[:finder_sql] - @finder_sql = interpolate_sql(@options[:finder_sql]) - else - @finder_sql = "#{@association_class.table_name}.#{@association_class_primary_key_name} = #{@owner.quoted_id}" - @finder_sql << " AND (#{interpolate_sql(@conditions)})" if @conditions - end - - if @options[:counter_sql] - @counter_sql = interpolate_sql(@options[:counter_sql]) - elsif @options[:finder_sql] - @options[:counter_sql] = @options[:finder_sql].gsub(/SELECT (.*) FROM/i, "SELECT COUNT(*) FROM") - @counter_sql = interpolate_sql(@options[:counter_sql]) - else - @counter_sql = "#{@association_class.table_name}.#{@association_class_primary_key_name} = #{@owner.quoted_id}" - @counter_sql << " AND (#{interpolate_sql(@conditions)})" if @conditions - end - end - end - end -end diff --git a/tracks/vendor/rails/activerecord/lib/active_record/associations/has_one_association.rb b/tracks/vendor/rails/activerecord/lib/active_record/associations/has_one_association.rb deleted file mode 100644 index 8f7857eb..00000000 --- a/tracks/vendor/rails/activerecord/lib/active_record/associations/has_one_association.rb +++ /dev/null @@ -1,74 +0,0 @@ -module ActiveRecord - module Associations - class HasOneAssociation < BelongsToAssociation #:nodoc: - def initialize(owner, association_name, association_class_name, association_class_primary_key_name, options) - super - - construct_sql - end - - def create(attributes = {}, replace_existing = true) - record = build(attributes, replace_existing) - record.save - record - end - - def build(attributes = {}, replace_existing = true) - record = @association_class.new(attributes) - - if replace_existing - replace(record, true) - else - record[@association_class_primary_key_name] = @owner.id unless @owner.new_record? - self.target = record - end - - record - end - - def replace(obj, dont_save = false) - load_target - unless @target.nil? - if dependent? && !dont_save && @target != obj - @target.destroy unless @target.new_record? - @owner.clear_association_cache - else - @target[@association_class_primary_key_name] = nil - @target.save unless @owner.new_record? - end - end - - if obj.nil? - @target = nil - else - raise_on_type_mismatch(obj) - - obj[@association_class_primary_key_name] = @owner.id unless @owner.new_record? - @target = (AssociationProxy === obj ? obj.target : obj) - end - - @loaded = true - unless @owner.new_record? or obj.nil? or dont_save - return (obj.save ? self : false) - else - return (obj.nil? ? nil : self) - end - end - - private - def find_target - @association_class.find(:first, :conditions => @finder_sql, :order => @options[:order], :include => @options[:include]) - end - - def target_obsolete? - false - end - - def construct_sql - @finder_sql = "#{@association_class.table_name}.#{@association_class_primary_key_name} = #{@owner.quoted_id}" - @finder_sql << " AND (#{sanitize_sql(@options[:conditions])})" if @options[:conditions] - @finder_sql - end - end - end -end diff --git a/tracks/vendor/rails/activerecord/lib/active_record/base.rb b/tracks/vendor/rails/activerecord/lib/active_record/base.rb deleted file mode 100644 index 51dc49d3..00000000 --- a/tracks/vendor/rails/activerecord/lib/active_record/base.rb +++ /dev/null @@ -1,1767 +0,0 @@ -require 'yaml' -require 'set' -require 'active_record/deprecated_finders' - -module ActiveRecord #:nodoc: - class ActiveRecordError < StandardError #:nodoc: - end - class SubclassNotFound < ActiveRecordError #:nodoc: - end - class AssociationTypeMismatch < ActiveRecordError #:nodoc: - end - class SerializationTypeMismatch < ActiveRecordError #:nodoc: - end - class AdapterNotSpecified < ActiveRecordError # :nodoc: - end - class AdapterNotFound < ActiveRecordError # :nodoc: - end - class ConnectionNotEstablished < ActiveRecordError #:nodoc: - end - class ConnectionFailed < ActiveRecordError #:nodoc: - end - class RecordNotFound < ActiveRecordError #:nodoc: - end - class StatementInvalid < ActiveRecordError #:nodoc: - end - class PreparedStatementInvalid < ActiveRecordError #:nodoc: - end - class StaleObjectError < ActiveRecordError #:nodoc: - end - class ConfigurationError < StandardError #:nodoc: - end - class ReadOnlyRecord < StandardError #:nodoc: - end - - class AttributeAssignmentError < ActiveRecordError #:nodoc: - attr_reader :exception, :attribute - def initialize(message, exception, attribute) - @exception = exception - @attribute = attribute - @message = message - end - end - - class MultiparameterAssignmentErrors < ActiveRecordError #:nodoc: - attr_reader :errors - def initialize(errors) - @errors = errors - end - end - - # Active Record objects don't specify their attributes directly, but rather infer them from the table definition with - # which they're linked. Adding, removing, and changing attributes and their type is done directly in the database. Any change - # is instantly reflected in the Active Record objects. The mapping that binds a given Active Record class to a certain - # database table will happen automatically in most common cases, but can be overwritten for the uncommon ones. - # - # See the mapping rules in table_name and the full example in link:files/README.html for more insight. - # - # == Creation - # - # Active Records accept constructor parameters either in a hash or as a block. The hash method is especially useful when - # you're receiving the data from somewhere else, like a HTTP request. It works like this: - # - # user = User.new(:name => "David", :occupation => "Code Artist") - # user.name # => "David" - # - # You can also use block initialization: - # - # user = User.new do |u| - # u.name = "David" - # u.occupation = "Code Artist" - # end - # - # And of course you can just create a bare object and specify the attributes after the fact: - # - # user = User.new - # user.name = "David" - # user.occupation = "Code Artist" - # - # == Conditions - # - # Conditions can either be specified as a string or an array representing the WHERE-part of an SQL statement. - # The array form is to be used when the condition input is tainted and requires sanitization. The string form can - # be used for statements that don't involve tainted data. Examples: - # - # User < ActiveRecord::Base - # def self.authenticate_unsafely(user_name, password) - # find(:first, :conditions => "user_name = '#{user_name}' AND password = '#{password}'") - # end - # - # def self.authenticate_safely(user_name, password) - # find(:first, :conditions => [ "user_name = ? AND password = ?", user_name, password ]) - # end - # end - # - # The authenticate_unsafely method inserts the parameters directly into the query and is thus susceptible to SQL-injection - # attacks if the user_name and +password+ parameters come directly from a HTTP request. The authenticate_safely method, - # on the other hand, will sanitize the user_name and +password+ before inserting them in the query, which will ensure that - # an attacker can't escape the query and fake the login (or worse). - # - # When using multiple parameters in the conditions, it can easily become hard to read exactly what the fourth or fifth - # question mark is supposed to represent. In those cases, you can resort to named bind variables instead. That's done by replacing - # the question marks with symbols and supplying a hash with values for the matching symbol keys: - # - # Company.find(:first, [ - # "id = :id AND name = :name AND division = :division AND created_at > :accounting_date", - # { :id => 3, :name => "37signals", :division => "First", :accounting_date => '2005-01-01' } - # ]) - # - # == Overwriting default accessors - # - # All column values are automatically available through basic accessors on the Active Record object, but some times you - # want to specialize this behavior. This can be done by either by overwriting the default accessors (using the same - # name as the attribute) calling read_attribute(attr_name) and write_attribute(attr_name, value) to actually change things. - # Example: - # - # class Song < ActiveRecord::Base - # # Uses an integer of seconds to hold the length of the song - # - # def length=(minutes) - # write_attribute(:length, minutes * 60) - # end - # - # def length - # read_attribute(:length) / 60 - # end - # end - # - # You can alternatively use self[:attribute]=(value) and self[:attribute] instead of write_attribute(:attribute, vaule) and - # read_attribute(:attribute) as a shorter form. - # - # == Accessing attributes before they have been typecasted - # - # Sometimes you want to be able to read the raw attribute data without having the column-determined typecast run its course first. - # That can be done by using the _before_type_cast accessors that all attributes have. For example, if your Account model - # has a balance attribute, you can call account.balance_before_type_cast or account.id_before_type_cast. - # - # This is especially useful in validation situations where the user might supply a string for an integer field and you want to display - # the original string back in an error message. Accessing the attribute normally would typecast the string to 0, which isn't what you - # want. - # - # == Dynamic attribute-based finders - # - # Dynamic attribute-based finders are a cleaner way of getting (and/or creating) objects by simple queries without turning to SQL. They work by - # appending the name of an attribute to find_by_ or find_all_by_, so you get finders like Person.find_by_user_name, - # Person.find_all_by_last_name, Payment.find_by_transaction_id. So instead of writing - # Person.find(:first, ["user_name = ?", user_name]), you just do Person.find_by_user_name(user_name). - # And instead of writing Person.find(:all, ["last_name = ?", last_name]), you just do Person.find_all_by_last_name(last_name). - # - # It's also possible to use multiple attributes in the same find by separating them with "_and_", so you get finders like - # Person.find_by_user_name_and_password or even Payment.find_by_purchaser_and_state_and_country. So instead of writing - # Person.find(:first, ["user_name = ? AND password = ?", user_name, password]), you just do - # Person.find_by_user_name_and_password(user_name, password). - # - # It's even possible to use all the additional parameters to find. For example, the full interface for Payment.find_all_by_amount - # is actually Payment.find_all_by_amount(amount, options). And the full interface to Person.find_by_user_name is - # actually Person.find_by_user_name(user_name, options). So you could call Payment.find_all_by_amount(50, :order => "created_on"). - # - # The same dynamic finder style can be used to create the object if it doesn't already exist. This dynamic finder is called with - # find_or_create_by_ and will return the object if it already exists and otherwise creates it, then returns it. Example: - # - # # No 'Summer' tag exists - # Tag.find_or_create_by_name("Summer") # equal to Tag.create(:name => "Summer") - # - # # Now the 'Summer' tag does exist - # Tag.find_or_create_by_name("Summer") # equal to Tag.find_by_name("Summer") - # - # == Saving arrays, hashes, and other non-mappable objects in text columns - # - # Active Record can serialize any object in text columns using YAML. To do so, you must specify this with a call to the class method +serialize+. - # This makes it possible to store arrays, hashes, and other non-mappable objects without doing any additional work. Example: - # - # class User < ActiveRecord::Base - # serialize :preferences - # end - # - # user = User.create(:preferences) => { "background" => "black", "display" => large }) - # User.find(user.id).preferences # => { "background" => "black", "display" => large } - # - # You can also specify a class option as the second parameter that'll raise an exception if a serialized object is retrieved as a - # descendent of a class not in the hierarchy. Example: - # - # class User < ActiveRecord::Base - # serialize :preferences, Hash - # end - # - # user = User.create(:preferences => %w( one two three )) - # User.find(user.id).preferences # raises SerializationTypeMismatch - # - # == Single table inheritance - # - # Active Record allows inheritance by storing the name of the class in a column that by default is called "type" (can be changed - # by overwriting Base.inheritance_column). This means that an inheritance looking like this: - # - # class Company < ActiveRecord::Base; end - # class Firm < Company; end - # class Client < Company; end - # class PriorityClient < Client; end - # - # When you do Firm.create(:name => "37signals"), this record will be saved in the companies table with type = "Firm". You can then - # fetch this row again using Company.find(:first, "name = '37signals'") and it will return a Firm object. - # - # If you don't have a type column defined in your table, single-table inheritance won't be triggered. In that case, it'll work just - # like normal subclasses with no special magic for differentiating between them or reloading the right type with find. - # - # Note, all the attributes for all the cases are kept in the same table. Read more: - # http://www.martinfowler.com/eaaCatalog/singleTableInheritance.html - # - # == Connection to multiple databases in different models - # - # Connections are usually created through ActiveRecord::Base.establish_connection and retrieved by ActiveRecord::Base.connection. - # All classes inheriting from ActiveRecord::Base will use this connection. But you can also set a class-specific connection. - # For example, if Course is a ActiveRecord::Base, but resides in a different database you can just say Course.establish_connection - # and Course *and all its subclasses* will use this connection instead. - # - # This feature is implemented by keeping a connection pool in ActiveRecord::Base that is a Hash indexed by the class. If a connection is - # requested, the retrieve_connection method will go up the class-hierarchy until a connection is found in the connection pool. - # - # == Exceptions - # - # * +ActiveRecordError+ -- generic error class and superclass of all other errors raised by Active Record - # * +AdapterNotSpecified+ -- the configuration hash used in establish_connection didn't include a - # :adapter key. - # * +AdapterNotFound+ -- the :adapter key used in establish_connection specified an non-existent adapter - # (or a bad spelling of an existing one). - # * +AssociationTypeMismatch+ -- the object assigned to the association wasn't of the type specified in the association definition. - # * +SerializationTypeMismatch+ -- the object serialized wasn't of the class specified as the second parameter. - # * +ConnectionNotEstablished+ -- no connection has been established. Use establish_connection before querying. - # * +RecordNotFound+ -- no record responded to the find* method. - # Either the row with the given ID doesn't exist or the row didn't meet the additional restrictions. - # * +StatementInvalid+ -- the database server rejected the SQL statement. The precise error is added in the message. - # Either the record with the given ID doesn't exist or the record didn't meet the additional restrictions. - # * +MultiparameterAssignmentErrors+ -- collection of errors that occurred during a mass assignment using the - # +attributes=+ method. The +errors+ property of this exception contains an array of +AttributeAssignmentError+ - # objects that should be inspected to determine which attributes triggered the errors. - # * +AttributeAssignmentError+ -- an error occurred while doing a mass assignment through the +attributes=+ method. - # You can inspect the +attribute+ property of the exception object to determine which attribute triggered the error. - # - # *Note*: The attributes listed are class-level attributes (accessible from both the class and instance level). - # So it's possible to assign a logger to the class through Base.logger= which will then be used by all - # instances in the current object space. - class Base - # Accepts a logger conforming to the interface of Log4r or the default Ruby 1.8+ Logger class, which is then passed - # on to any new database connections made and which can be retrieved on both a class and instance level by calling +logger+. - cattr_accessor :logger - - def self.inherited(child) #:nodoc: - @@subclasses[self] ||= [] - @@subclasses[self] << child - super - end - - # Allow all subclasses of AR::Base to be reloaded in dev mode, unless they - # explicitly decline the honor. USE WITH CAUTION. Only AR subclasses kept - # in the framework should use the flag, so #reset_subclasses and so forth - # leave it alone. - def self.reloadable? #:nodoc: - true - end - - def self.reset_subclasses - nonreloadables = [] - subclasses.each do |klass| - unless klass.reloadable? - nonreloadables << klass - next - end - klass.instance_variables.each { |var| klass.send(:remove_instance_variable, var) } - klass.instance_methods(false).each { |m| klass.send :undef_method, m } - end - @@subclasses = {} - nonreloadables.each { |klass| (@@subclasses[klass.superclass] ||= []) << klass } - end - - @@subclasses = {} - - cattr_accessor :configurations - @@configurations = {} - - # Accessor for the prefix type that will be prepended to every primary key column name. The options are :table_name and - # :table_name_with_underscore. If the first is specified, the Product class will look for "productid" instead of "id" as - # the primary column. If the latter is specified, the Product class will look for "product_id" instead of "id". Remember - # that this is a global setting for all Active Records. - cattr_accessor :primary_key_prefix_type - @@primary_key_prefix_type = nil - - # Accessor for the name of the prefix string to prepend to every table name. So if set to "basecamp_", all - # table names will be named like "basecamp_projects", "basecamp_people", etc. This is a convenient way of creating a namespace - # for tables in a shared database. By default, the prefix is the empty string. - cattr_accessor :table_name_prefix - @@table_name_prefix = "" - - # Works like +table_name_prefix+, but appends instead of prepends (set to "_basecamp" gives "projects_basecamp", - # "people_basecamp"). By default, the suffix is the empty string. - cattr_accessor :table_name_suffix - @@table_name_suffix = "" - - # Indicates whether or not table names should be the pluralized versions of the corresponding class names. - # If true, the default table name for a +Product+ class will be +products+. If false, it would just be +product+. - # See table_name for the full rules on table/class naming. This is true, by default. - cattr_accessor :pluralize_table_names - @@pluralize_table_names = true - - # Determines whether or not to use ANSI codes to colorize the logging statements committed by the connection adapter. These colors - # make it much easier to overview things during debugging (when used through a reader like +tail+ and on a black background), but - # may complicate matters if you use software like syslog. This is true, by default. - cattr_accessor :colorize_logging - @@colorize_logging = true - - # Determines whether to use Time.local (using :local) or Time.utc (using :utc) when pulling dates and times from the database. - # This is set to :local by default. - cattr_accessor :default_timezone - @@default_timezone = :local - - # Determines whether or not to use a connection for each thread, or a single shared connection for all threads. - # Defaults to true; Railties' WEBrick server sets this to false. - cattr_accessor :allow_concurrency - @@allow_concurrency = true - - # Determines whether to speed up access by generating optimized reader - # methods to avoid expensive calls to method_missing when accessing - # attributes by name. You might want to set this to false in development - # mode, because the methods would be regenerated on each request. - cattr_accessor :generate_read_methods - @@generate_read_methods = true - - # Specifies the format to use when dumping the database schema with Rails' - # Rakefile. If :sql, the schema is dumped as (potentially database- - # specific) SQL statements. If :ruby, the schema is dumped as an - # ActiveRecord::Schema file which can be loaded into any database that - # supports migrations. Use :ruby if you want to have different database - # adapters for, e.g., your development and test environments. - cattr_accessor :schema_format - @@schema_format = :sql - - class << self # Class methods - # Find operates with three different retrieval approaches: - # - # * Find by id: This can either be a specific id (1), a list of ids (1, 5, 6), or an array of ids ([5, 6, 10]). - # If no record can be found for all of the listed ids, then RecordNotFound will be raised. - # * Find first: This will return the first record matched by the options used. These options can either be specific - # conditions or merely an order. If no record can matched, nil is returned. - # * Find all: This will return all the records matched by the options used. If no records are found, an empty array is returned. - # - # All approaches accept an option hash as their last parameter. The options are: - # - # * :conditions: An SQL fragment like "administrator = 1" or [ "user_name = ?", username ]. See conditions in the intro. - # * :order: An SQL fragment like "created_at DESC, name". - # * :group: An attribute name by which the result should be grouped. Uses the GROUP BY SQL-clause. - # * :limit: An integer determining the limit on the number of rows that should be returned. - # * :offset: An integer determining the offset from where the rows should be fetched. So at 5, it would skip the first 4 rows. - # * :joins: An SQL fragment for additional joins like "LEFT JOIN comments ON comments.post_id = id". (Rarely needed). - # The records will be returned read-only since they will have attributes that do not correspond to the table's columns. - # Pass :readonly => false to override. - # * :include: Names associations that should be loaded alongside using LEFT OUTER JOINs. The symbols named refer - # to already defined associations. See eager loading under Associations. - # * :select: By default, this is * as in SELECT * FROM, but can be changed if you for example want to do a join, but not - # include the joined columns. - # * :readonly: Mark the returned records read-only so they cannot be saved or updated. - # - # Examples for find by id: - # Person.find(1) # returns the object for ID = 1 - # Person.find(1, 2, 6) # returns an array for objects with IDs in (1, 2, 6) - # Person.find([7, 17]) # returns an array for objects with IDs in (7, 17) - # Person.find([1]) # returns an array for objects the object with ID = 1 - # Person.find(1, :conditions => "administrator = 1", :order => "created_on DESC") - # - # Examples for find first: - # Person.find(:first) # returns the first object fetched by SELECT * FROM people - # Person.find(:first, :conditions => [ "user_name = ?", user_name]) - # Person.find(:first, :order => "created_on DESC", :offset => 5) - # - # Examples for find all: - # Person.find(:all) # returns an array of objects for all the rows fetched by SELECT * FROM people - # Person.find(:all, :conditions => [ "category IN (?)", categories], :limit => 50) - # Person.find(:all, :offset => 10, :limit => 10) - # Person.find(:all, :include => [ :account, :friends ]) - # Person.find(:all, :group => "category") - def find(*args) - options = extract_options_from_args!(args) - - # Inherit :readonly from finder scope if set. Otherwise, - # if :joins is not blank then :readonly defaults to true. - unless options.has_key?(:readonly) - if scoped?(:find, :readonly) - options[:readonly] = scope(:find, :readonly) - elsif !options[:joins].blank? - options[:readonly] = true - end - end - - case args.first - when :first - find(:all, options.merge(options[:include] ? { } : { :limit => 1 })).first - when :all - records = options[:include] ? find_with_associations(options) : find_by_sql(construct_finder_sql(options)) - records.each { |record| record.readonly! } if options[:readonly] - records - else - return args.first if args.first.kind_of?(Array) && args.first.empty? - expects_array = args.first.kind_of?(Array) - - conditions = " AND (#{sanitize_sql(options[:conditions])})" if options[:conditions] - - ids = args.flatten.compact.uniq - case ids.size - when 0 - raise RecordNotFound, "Couldn't find #{name} without an ID#{conditions}" - when 1 - if result = find(:first, options.merge({ :conditions => "#{table_name}.#{primary_key} = #{sanitize(ids.first)}#{conditions}" })) - return expects_array ? [ result ] : result - else - raise RecordNotFound, "Couldn't find #{name} with ID=#{ids.first}#{conditions}" - end - else - # Find multiple ids - ids_list = ids.map { |id| sanitize(id) }.join(',') - result = find(:all, options.merge({ :conditions => "#{table_name}.#{primary_key} IN (#{ids_list})#{conditions}"})) - if result.size == ids.size - return result - else - raise RecordNotFound, "Couldn't find all #{name.pluralize} with IDs (#{ids_list})#{conditions}" - end - end - end - end - - # Works like find(:all), but requires a complete SQL string. Examples: - # Post.find_by_sql "SELECT p.*, c.author FROM posts p, comments c WHERE p.id = c.post_id" - # Post.find_by_sql ["SELECT * FROM posts WHERE author = ? AND created > ?", author_id, start_date] - def find_by_sql(sql) - connection.select_all(sanitize_sql(sql), "#{name} Load").collect! { |record| instantiate(record) } - end - - # Returns true if the given +id+ represents the primary key of a record in the database, false otherwise. - # Example: - # Person.exists?(5) - def exists?(id) - !find(:first, :conditions => ["#{primary_key} = ?", id]).nil? rescue false - end - - # Creates an object, instantly saves it as a record (if the validation permits it), and returns it. If the save - # fails under validations, the unsaved object is still returned. - def create(attributes = nil) - if attributes.is_a?(Array) - attributes.collect { |attr| create(attr) } - else - attributes.reverse_merge!(scope(:create)) if scoped?(:create) - - object = new(attributes) - object.save - object - end - end - - # Finds the record from the passed +id+, instantly saves it with the passed +attributes+ (if the validation permits it), - # and returns it. If the save fails under validations, the unsaved object is still returned. - def update(id, attributes) - if id.is_a?(Array) - idx = -1 - id.collect { |id| idx += 1; update(id, attributes[idx]) } - else - object = find(id) - object.update_attributes(attributes) - object - end - end - - # Deletes the record with the given +id+ without instantiating an object first. If an array of ids is provided, all of them - # are deleted. - def delete(id) - delete_all([ "#{primary_key} IN (?)", id ]) - end - - # Destroys the record with the given +id+ by instantiating the object and calling #destroy (all the callbacks are the triggered). - # If an array of ids is provided, all of them are destroyed. - def destroy(id) - id.is_a?(Array) ? id.each { |id| destroy(id) } : find(id).destroy - end - - # Updates all records with the SET-part of an SQL update statement in +updates+ and returns an integer with the number of rows updated. - # A subset of the records can be selected by specifying +conditions+. Example: - # Billing.update_all "category = 'authorized', approved = 1", "author = 'David'" - def update_all(updates, conditions = nil) - sql = "UPDATE #{table_name} SET #{sanitize_sql(updates)} " - add_conditions!(sql, conditions) - connection.update(sql, "#{name} Update") - end - - # Destroys the objects for all the records that match the +condition+ by instantiating each object and calling - # the destroy method. Example: - # Person.destroy_all "last_login < '2004-04-04'" - def destroy_all(conditions = nil) - find(:all, :conditions => conditions).each { |object| object.destroy } - end - - # Deletes all the records that match the +condition+ without instantiating the objects first (and hence not - # calling the destroy method). Example: - # Post.delete_all "person_id = 5 AND (category = 'Something' OR category = 'Else')" - def delete_all(conditions = nil) - sql = "DELETE FROM #{table_name} " - add_conditions!(sql, conditions) - connection.delete(sql, "#{name} Delete all") - end - - # Returns the number of records that meet the +conditions+. Zero is returned if no records match. Example: - # Product.count "sales > 1" - def count(conditions = nil, joins = nil) - sql = "SELECT COUNT(*) FROM #{table_name} " - sql << " #{joins} " if joins - add_conditions!(sql, conditions) - count_by_sql(sql) - end - - # Returns the result of an SQL statement that should only include a COUNT(*) in the SELECT part. - # Product.count_by_sql "SELECT COUNT(*) FROM sales s, customers c WHERE s.customer_id = c.id" - def count_by_sql(sql) - sql = sanitize_conditions(sql) - connection.select_value(sql, "#{name} Count").to_i - end - - # Increments the specified counter by one. So DiscussionBoard.increment_counter("post_count", - # discussion_board_id) would increment the "post_count" counter on the board responding to discussion_board_id. - # This is used for caching aggregate values, so that they don't need to be computed every time. Especially important - # for looping over a collection where each element require a number of aggregate values. Like the DiscussionBoard - # that needs to list both the number of posts and comments. - def increment_counter(counter_name, id) - update_all "#{counter_name} = #{counter_name} + 1", "#{primary_key} = #{quote(id)}" - end - - # Works like increment_counter, but decrements instead. - def decrement_counter(counter_name, id) - update_all "#{counter_name} = #{counter_name} - 1", "#{primary_key} = #{quote(id)}" - end - - # Attributes named in this macro are protected from mass-assignment, such as new(attributes) and - # attributes=(attributes). Their assignment will simply be ignored. Instead, you can use the direct writer - # methods to do assignment. This is meant to protect sensitive attributes from being overwritten by URL/form hackers. Example: - # - # class Customer < ActiveRecord::Base - # attr_protected :credit_rating - # end - # - # customer = Customer.new("name" => David, "credit_rating" => "Excellent") - # customer.credit_rating # => nil - # customer.attributes = { "description" => "Jolly fellow", "credit_rating" => "Superb" } - # customer.credit_rating # => nil - # - # customer.credit_rating = "Average" - # customer.credit_rating # => "Average" - def attr_protected(*attributes) - write_inheritable_array("attr_protected", attributes - (protected_attributes || [])) - end - - # Returns an array of all the attributes that have been protected from mass-assignment. - def protected_attributes # :nodoc: - read_inheritable_attribute("attr_protected") - end - - # If this macro is used, only those attributes named in it will be accessible for mass-assignment, such as - # new(attributes) and attributes=(attributes). This is the more conservative choice for mass-assignment - # protection. If you'd rather start from an all-open default and restrict attributes as needed, have a look at - # attr_protected. - def attr_accessible(*attributes) - write_inheritable_array("attr_accessible", attributes - (accessible_attributes || [])) - end - - # Returns an array of all the attributes that have been made accessible to mass-assignment. - def accessible_attributes # :nodoc: - read_inheritable_attribute("attr_accessible") - end - - # Specifies that the attribute by the name of +attr_name+ should be serialized before saving to the database and unserialized - # after loading from the database. The serialization is done through YAML. If +class_name+ is specified, the serialized - # object must be of that class on retrieval or +SerializationTypeMismatch+ will be raised. - def serialize(attr_name, class_name = Object) - serialized_attributes[attr_name.to_s] = class_name - end - - # Returns a hash of all the attributes that have been specified for serialization as keys and their class restriction as values. - def serialized_attributes - read_inheritable_attribute("attr_serialized") or write_inheritable_attribute("attr_serialized", {}) - end - - # Guesses the table name (in forced lower-case) based on the name of the class in the inheritance hierarchy descending - # directly from ActiveRecord. So if the hierarchy looks like: Reply < Message < ActiveRecord, then Message is used - # to guess the table name from even when called on Reply. The rules used to do the guess are handled by the Inflector class - # in Active Support, which knows almost all common English inflections (report a bug if your inflection isn't covered). - # - # Additionally, the class-level table_name_prefix is prepended to the table_name and the table_name_suffix is appended. - # So if you have "myapp_" as a prefix, the table name guess for an Account class becomes "myapp_accounts". - # - # You can also overwrite this class method to allow for unguessable links, such as a Mouse class with a link to a - # "mice" table. Example: - # - # class Mouse < ActiveRecord::Base - # set_table_name "mice" - # end - def table_name - reset_table_name - end - - def reset_table_name - name = "#{table_name_prefix}#{undecorated_table_name(class_name_of_active_record_descendant(self))}#{table_name_suffix}" - set_table_name name - name - end - - # Defines the primary key field -- can be overridden in subclasses. Overwriting will negate any effect of the - # primary_key_prefix_type setting, though. - def primary_key - reset_primary_key - end - - def reset_primary_key - key = 'id' - case primary_key_prefix_type - when :table_name - key = Inflector.foreign_key(class_name_of_active_record_descendant(self), false) - when :table_name_with_underscore - key = Inflector.foreign_key(class_name_of_active_record_descendant(self)) - end - set_primary_key(key) - key - end - - # Defines the column name for use with single table inheritance -- can be overridden in subclasses. - def inheritance_column - "type" - end - - # Lazy-set the sequence name to the connection's default. This method - # is only ever called once since set_sequence_name overrides it. - def sequence_name - reset_sequence_name - end - - def reset_sequence_name - default = connection.default_sequence_name(table_name, primary_key) - set_sequence_name(default) - default - end - - # Sets the table name to use to the given value, or (if the value - # is nil or false) to the value returned by the given block. - # - # Example: - # - # class Project < ActiveRecord::Base - # set_table_name "project" - # end - def set_table_name( value=nil, &block ) - define_attr_method :table_name, value, &block - end - alias :table_name= :set_table_name - - # Sets the name of the primary key column to use to the given value, - # or (if the value is nil or false) to the value returned by the given - # block. - # - # Example: - # - # class Project < ActiveRecord::Base - # set_primary_key "sysid" - # end - def set_primary_key( value=nil, &block ) - define_attr_method :primary_key, value, &block - end - alias :primary_key= :set_primary_key - - # Sets the name of the inheritance column to use to the given value, - # or (if the value # is nil or false) to the value returned by the - # given block. - # - # Example: - # - # class Project < ActiveRecord::Base - # set_inheritance_column do - # original_inheritance_column + "_id" - # end - # end - def set_inheritance_column( value=nil, &block ) - define_attr_method :inheritance_column, value, &block - end - alias :inheritance_column= :set_inheritance_column - - # Sets the name of the sequence to use when generating ids to the given - # value, or (if the value is nil or false) to the value returned by the - # given block. This is required for Oracle and is useful for any - # database which relies on sequences for primary key generation. - # - # If a sequence name is not explicitly set when using Oracle or Firebird, - # it will default to the commonly used pattern of: #{table_name}_seq - # - # If a sequence name is not explicitly set when using PostgreSQL, it - # will discover the sequence corresponding to your primary key for you. - # - # Example: - # - # class Project < ActiveRecord::Base - # set_sequence_name "projectseq" # default would have been "project_seq" - # end - def set_sequence_name( value=nil, &block ) - define_attr_method :sequence_name, value, &block - end - alias :sequence_name= :set_sequence_name - - # Turns the +table_name+ back into a class name following the reverse rules of +table_name+. - def class_name(table_name = table_name) # :nodoc: - # remove any prefix and/or suffix from the table name - class_name = table_name[table_name_prefix.length..-(table_name_suffix.length + 1)].camelize - class_name = class_name.singularize if pluralize_table_names - class_name - end - - # Indicates whether the table associated with this class exists - def table_exists? - if connection.respond_to?(:tables) - connection.tables.include? table_name - else - # if the connection adapter hasn't implemented tables, there are two crude tests that can be - # used - see if getting column info raises an error, or if the number of columns returned is zero - begin - reset_column_information - columns.size > 0 - rescue ActiveRecord::StatementInvalid - false - end - end - end - - # Returns an array of column objects for the table associated with this class. - def columns - unless @columns - @columns = connection.columns(table_name, "#{name} Columns") - @columns.each {|column| column.primary = column.name == primary_key} - end - @columns - end - - # Returns an array of column objects for the table associated with this class. - def columns_hash - @columns_hash ||= columns.inject({}) { |hash, column| hash[column.name] = column; hash } - end - - def column_names - @column_names ||= columns.map { |column| column.name } - end - - # Returns an array of column objects where the primary id, all columns ending in "_id" or "_count", - # and columns used for single table inheritance have been removed. - def content_columns - @content_columns ||= columns.reject { |c| c.primary || c.name =~ /(_id|_count)$/ || c.name == inheritance_column } - end - - # Returns a hash of all the methods added to query each of the columns in the table with the name of the method as the key - # and true as the value. This makes it possible to do O(1) lookups in respond_to? to check if a given method for attribute - # is available. - def column_methods_hash - @dynamic_methods_hash ||= column_names.inject(Hash.new(false)) do |methods, attr| - attr_name = attr.to_s - methods[attr.to_sym] = attr_name - methods["#{attr}=".to_sym] = attr_name - methods["#{attr}?".to_sym] = attr_name - methods["#{attr}_before_type_cast".to_sym] = attr_name - methods - end - end - - # Contains the names of the generated reader methods. - def read_methods - @read_methods ||= Set.new - end - - # Resets all the cached information about columns, which will cause them to be reloaded on the next request. - def reset_column_information - read_methods.each { |name| undef_method(name) } - @column_names = @columns = @columns_hash = @content_columns = @dynamic_methods_hash = @read_methods = nil - end - - def reset_column_information_and_inheritable_attributes_for_all_subclasses#:nodoc: - subclasses.each { |klass| klass.reset_inheritable_attributes; klass.reset_column_information } - end - - # Transforms attribute key names into a more humane format, such as "First name" instead of "first_name". Example: - # Person.human_attribute_name("first_name") # => "First name" - # Deprecated in favor of just calling "first_name".humanize - def human_attribute_name(attribute_key_name) #:nodoc: - attribute_key_name.humanize - end - - def descends_from_active_record? # :nodoc: - superclass == Base || !columns_hash.include?(inheritance_column) - end - - def quote(object) #:nodoc: - connection.quote(object) - end - - # Used to sanitize objects before they're used in an SELECT SQL-statement. Delegates to connection.quote. - def sanitize(object) #:nodoc: - connection.quote(object) - end - - # Log and benchmark multiple statements in a single block. Example: - # - # Project.benchmark("Creating project") do - # project = Project.create("name" => "stuff") - # project.create_manager("name" => "David") - # project.milestones << Milestone.find(:all) - # end - # - # The benchmark is only recorded if the current level of the logger matches the log_level, which makes it - # easy to include benchmarking statements in production software that will remain inexpensive because the benchmark - # will only be conducted if the log level is low enough. - # - # The logging of the multiple statements is turned off unless use_silence is set to false. - def benchmark(title, log_level = Logger::DEBUG, use_silence = true) - if logger && logger.level == log_level - result = nil - seconds = Benchmark.realtime { result = use_silence ? silence { yield } : yield } - logger.add(log_level, "#{title} (#{'%.5f' % seconds})") - result - else - yield - end - end - - # Silences the logger for the duration of the block. - def silence - old_logger_level, logger.level = logger.level, Logger::ERROR if logger - yield - ensure - logger.level = old_logger_level if logger - end - - # Scope parameters to method calls within the block. Takes a hash of method_name => parameters hash. - # method_name may be :find or :create. - # :find parameters may include the :conditions, :joins, - # :offset, :limit, and :readonly options. - # :create parameters are an attributes hash. - # - # Article.with_scope(:find => { :conditions => "blog_id = 1" }, :create => { :blog_id => 1 }) do - # Article.find(1) # => SELECT * from articles WHERE blog_id = 1 AND id = 1 - # a = Article.create(1) - # a.blog_id == 1 - # end - def with_scope(method_scoping = {}) - # Dup first and second level of hash (method and params). - method_scoping = method_scoping.inject({}) do |hash, (method, params)| - hash[method] = params.dup - hash - end - - method_scoping.assert_valid_keys [:find, :create] - if f = method_scoping[:find] - f.assert_valid_keys [:conditions, :joins, :offset, :limit, :readonly] - f[:readonly] = true if !f[:joins].blank? && !f.has_key?(:readonly) - end - - raise ArgumentError, "Nested scopes are not yet supported: #{scoped_methods.inspect}" unless scoped_methods.nil? - - self.scoped_methods = method_scoping - yield - ensure - self.scoped_methods = nil - end - - # Overwrite the default class equality method to provide support for association proxies. - def ===(object) - object.is_a?(self) - end - - # Deprecated - def threaded_connections - allow_concurrency - end - - # Deprecated - def threaded_connections=(value) - self.allow_concurrency = value - end - - - private - # Finder methods must instantiate through this method to work with the single-table inheritance model - # that makes it possible to create objects of different types from the same table. - def instantiate(record) - object = - if subclass_name = record[inheritance_column] - if subclass_name.empty? - allocate - else - require_association_class(subclass_name) - begin - compute_type(subclass_name).allocate - rescue NameError - raise SubclassNotFound, - "The single-table inheritance mechanism failed to locate the subclass: '#{record[inheritance_column]}'. " + - "This error is raised because the column '#{inheritance_column}' is reserved for storing the class in case of inheritance. " + - "Please rename this column if you didn't intend it to be used for storing the inheritance class " + - "or overwrite #{self.to_s}.inheritance_column to use another column for that information." - end - end - else - allocate - end - - object.instance_variable_set("@attributes", record) - object - end - - # Returns the name of the type of the record using the current module as a prefix. So descendents of - # MyApp::Business::Account would appear as "MyApp::Business::AccountSubclass". - def type_name_with_module(type_name) - self.name =~ /::/ ? self.name.scan(/(.*)::/).first.first + "::" + type_name : type_name - end - - def construct_finder_sql(options) - sql = "SELECT #{options[:select] || '*'} FROM #{table_name} " - add_joins!(sql, options) - add_conditions!(sql, options[:conditions]) - sql << " GROUP BY #{options[:group]} " if options[:group] - sql << " ORDER BY #{options[:order]} " if options[:order] - add_limit!(sql, options) - sql - end - - def add_limit!(sql, options) - options[:limit] ||= scope(:find, :limit) - options[:offset] ||= scope(:find, :offset) - connection.add_limit_offset!(sql, options) - end - - def add_joins!(sql, options) - join = scope(:find, :joins) || options[:joins] - sql << " #{join} " if join - end - - # Adds a sanitized version of +conditions+ to the +sql+ string. Note that the passed-in +sql+ string is changed. - def add_conditions!(sql, conditions) - segments = [scope(:find, :conditions)] - segments << sanitize_sql(conditions) unless conditions.nil? - segments << type_condition unless descends_from_active_record? - segments.compact! - sql << "WHERE (#{segments.join(") AND (")}) " unless segments.empty? - end - - def type_condition - quoted_inheritance_column = connection.quote_column_name(inheritance_column) - type_condition = subclasses.inject("#{table_name}.#{quoted_inheritance_column} = '#{name.demodulize}' ") do |condition, subclass| - condition << "OR #{table_name}.#{quoted_inheritance_column} = '#{subclass.name.demodulize}' " - end - - " (#{type_condition}) " - end - - # Guesses the table name, but does not decorate it with prefix and suffix information. - def undecorated_table_name(class_name = class_name_of_active_record_descendant(self)) - table_name = Inflector.underscore(Inflector.demodulize(class_name)) - table_name = Inflector.pluralize(table_name) if pluralize_table_names - table_name - end - - # Enables dynamic finders like find_by_user_name(user_name) and find_by_user_name_and_password(user_name, password) that are turned into - # find(:first, :conditions => ["user_name = ?", user_name]) and find(:first, :conditions => ["user_name = ? AND password = ?", user_name, password]) - # respectively. Also works for find(:all), but using find_all_by_amount(50) that are turned into find(:all, :conditions => ["amount = ?", 50]). - # - # It's even possible to use all the additional parameters to find. For example, the full interface for find_all_by_amount - # is actually find_all_by_amount(amount, options). - def method_missing(method_id, *arguments) - if match = /find_(all_by|by)_([_a-zA-Z]\w*)/.match(method_id.to_s) - finder = determine_finder(match) - - attribute_names = extract_attribute_names_from_match(match) - super unless all_attributes_exists?(attribute_names) - - conditions = construct_conditions_from_arguments(attribute_names, arguments) - - if arguments[attribute_names.length].is_a?(Hash) - find(finder, { :conditions => conditions }.update(arguments[attribute_names.length])) - else - send("find_#{finder}", conditions, *arguments[attribute_names.length..-1]) # deprecated API - end - elsif match = /find_or_create_by_([_a-zA-Z]\w*)/.match(method_id.to_s) - attribute_names = extract_attribute_names_from_match(match) - super unless all_attributes_exists?(attribute_names) - - find(:first, :conditions => construct_conditions_from_arguments(attribute_names, arguments)) || - create(construct_attributes_from_arguments(attribute_names, arguments)) - else - super - end - end - - def determine_finder(match) - match.captures.first == 'all_by' ? :all : :first - end - - def extract_attribute_names_from_match(match) - match.captures.last.split('_and_') - end - - def construct_conditions_from_arguments(attribute_names, arguments) - conditions = [] - attribute_names.each_with_index { |name, idx| conditions << "#{table_name}.#{connection.quote_column_name(name)} #{attribute_condition(arguments[idx])} " } - [ conditions.join(" AND "), *arguments[0...attribute_names.length] ] - end - - def construct_attributes_from_arguments(attribute_names, arguments) - attributes = {} - attribute_names.each_with_index { |name, idx| attributes[name] = arguments[idx] } - attributes - end - - def all_attributes_exists?(attribute_names) - attribute_names.all? { |name| column_methods_hash.include?(name.to_sym) } - end - - def attribute_condition(argument) - case argument - when nil then "IS ?" - when Array then "IN (?)" - else "= ?" - end - end - - # Defines an "attribute" method (like #inheritance_column or - # #table_name). A new (class) method will be created with the - # given name. If a value is specified, the new method will - # return that value (as a string). Otherwise, the given block - # will be used to compute the value of the method. - # - # The original method will be aliased, with the new name being - # prefixed with "original_". This allows the new method to - # access the original value. - # - # Example: - # - # class A < ActiveRecord::Base - # define_attr_method :primary_key, "sysid" - # define_attr_method( :inheritance_column ) do - # original_inheritance_column + "_id" - # end - # end - def define_attr_method(name, value=nil, &block) - sing = class << self; self; end - sing.send :alias_method, "original_#{name}", name - if block_given? - sing.send :define_method, name, &block - else - # use eval instead of a block to work around a memory leak in dev - # mode in fcgi - sing.class_eval "def #{name}; #{value.to_s.inspect}; end" - end - end - - protected - def subclasses - @@subclasses[self] ||= [] - @@subclasses[self] + extra = @@subclasses[self].inject([]) {|list, subclass| list + subclass.subclasses } - end - - # Test whether the given method and optional key are scoped. - def scoped?(method, key = nil) - scoped_methods and scoped_methods.has_key?(method) and (key.nil? or scope(method).has_key?(key)) - end - - # Retrieve the scope for the given method and optional key. - def scope(method, key = nil) - if scoped_methods and scope = scoped_methods[method] - key ? scope[key] : scope - end - end - - def scoped_methods - if allow_concurrency - Thread.current[:scoped_methods] ||= {} - Thread.current[:scoped_methods][self] ||= nil - else - @scoped_methods ||= nil - end - end - - def scoped_methods=(value) - if allow_concurrency - Thread.current[:scoped_methods] ||= {} - Thread.current[:scoped_methods][self] = value - else - @scoped_methods = value - end - end - - # Returns the class type of the record using the current module as a prefix. So descendents of - # MyApp::Business::Account would appear as MyApp::Business::AccountSubclass. - def compute_type(type_name) - type_name_with_module(type_name).split("::").inject(Object) do |final_type, part| - final_type.const_get(part) - end - end - - # Returns the name of the class descending directly from ActiveRecord in the inheritance hierarchy. - def class_name_of_active_record_descendant(klass) - if klass.superclass == Base - klass.name - elsif klass.superclass.nil? - raise ActiveRecordError, "#{name} doesn't belong in a hierarchy descending from ActiveRecord" - else - class_name_of_active_record_descendant(klass.superclass) - end - end - - # Accepts an array or string. The string is returned untouched, but the array has each value - # sanitized and interpolated into the sql statement. - # ["name='%s' and group_id='%s'", "foo'bar", 4] returns "name='foo''bar' and group_id='4'" - def sanitize_sql(ary) - return ary unless ary.is_a?(Array) - - statement, *values = ary - if values.first.is_a?(Hash) and statement =~ /:\w+/ - replace_named_bind_variables(statement, values.first) - elsif statement.include?('?') - replace_bind_variables(statement, values) - else - statement % values.collect { |value| connection.quote_string(value.to_s) } - end - end - - alias_method :sanitize_conditions, :sanitize_sql - - def replace_bind_variables(statement, values) - raise_if_bind_arity_mismatch(statement, statement.count('?'), values.size) - bound = values.dup - statement.gsub('?') { quote_bound_value(bound.shift) } - end - - def replace_named_bind_variables(statement, bind_vars) - raise_if_bind_arity_mismatch(statement, statement.scan(/:(\w+)/).uniq.size, bind_vars.size) - statement.gsub(/:(\w+)/) do - match = $1.to_sym - if bind_vars.include?(match) - quote_bound_value(bind_vars[match]) - else - raise PreparedStatementInvalid, "missing value for :#{match} in #{statement}" - end - end - end - - def quote_bound_value(value) - if (value.respond_to?(:map) && !value.is_a?(String)) - value.map { |v| connection.quote(v) }.join(',') - else - connection.quote(value) - end - end - - def raise_if_bind_arity_mismatch(statement, expected, provided) - unless expected == provided - raise PreparedStatementInvalid, "wrong number of bind variables (#{provided} for #{expected}) in: #{statement}" - end - end - - def extract_options_from_args!(args) - options = args.last.is_a?(Hash) ? args.pop : {} - validate_find_options(options) - options - end - - def validate_find_options(options) - options.assert_valid_keys [:conditions, :include, :joins, :limit, :offset, :order, :select, :readonly, :group] - end - - def encode_quoted_value(value) - quoted_value = connection.quote(value) - quoted_value = "'#{quoted_value[1..-2].gsub(/\'/, "\\\\'")}'" if quoted_value.include?("\\\'") # (for ruby mode) " - quoted_value - end - end - - public - # New objects can be instantiated as either empty (pass no construction parameter) or pre-set with - # attributes but not yet saved (pass a hash with key names matching the associated table column names). - # In both instances, valid attribute keys are determined by the column names of the associated table -- - # hence you can't have attributes that aren't part of the table columns. - def initialize(attributes = nil) - @attributes = attributes_from_column_definition - @new_record = true - ensure_proper_type - self.attributes = attributes unless attributes.nil? - yield self if block_given? - end - - # A model instance's primary key is always available as model.id - # whether you name it the default 'id' or set it to something else. - def id - attr_name = self.class.primary_key - column = column_for_attribute(attr_name) - define_read_method(:id, attr_name, column) if self.class.generate_read_methods - read_attribute(attr_name) - end - - # Enables Active Record objects to be used as URL parameters in Action Pack automatically. - alias_method :to_param, :id - - def id_before_type_cast #:nodoc: - read_attribute_before_type_cast(self.class.primary_key) - end - - def quoted_id #:nodoc: - quote(id, column_for_attribute(self.class.primary_key)) - end - - # Sets the primary ID. - def id=(value) - write_attribute(self.class.primary_key, value) - end - - # Returns true if this object hasn't been saved yet -- that is, a record for the object doesn't exist yet. - def new_record? - @new_record - end - - # * No record exists: Creates a new record with values matching those of the object attributes. - # * A record does exist: Updates the record with values matching those of the object attributes. - def save - raise ActiveRecord::ReadOnlyRecord if readonly? - create_or_update - end - - # Deletes the record in the database and freezes this instance to reflect that no changes should - # be made (since they can't be persisted). - def destroy - unless new_record? - connection.delete <<-end_sql, "#{self.class.name} Destroy" - DELETE FROM #{self.class.table_name} - WHERE #{self.class.primary_key} = #{quoted_id} - end_sql - end - - freeze - end - - # Returns a clone of the record that hasn't been assigned an id yet and - # is treated as a new record. Note that this is a "shallow" clone: - # it copies the object's attributes only, not its associations. - # The extent of a "deep" clone is application-specific and is therefore - # left to the application to implement according to its need. - def clone - attrs = self.attributes_before_type_cast - attrs.delete(self.class.primary_key) - self.class.new do |record| - record.send :instance_variable_set, '@attributes', attrs - end - end - - # Updates a single attribute and saves the record. This is especially useful for boolean flags on existing records. - # Note: This method is overwritten by the Validation module that'll make sure that updates made with this method - # doesn't get subjected to validation checks. Hence, attributes can be updated even if the full object isn't valid. - def update_attribute(name, value) - send(name.to_s + '=', value) - save - end - - # Updates all the attributes from the passed-in Hash and saves the record. If the object is invalid, the saving will - # fail and false will be returned. - def update_attributes(attributes) - self.attributes = attributes - save - end - - # Initializes the +attribute+ to zero if nil and adds one. Only makes sense for number-based attributes. Returns self. - def increment(attribute) - self[attribute] ||= 0 - self[attribute] += 1 - self - end - - # Increments the +attribute+ and saves the record. - def increment!(attribute) - increment(attribute).update_attribute(attribute, self[attribute]) - end - - # Initializes the +attribute+ to zero if nil and subtracts one. Only makes sense for number-based attributes. Returns self. - def decrement(attribute) - self[attribute] ||= 0 - self[attribute] -= 1 - self - end - - # Decrements the +attribute+ and saves the record. - def decrement!(attribute) - decrement(attribute).update_attribute(attribute, self[attribute]) - end - - # Turns an +attribute+ that's currently true into false and vice versa. Returns self. - def toggle(attribute) - self[attribute] = !send("#{attribute}?") - self - end - - # Toggles the +attribute+ and saves the record. - def toggle!(attribute) - toggle(attribute).update_attribute(attribute, self[attribute]) - end - - # Reloads the attributes of this object from the database. - def reload - clear_aggregation_cache - clear_association_cache - @attributes.update(self.class.find(self.id).instance_variable_get('@attributes')) - self - end - - # Returns the value of the attribute identified by attr_name after it has been typecast (for example, - # "2004-12-12" in a data column is cast to a date object, like Date.new(2004, 12, 12)). - # (Alias for the protected read_attribute method). - def [](attr_name) - read_attribute(attr_name) - end - - # Updates the attribute identified by attr_name with the specified +value+. - # (Alias for the protected write_attribute method). - def []=(attr_name, value) - write_attribute(attr_name, value) - end - - # Allows you to set all the attributes at once by passing in a hash with keys - # matching the attribute names (which again matches the column names). Sensitive attributes can be protected - # from this form of mass-assignment by using the +attr_protected+ macro. Or you can alternatively - # specify which attributes *can* be accessed in with the +attr_accessible+ macro. Then all the - # attributes not included in that won't be allowed to be mass-assigned. - def attributes=(attributes) - return if attributes.nil? - attributes.stringify_keys! - - multi_parameter_attributes = [] - remove_attributes_protected_from_mass_assignment(attributes).each do |k, v| - k.include?("(") ? multi_parameter_attributes << [ k, v ] : send(k + "=", v) - end - assign_multiparameter_attributes(multi_parameter_attributes) - end - - # Returns a hash of all the attributes with their names as keys and clones of their objects as values. - def attributes - clone_attributes :read_attribute - end - - # Returns a hash of cloned attributes before typecasting and deserialization. - def attributes_before_type_cast - clone_attributes :read_attribute_before_type_cast - end - - # Returns true if the specified +attribute+ has been set by the user or by a database load and is neither - # nil nor empty? (the latter only applies to objects that respond to empty?, most notably Strings). - def attribute_present?(attribute) - value = read_attribute(attribute) - !value.blank? or value == 0 - end - - # Returns true if the given attribute is in the attributes hash - def has_attribute?(attr_name) - @attributes.has_key?(attr_name.to_s) - end - - # Returns an array of names for the attributes available on this object sorted alphabetically. - def attribute_names - @attributes.keys.sort - end - - # Returns the column object for the named attribute. - def column_for_attribute(name) - self.class.columns_hash[name.to_s] - end - - # Returns true if the +comparison_object+ is the same object, or is of the same type and has the same id. - def ==(comparison_object) - comparison_object.equal?(self) || - (comparison_object.instance_of?(self.class) && - comparison_object.id == id && - !comparison_object.new_record?) - end - - # Delegates to == - def eql?(comparison_object) - self == (comparison_object) - end - - # Delegates to id in order to allow two records of the same type and id to work with something like: - # [ Person.find(1), Person.find(2), Person.find(3) ] & [ Person.find(1), Person.find(4) ] # => [ Person.find(1) ] - def hash - id.hash - end - - # For checking respond_to? without searching the attributes (which is faster). - alias_method :respond_to_without_attributes?, :respond_to? - - # A Person object with a name attribute can ask person.respond_to?("name"), person.respond_to?("name="), and - # person.respond_to?("name?") which will all return true. - def respond_to?(method, include_priv = false) - if attr_name = self.class.column_methods_hash[method.to_sym] - return true if @attributes.include?(attr_name) || attr_name == self.class.primary_key - return false if self.class.read_methods.include?(attr_name) - elsif @attributes.include?(method_name = method.to_s) - return true - elsif md = /(=|\?|_before_type_cast)$/.match(method_name) - return true if @attributes.include?(md.pre_match) - end - # super must be called at the end of the method, because the inherited respond_to? - # would return true for generated readers, even if the attribute wasn't present - super - end - - # Just freeze the attributes hash, such that associations are still accessible even on destroyed records. - def freeze - @attributes.freeze; self - end - - def frozen? - @attributes.frozen? - end - - def readonly? - @readonly == true - end - - def readonly! - @readonly = true - end - - private - def create_or_update - if new_record? then create else update end - end - - # Updates the associated record with values matching those of the instance attributes. - def update - connection.update( - "UPDATE #{self.class.table_name} " + - "SET #{quoted_comma_pair_list(connection, attributes_with_quotes(false))} " + - "WHERE #{self.class.primary_key} = #{quote(id)}", - "#{self.class.name} Update" - ) - end - - # Creates a new record with values matching those of the instance attributes. - def create - if self.id.nil? and connection.prefetch_primary_key?(self.class.table_name) - self.id = connection.next_sequence_value(self.class.sequence_name) - end - - self.id = connection.insert( - "INSERT INTO #{self.class.table_name} " + - "(#{quoted_column_names.join(', ')}) " + - "VALUES(#{attributes_with_quotes.values.join(', ')})", - "#{self.class.name} Create", - self.class.primary_key, self.id, self.class.sequence_name - ) - - @new_record = false - end - - # Sets the attribute used for single table inheritance to this class name if this is not the ActiveRecord descendent. - # Considering the hierarchy Reply < Message < ActiveRecord, this makes it possible to do Reply.new without having to - # set Reply[Reply.inheritance_column] = "Reply" yourself. No such attribute would be set for objects of the - # Message class in that example. - def ensure_proper_type - unless self.class.descends_from_active_record? - write_attribute(self.class.inheritance_column, Inflector.demodulize(self.class.name)) - end - end - - # Allows access to the object attributes, which are held in the @attributes hash, as were - # they first-class methods. So a Person class with a name attribute can use Person#name and - # Person#name= and never directly use the attributes hash -- except for multiple assigns with - # ActiveRecord#attributes=. A Milestone class can also ask Milestone#completed? to test that - # the completed attribute is not nil or 0. - # - # It's also possible to instantiate related objects, so a Client class belonging to the clients - # table with a master_id foreign key can instantiate master through Client#master. - def method_missing(method_id, *args, &block) - method_name = method_id.to_s - if @attributes.include?(method_name) - define_read_methods if self.class.read_methods.empty? && self.class.generate_read_methods - read_attribute(method_name) - elsif self.class.primary_key.to_s == method_name - id - elsif md = /(=|\?|_before_type_cast)$/.match(method_name) - attribute_name, method_type = md.pre_match, md.to_s - if @attributes.include?(attribute_name) - case method_type - when '=' - write_attribute(attribute_name, args.first) - when '?' - query_attribute(attribute_name) - when '_before_type_cast' - read_attribute_before_type_cast(attribute_name) - end - else - super - end - else - super - end - end - - # Returns the value of the attribute identified by attr_name after it has been typecast (for example, - # "2004-12-12" in a data column is cast to a date object, like Date.new(2004, 12, 12)). - def read_attribute(attr_name) - attr_name = attr_name.to_s - if !(value = @attributes[attr_name]).nil? - if column = column_for_attribute(attr_name) - if unserializable_attribute?(attr_name, column) - unserialize_attribute(attr_name) - else - column.type_cast(value) - end - else - value - end - else - nil - end - end - - def read_attribute_before_type_cast(attr_name) - @attributes[attr_name] - end - - # Called on first read access to any given column and generates reader - # methods for all columns in the columns_hash if - # ActiveRecord::Base.generate_read_methods is set to true. - def define_read_methods - self.class.columns_hash.each do |name, column| - unless self.class.serialized_attributes[name] || respond_to_without_attributes?(name) - define_read_method(name.to_sym, name, column) - end - end - end - - # Define an attribute reader method. Cope with nil column. - def define_read_method(symbol, attr_name, column) - cast_code = column.type_cast_code('v') if column - access_code = cast_code ? "(v=@attributes['#{attr_name}']) && #{cast_code}" : "@attributes['#{attr_name}']" - - unless attr_name.to_s == self.class.primary_key.to_s - access_code = access_code.insert(0, "raise NoMethodError, 'missing attribute: #{attr_name}', caller unless @attributes.has_key?('#{attr_name}'); ") - self.class.read_methods << attr_name - end - - begin - self.class.class_eval("def #{symbol}; #{access_code}; end") - rescue SyntaxError => err - self.class.read_methods.delete(attr_name) - if logger - logger.warn "Exception occured during reader method compilation." - logger.warn "Maybe #{attr_name} is not a valid Ruby identifier?" - logger.warn "#{err.message}" - end - end - end - - # Returns true if the attribute is of a text column and marked for serialization. - def unserializable_attribute?(attr_name, column) - column.text? && self.class.serialized_attributes[attr_name] - end - - # Returns the unserialized object of the attribute. - def unserialize_attribute(attr_name) - unserialized_object = object_from_yaml(@attributes[attr_name]) - - if unserialized_object.is_a?(self.class.serialized_attributes[attr_name]) - @attributes[attr_name] = unserialized_object - else - raise SerializationTypeMismatch, - "#{attr_name} was supposed to be a #{self.class.serialized_attributes[attr_name]}, but was a #{unserialized_object.class.to_s}" - end - end - - # Updates the attribute identified by attr_name with the specified +value+. Empty strings for fixnum and float - # columns are turned into nil. - def write_attribute(attr_name, value) - attr_name = attr_name.to_s - if (column = column_for_attribute(attr_name)) && column.number? - @attributes[attr_name] = convert_number_column_value(value) - else - @attributes[attr_name] = value - end - end - - def convert_number_column_value(value) - case value - when FalseClass: 0 - when TrueClass: 1 - when '': nil - else value - end - end - - def query_attribute(attr_name) - attribute = @attributes[attr_name] - if attribute.kind_of?(Fixnum) && attribute == 0 - false - elsif attribute.kind_of?(String) && attribute == "0" - false - elsif attribute.kind_of?(String) && attribute.empty? - false - elsif attribute.nil? - false - elsif attribute == false - false - elsif attribute == "f" - false - elsif attribute == "false" - false - else - true - end - end - - def remove_attributes_protected_from_mass_assignment(attributes) - if self.class.accessible_attributes.nil? && self.class.protected_attributes.nil? - attributes.reject { |key, value| attributes_protected_by_default.include?(key.gsub(/\(.+/, "")) } - elsif self.class.protected_attributes.nil? - attributes.reject { |key, value| !self.class.accessible_attributes.include?(key.gsub(/\(.+/, "").intern) || attributes_protected_by_default.include?(key.gsub(/\(.+/, "")) } - elsif self.class.accessible_attributes.nil? - attributes.reject { |key, value| self.class.protected_attributes.include?(key.gsub(/\(.+/,"").intern) || attributes_protected_by_default.include?(key.gsub(/\(.+/, "")) } - end - end - - # The primary key and inheritance column can never be set by mass-assignment for security reasons. - def attributes_protected_by_default - default = [ self.class.primary_key, self.class.inheritance_column ] - default << 'id' unless self.class.primary_key.eql? 'id' - default - end - - # Returns copy of the attributes hash where all the values have been safely quoted for use in - # an SQL statement. - def attributes_with_quotes(include_primary_key = true) - attributes.inject({}) do |quoted, (name, value)| - if column = column_for_attribute(name) - quoted[name] = quote(value, column) unless !include_primary_key && column.primary - end - quoted - end - end - - # Quote strings appropriately for SQL statements. - def quote(value, column = nil) - self.class.connection.quote(value, column) - end - - # Interpolate custom sql string in instance context. - # Optional record argument is meant for custom insert_sql. - def interpolate_sql(sql, record = nil) - instance_eval("%@#{sql.gsub('@', '\@')}@") - end - - # Initializes the attributes array with keys matching the columns from the linked table and - # the values matching the corresponding default value of that column, so - # that a new instance, or one populated from a passed-in Hash, still has all the attributes - # that instances loaded from the database would. - def attributes_from_column_definition - self.class.columns.inject({}) do |attributes, column| - attributes[column.name] = column.default unless column.name == self.class.primary_key - attributes - end - end - - # Instantiates objects for all attribute classes that needs more than one constructor parameter. This is done - # by calling new on the column type or aggregation type (through composed_of) object with these parameters. - # So having the pairs written_on(1) = "2004", written_on(2) = "6", written_on(3) = "24", will instantiate - # written_on (a date type) with Date.new("2004", "6", "24"). You can also specify a typecast character in the - # parentheses to have the parameters typecasted before they're used in the constructor. Use i for Fixnum, f for Float, - # s for String, and a for Array. If all the values for a given attribute is empty, the attribute will be set to nil. - def assign_multiparameter_attributes(pairs) - execute_callstack_for_multiparameter_attributes( - extract_callstack_for_multiparameter_attributes(pairs) - ) - end - - # Includes an ugly hack for Time.local instead of Time.new because the latter is reserved by Time itself. - def execute_callstack_for_multiparameter_attributes(callstack) - errors = [] - callstack.each do |name, values| - klass = (self.class.reflect_on_aggregation(name) || column_for_attribute(name)).klass - if values.empty? - send(name + "=", nil) - else - begin - send(name + "=", Time == klass ? klass.local(*values) : klass.new(*values)) - rescue => ex - errors << AttributeAssignmentError.new("error on assignment #{values.inspect} to #{name}", ex, name) - end - end - end - unless errors.empty? - raise MultiparameterAssignmentErrors.new(errors), "#{errors.size} error(s) on assignment of multiparameter attributes" - end - end - - def extract_callstack_for_multiparameter_attributes(pairs) - attributes = { } - - for pair in pairs - multiparameter_name, value = pair - attribute_name = multiparameter_name.split("(").first - attributes[attribute_name] = [] unless attributes.include?(attribute_name) - - unless value.empty? - attributes[attribute_name] << - [ find_parameter_position(multiparameter_name), type_cast_attribute_value(multiparameter_name, value) ] - end - end - - attributes.each { |name, values| attributes[name] = values.sort_by{ |v| v.first }.collect { |v| v.last } } - end - - def type_cast_attribute_value(multiparameter_name, value) - multiparameter_name =~ /\([0-9]*([a-z])\)/ ? value.send("to_" + $1) : value - end - - def find_parameter_position(multiparameter_name) - multiparameter_name.scan(/\(([0-9]*).*\)/).first.first - end - - # Returns a comma-separated pair list, like "key1 = val1, key2 = val2". - def comma_pair_list(hash) - hash.inject([]) { |list, pair| list << "#{pair.first} = #{pair.last}" }.join(", ") - end - - def quoted_column_names(attributes = attributes_with_quotes) - attributes.keys.collect do |column_name| - self.class.connection.quote_column_name(column_name) - end - end - - def quote_columns(quoter, hash) - hash.inject({}) do |quoted, (name, value)| - quoted[quoter.quote_column_name(name)] = value - quoted - end - end - - def quoted_comma_pair_list(quoter, hash) - comma_pair_list(quote_columns(quoter, hash)) - end - - def object_from_yaml(string) - return string unless string.is_a?(String) - YAML::load(string) rescue string - end - - def clone_attributes(reader_method = :read_attribute, attributes = {}) - self.attribute_names.inject(attributes) do |attributes, name| - attributes[name] = clone_attribute_value(reader_method, name) - attributes - end - end - - def clone_attribute_value(reader_method, attribute_name) - value = send(reader_method, attribute_name) - value.clone - rescue TypeError, NoMethodError - value - end - end -end diff --git a/tracks/vendor/rails/activerecord/lib/active_record/callbacks.rb b/tracks/vendor/rails/activerecord/lib/active_record/callbacks.rb deleted file mode 100644 index aa3aa2d1..00000000 --- a/tracks/vendor/rails/activerecord/lib/active_record/callbacks.rb +++ /dev/null @@ -1,367 +0,0 @@ -require 'observer' - -module ActiveRecord - # Callbacks are hooks into the lifecycle of an Active Record object that allows you to trigger logic - # before or after an alteration of the object state. This can be used to make sure that associated and - # dependent objects are deleted when destroy is called (by overwriting before_destroy) or to massage attributes - # before they're validated (by overwriting before_validation). As an example of the callbacks initiated, consider - # the Base#save call: - # - # * (-) save - # * (-) valid? - # * (1) before_validation - # * (2) before_validation_on_create - # * (-) validate - # * (-) validate_on_create - # * (4) after_validation - # * (5) after_validation_on_create - # * (6) before_save - # * (7) before_create - # * (-) create - # * (8) after_create - # * (9) after_save - # - # That's a total of nine callbacks, which gives you immense power to react and prepare for each state in the - # Active Record lifecycle. - # - # Examples: - # class CreditCard < ActiveRecord::Base - # # Strip everything but digits, so the user can specify "555 234 34" or - # # "5552-3434" or both will mean "55523434" - # def before_validation_on_create - # self.number = number.gsub(/[^0-9]/, "") if attribute_present?("number") - # end - # end - # - # class Subscription < ActiveRecord::Base - # before_create :record_signup - # - # private - # def record_signup - # self.signed_up_on = Date.today - # end - # end - # - # class Firm < ActiveRecord::Base - # # Destroys the associated clients and people when the firm is destroyed - # before_destroy { |record| Person.destroy_all "firm_id = #{record.id}" } - # before_destroy { |record| Client.destroy_all "client_of = #{record.id}" } - # end - # - # == Inheritable callback queues - # - # Besides the overwriteable callback methods, it's also possible to register callbacks through the use of the callback macros. - # Their main advantage is that the macros add behavior into a callback queue that is kept intact down through an inheritance - # hierarchy. Example: - # - # class Topic < ActiveRecord::Base - # before_destroy :destroy_author - # end - # - # class Reply < Topic - # before_destroy :destroy_readers - # end - # - # Now, when Topic#destroy is run only +destroy_author+ is called. When Reply#destroy is run both +destroy_author+ and - # +destroy_readers+ is called. Contrast this to the situation where we've implemented the save behavior through overwriteable - # methods: - # - # class Topic < ActiveRecord::Base - # def before_destroy() destroy_author end - # end - # - # class Reply < Topic - # def before_destroy() destroy_readers end - # end - # - # In that case, Reply#destroy would only run +destroy_readers+ and _not_ +destroy_author+. So use the callback macros when - # you want to ensure that a certain callback is called for the entire hierarchy and the regular overwriteable methods when you - # want to leave it up to each descendent to decide whether they want to call +super+ and trigger the inherited callbacks. - # - # *IMPORTANT:* In order for inheritance to work for the callback queues, you must specify the callbacks before specifying the - # associations. Otherwise, you might trigger the loading of a child before the parent has registered the callbacks and they won't - # be inherited. - # - # == Types of callbacks - # - # There are four types of callbacks accepted by the callback macros: Method references (symbol), callback objects, - # inline methods (using a proc), and inline eval methods (using a string). Method references and callback objects are the - # recommended approaches, inline methods using a proc are sometimes appropriate (such as for creating mix-ins), and inline - # eval methods are deprecated. - # - # The method reference callbacks work by specifying a protected or private method available in the object, like this: - # - # class Topic < ActiveRecord::Base - # before_destroy :delete_parents - # - # private - # def delete_parents - # self.class.delete_all "parent_id = #{id}" - # end - # end - # - # The callback objects have methods named after the callback called with the record as the only parameter, such as: - # - # class BankAccount < ActiveRecord::Base - # before_save EncryptionWrapper.new("credit_card_number") - # after_save EncryptionWrapper.new("credit_card_number") - # after_initialize EncryptionWrapper.new("credit_card_number") - # end - # - # class EncryptionWrapper - # def initialize(attribute) - # @attribute = attribute - # end - # - # def before_save(record) - # record.credit_card_number = encrypt(record.credit_card_number) - # end - # - # def after_save(record) - # record.credit_card_number = decrypt(record.credit_card_number) - # end - # - # alias_method :after_find, :after_save - # - # private - # def encrypt(value) - # # Secrecy is committed - # end - # - # def decrypt(value) - # # Secrecy is unveiled - # end - # end - # - # So you specify the object you want messaged on a given callback. When that callback is triggered, the object has - # a method by the name of the callback messaged. - # - # The callback macros usually accept a symbol for the method they're supposed to run, but you can also pass a "method string", - # which will then be evaluated within the binding of the callback. Example: - # - # class Topic < ActiveRecord::Base - # before_destroy 'self.class.delete_all "parent_id = #{id}"' - # end - # - # Notice that single plings (') are used so the #{id} part isn't evaluated until the callback is triggered. Also note that these - # inline callbacks can be stacked just like the regular ones: - # - # class Topic < ActiveRecord::Base - # before_destroy 'self.class.delete_all "parent_id = #{id}"', - # 'puts "Evaluated after parents are destroyed"' - # end - # - # == The after_find and after_initialize exceptions - # - # Because after_find and after_initialize are called for each object found and instantiated by a finder, such as Base.find(:all), we've had - # to implement a simple performance constraint (50% more speed on a simple test case). Unlike all the other callbacks, after_find and - # after_initialize will only be run if an explicit implementation is defined (def after_find). In that case, all of the - # callback types will be called. - # - # == Cancelling callbacks - # - # If a before_* callback returns false, all the later callbacks and the associated action are cancelled. If an after_* callback returns - # false, all the later callbacks are cancelled. Callbacks are generally run in the order they are defined, with the exception of callbacks - # defined as methods on the model, which are called last. - module Callbacks - CALLBACKS = %w( - after_find after_initialize before_save after_save before_create after_create before_update after_update before_validation - after_validation before_validation_on_create after_validation_on_create before_validation_on_update - after_validation_on_update before_destroy after_destroy - ) - - def self.append_features(base) #:nodoc: - super - - base.extend(ClassMethods) - base.class_eval do - class << self - include Observable - alias_method :instantiate_without_callbacks, :instantiate - alias_method :instantiate, :instantiate_with_callbacks - end - - alias_method :initialize_without_callbacks, :initialize - alias_method :initialize, :initialize_with_callbacks - - alias_method :create_or_update_without_callbacks, :create_or_update - alias_method :create_or_update, :create_or_update_with_callbacks - - alias_method :valid_without_callbacks, :valid? - alias_method :valid?, :valid_with_callbacks - - alias_method :create_without_callbacks, :create - alias_method :create, :create_with_callbacks - - alias_method :update_without_callbacks, :update - alias_method :update, :update_with_callbacks - - alias_method :destroy_without_callbacks, :destroy - alias_method :destroy, :destroy_with_callbacks - end - - CALLBACKS.each do |method| - base.class_eval <<-"end_eval" - def self.#{method}(*callbacks, &block) - callbacks << block if block_given? - write_inheritable_array(#{method.to_sym.inspect}, callbacks) - end - end_eval - end - end - - module ClassMethods #:nodoc: - def instantiate_with_callbacks(record) - object = instantiate_without_callbacks(record) - - if object.respond_to_without_attributes?(:after_find) - object.send(:callback, :after_find) - end - - if object.respond_to_without_attributes?(:after_initialize) - object.send(:callback, :after_initialize) - end - - object - end - end - - # Is called when the object was instantiated by one of the finders, like Base.find. - #def after_find() end - - # Is called after the object has been instantiated by a call to Base.new. - #def after_initialize() end - - def initialize_with_callbacks(attributes = nil) #:nodoc: - initialize_without_callbacks(attributes) - result = yield self if block_given? - callback(:after_initialize) if respond_to_without_attributes?(:after_initialize) - result - end - - # Is called _before_ Base.save (regardless of whether it's a create or update save). - def before_save() end - - # Is called _after_ Base.save (regardless of whether it's a create or update save). - def after_save() end - def create_or_update_with_callbacks #:nodoc: - return false if callback(:before_save) == false - result = create_or_update_without_callbacks - callback(:after_save) - result - end - - # Is called _before_ Base.save on new objects that haven't been saved yet (no record exists). - def before_create() end - - # Is called _after_ Base.save on new objects that haven't been saved yet (no record exists). - def after_create() end - def create_with_callbacks #:nodoc: - return false if callback(:before_create) == false - result = create_without_callbacks - callback(:after_create) - result - end - - # Is called _before_ Base.save on existing objects that have a record. - def before_update() end - - # Is called _after_ Base.save on existing objects that have a record. - def after_update() end - - def update_with_callbacks #:nodoc: - return false if callback(:before_update) == false - result = update_without_callbacks - callback(:after_update) - result - end - - # Is called _before_ Validations.validate (which is part of the Base.save call). - def before_validation() end - - # Is called _after_ Validations.validate (which is part of the Base.save call). - def after_validation() end - - # Is called _before_ Validations.validate (which is part of the Base.save call) on new objects - # that haven't been saved yet (no record exists). - def before_validation_on_create() end - - # Is called _after_ Validations.validate (which is part of the Base.save call) on new objects - # that haven't been saved yet (no record exists). - def after_validation_on_create() end - - # Is called _before_ Validations.validate (which is part of the Base.save call) on - # existing objects that have a record. - def before_validation_on_update() end - - # Is called _after_ Validations.validate (which is part of the Base.save call) on - # existing objects that have a record. - def after_validation_on_update() end - - def valid_with_callbacks #:nodoc: - return false if callback(:before_validation) == false - if new_record? then result = callback(:before_validation_on_create) else result = callback(:before_validation_on_update) end - return false if result == false - - result = valid_without_callbacks - - callback(:after_validation) - if new_record? then callback(:after_validation_on_create) else callback(:after_validation_on_update) end - - return result - end - - # Is called _before_ Base.destroy. - def before_destroy() end - - # Is called _after_ Base.destroy (and all the attributes have been frozen). - def after_destroy() end - def destroy_with_callbacks #:nodoc: - return false if callback(:before_destroy) == false - result = destroy_without_callbacks - callback(:after_destroy) - result - end - - private - def callback(method) - notify(method) - - callbacks_for(method).each do |callback| - result = case callback - when Symbol - self.send(callback) - when String - eval(callback, binding) - when Proc, Method - callback.call(self) - else - if callback.respond_to?(method) - callback.send(method, self) - else - raise ActiveRecordError, "Callbacks must be a symbol denoting the method to call, a string to be evaluated, a block to be invoked, or an object responding to the callback method." - end - end - return false if result == false - end - - result = send(method) if respond_to_without_attributes?(method) - - return result - end - - def callbacks_for(method) - self.class.read_inheritable_attribute(method.to_sym) or [] - end - - def invoke_and_notify(method) - notify(method) - send(method) if respond_to_without_attributes?(method) - end - - def notify(method) #:nodoc: - self.class.changed - self.class.notify_observers(method, self) - end - end -end diff --git a/tracks/vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/connection_specification.rb b/tracks/vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/connection_specification.rb deleted file mode 100644 index bba4bbb1..00000000 --- a/tracks/vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/connection_specification.rb +++ /dev/null @@ -1,153 +0,0 @@ -module ActiveRecord - class Base - class ConnectionSpecification #:nodoc: - attr_reader :config, :adapter_method - def initialize (config, adapter_method) - @config, @adapter_method = config, adapter_method - end - end - - # The class -> [adapter_method, config] map - @@defined_connections = {} - - # The class -> thread id -> adapter cache. - @@connection_cache = Hash.new { |h, k| h[k] = Hash.new } - - # Returns the connection currently associated with the class. This can - # also be used to "borrow" the connection to do database work unrelated - # to any of the specific Active Records. - def self.connection - @@connection_cache[Thread.current.object_id][name] ||= retrieve_connection - end - - # Clears the cache which maps classes to connections. - def self.clear_connection_cache! - @@connection_cache.clear - end - - # Returns the connection currently associated with the class. This can - # also be used to "borrow" the connection to do database work that isn't - # easily done without going straight to SQL. - def connection - self.class.connection - end - - # Establishes the connection to the database. Accepts a hash as input where - # the :adapter key must be specified with the name of a database adapter (in lower-case) - # example for regular databases (MySQL, Postgresql, etc): - # - # ActiveRecord::Base.establish_connection( - # :adapter => "mysql", - # :host => "localhost", - # :username => "myuser", - # :password => "mypass", - # :database => "somedatabase" - # ) - # - # Example for SQLite database: - # - # ActiveRecord::Base.establish_connection( - # :adapter => "sqlite", - # :database => "path/to/dbfile" - # ) - # - # Also accepts keys as strings (for parsing from yaml for example): - # ActiveRecord::Base.establish_connection( - # "adapter" => "sqlite", - # "database" => "path/to/dbfile" - # ) - # - # The exceptions AdapterNotSpecified, AdapterNotFound and ArgumentError - # may be returned on an error. - def self.establish_connection(spec = nil) - case spec - when nil - raise AdapterNotSpecified unless defined? RAILS_ENV - establish_connection(RAILS_ENV) - when ConnectionSpecification - @@defined_connections[name] = spec - when Symbol, String - if configuration = configurations[spec.to_s] - establish_connection(configuration) - else - raise AdapterNotSpecified, "#{spec} database is not configured" - end - else - spec = spec.symbolize_keys - unless spec.key?(:adapter) then raise AdapterNotSpecified, "database configuration does not specify adapter" end - adapter_method = "#{spec[:adapter]}_connection" - unless respond_to?(adapter_method) then raise AdapterNotFound, "database configuration specifies nonexistent #{spec[:adapter]} adapter" end - remove_connection - establish_connection(ConnectionSpecification.new(spec, adapter_method)) - end - end - - def self.active_connections #:nodoc: - if allow_concurrency - Thread.current['active_connections'] ||= {} - else - @@active_connections ||= {} - end - end - - # Locate the connection of the nearest super class. This can be an - # active or defined connections: if it is the latter, it will be - # opened and set as the active connection for the class it was defined - # for (not necessarily the current class). - def self.retrieve_connection #:nodoc: - klass = self - ar_super = ActiveRecord::Base.superclass - until klass == ar_super - if conn = active_connections[klass.name] - # Reconnect if the connection is inactive. - conn.reconnect! unless conn.active? - return conn - elsif conn = @@defined_connections[klass.name] - klass.connection = conn - return self.connection - end - klass = klass.superclass - end - raise ConnectionNotEstablished - end - - # Returns true if a connection that's accessible to this class have already been opened. - def self.connected? - klass = self - until klass == ActiveRecord::Base.superclass - if active_connections[klass.name] - return true - else - klass = klass.superclass - end - end - return false - end - - # Remove the connection for this class. This will close the active - # connection and the defined connection (if they exist). The result - # can be used as argument for establish_connection, for easy - # re-establishing of the connection. - def self.remove_connection(klass=self) - conn = @@defined_connections[klass.name] - @@defined_connections.delete(klass.name) - @@connection_cache[Thread.current.object_id].delete(klass.name) - active_connections.delete(klass.name) - @connection = nil - conn.config if conn - end - - # Set the connection for the class. - def self.connection=(spec) - if spec.kind_of?(ActiveRecord::ConnectionAdapters::AbstractAdapter) - active_connections[name] = spec - elsif spec.kind_of?(ConnectionSpecification) - self.connection = self.send(spec.adapter_method, spec.config) - elsif spec.nil? - raise ConnectionNotEstablished - else - establish_connection spec - end - end - end -end diff --git a/tracks/vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb b/tracks/vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb deleted file mode 100644 index c45454ea..00000000 --- a/tracks/vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb +++ /dev/null @@ -1,104 +0,0 @@ -module ActiveRecord - module ConnectionAdapters # :nodoc: - module DatabaseStatements - # Returns an array of record hashes with the column names as keys and - # column values as values. - def select_all(sql, name = nil) - end - - # Returns a record hash with the column names as keys and column values - # as values. - def select_one(sql, name = nil) - end - - # Returns a single value from a record - def select_value(sql, name = nil) - result = select_one(sql, name) - result.nil? ? nil : result.values.first - end - - # Returns an array of the values of the first column in a select: - # select_values("SELECT id FROM companies LIMIT 3") => [1,2,3] - def select_values(sql, name = nil) - result = select_all(sql, name) - result.map{ |v| v.values.first } - end - - # Executes the SQL statement in the context of this connection. - # This abstract method raises a NotImplementedError. - def execute(sql, name = nil) - raise NotImplementedError, "execute is an abstract method" - end - - # Returns the last auto-generated ID from the affected table. - def insert(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil) end - - # Executes the update statement and returns the number of rows affected. - def update(sql, name = nil) end - - # Executes the delete statement and returns the number of rows affected. - def delete(sql, name = nil) end - - # Wrap a block in a transaction. Returns result of block. - def transaction(start_db_transaction = true) - transaction_open = false - begin - if block_given? - if start_db_transaction - begin_db_transaction - transaction_open = true - end - yield - end - rescue Exception => database_transaction_rollback - if transaction_open - transaction_open = false - rollback_db_transaction - end - raise - end - ensure - commit_db_transaction if transaction_open - end - - # Begins the transaction (and turns off auto-committing). - def begin_db_transaction() end - - # Commits the transaction (and turns on auto-committing). - def commit_db_transaction() end - - # Rolls back the transaction (and turns on auto-committing). Must be - # done if the transaction block raises an exception or returns false. - def rollback_db_transaction() end - - # Alias for #add_limit_offset!. - def add_limit!(sql, options) - add_limit_offset!(sql, options) if options - end - - # Appends +LIMIT+ and +OFFSET+ options to a SQL statement. - # This method *modifies* the +sql+ parameter. - # ===== Examples - # add_limit_offset!('SELECT * FROM suppliers', {:limit => 10, :offset => 50}) - # generates - # SELECT * FROM suppliers LIMIT 10 OFFSET 50 - def add_limit_offset!(sql, options) - if limit = options[:limit] - sql << " LIMIT #{limit}" - if offset = options[:offset] - sql << " OFFSET #{offset}" - end - end - end - - def default_sequence_name(table, column) - nil - end - - # Set the sequence to the max value of the table's column. - def reset_sequence!(table, column, sequence = nil) - # Do nothing by default. Implement for PostgreSQL, Oracle, ... - end - end - end -end diff --git a/tracks/vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb b/tracks/vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb deleted file mode 100644 index acfd0f08..00000000 --- a/tracks/vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb +++ /dev/null @@ -1,51 +0,0 @@ -module ActiveRecord - module ConnectionAdapters # :nodoc: - module Quoting - # Quotes the column value to help prevent - # {SQL injection attacks}[http://en.wikipedia.org/wiki/SQL_injection]. - def quote(value, column = nil) - case value - when String - if column && column.type == :binary - "'#{quote_string(column.class.string_to_binary(value))}'" # ' (for ruby-mode) - elsif column && [:integer, :float].include?(column.type) - value.to_s - else - "'#{quote_string(value)}'" # ' (for ruby-mode) - end - when NilClass then "NULL" - when TrueClass then (column && column.type == :integer ? '1' : quoted_true) - when FalseClass then (column && column.type == :integer ? '0' : quoted_false) - when Float, Fixnum, Bignum then value.to_s - when Date then "'#{value.to_s}'" - when Time, DateTime then "'#{quoted_date(value)}'" - else "'#{quote_string(value.to_yaml)}'" - end - end - - # Quotes a string, escaping any ' (single quote) and \ (backslash) - # characters. - def quote_string(s) - s.gsub(/\\/, '\&\&').gsub(/'/, "''") # ' (for ruby-mode) - end - - # Returns a quoted form of the column name. This is highly adapter - # specific. - def quote_column_name(name) - name - end - - def quoted_true - "'t'" - end - - def quoted_false - "'f'" - end - - def quoted_date(value) - value.strftime("%Y-%m-%d %H:%M:%S") - end - end - end -end diff --git a/tracks/vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb b/tracks/vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb deleted file mode 100644 index df79f275..00000000 --- a/tracks/vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb +++ /dev/null @@ -1,258 +0,0 @@ -require 'parsedate' - -module ActiveRecord - module ConnectionAdapters #:nodoc: - # An abstract definition of a column in a table. - class Column - attr_reader :name, :default, :type, :limit, :null - attr_accessor :primary - - # Instantiates a new column in the table. - # - # +name+ is the column's name, as in supplier_id int(11). - # +default+ is the type-casted default value, such as sales_stage varchar(20) default 'new'. - # +sql_type+ is only used to extract the column's length, if necessary. For example, company_name varchar(60). - # +null+ determines if this column allows +NULL+ values. - def initialize(name, default, sql_type = nil, null = true) - @name, @type, @null = name, simplified_type(sql_type), null - # have to do this one separately because type_cast depends on #type - @default = type_cast(default) - @limit = extract_limit(sql_type) unless sql_type.nil? - @primary = nil - @text = [:string, :text].include? @type - @number = [:float, :integer].include? @type - end - - def text? - @text - end - - def number? - @number - end - - # Returns the Ruby class that corresponds to the abstract data type. - def klass - case type - when :integer then Fixnum - when :float then Float - when :datetime then Time - when :date then Date - when :timestamp then Time - when :time then Time - when :text, :string then String - when :binary then String - when :boolean then Object - end - end - - # Casts value (which is a String) to an appropriate instance. - def type_cast(value) - return nil if value.nil? - case type - when :string then value - when :text then value - when :integer then value.to_i rescue value ? 1 : 0 - when :float then value.to_f - when :datetime then self.class.string_to_time(value) - when :timestamp then self.class.string_to_time(value) - when :time then self.class.string_to_dummy_time(value) - when :date then self.class.string_to_date(value) - when :binary then self.class.binary_to_string(value) - when :boolean then self.class.value_to_boolean(value) - else value - end - end - - def type_cast_code(var_name) - case type - when :string then nil - when :text then nil - when :integer then "(#{var_name}.to_i rescue #{var_name} ? 1 : 0)" - when :float then "#{var_name}.to_f" - when :datetime then "#{self.class.name}.string_to_time(#{var_name})" - when :timestamp then "#{self.class.name}.string_to_time(#{var_name})" - when :time then "#{self.class.name}.string_to_dummy_time(#{var_name})" - when :date then "#{self.class.name}.string_to_date(#{var_name})" - when :binary then "#{self.class.name}.binary_to_string(#{var_name})" - when :boolean then "#{self.class.name}.value_to_boolean(#{var_name})" - else nil - end - end - - # Returns the human name of the column name. - # - # ===== Examples - # Column.new('sales_stage', ...).human_name #=> 'Sales stage' - def human_name - Base.human_attribute_name(@name) - end - - # Used to convert from Strings to BLOBs - def self.string_to_binary(value) - value - end - - # Used to convert from BLOBs to Strings - def self.binary_to_string(value) - value - end - - def self.string_to_date(string) - return string unless string.is_a?(String) - date_array = ParseDate.parsedate(string) - # treat 0000-00-00 as nil - Date.new(date_array[0], date_array[1], date_array[2]) rescue nil - end - - def self.string_to_time(string) - return string unless string.is_a?(String) - time_array = ParseDate.parsedate(string)[0..5] - # treat 0000-00-00 00:00:00 as nil - Time.send(Base.default_timezone, *time_array) rescue nil - end - - def self.string_to_dummy_time(string) - return string unless string.is_a?(String) - time_array = ParseDate.parsedate(string) - # pad the resulting array with dummy date information - time_array[0] = 2000; time_array[1] = 1; time_array[2] = 1; - Time.send(Base.default_timezone, *time_array) rescue nil - end - - # convert something to a boolean - def self.value_to_boolean(value) - return value if value==true || value==false - case value.to_s.downcase - when "true", "t", "1" then true - else false - end - end - - private - def extract_limit(sql_type) - $1.to_i if sql_type =~ /\((.*)\)/ - end - - def simplified_type(field_type) - case field_type - when /int/i - :integer - when /float|double|decimal|numeric/i - :float - when /datetime/i - :datetime - when /timestamp/i - :timestamp - when /time/i - :time - when /date/i - :date - when /clob/i, /text/i - :text - when /blob/i, /binary/i - :binary - when /char/i, /string/i - :string - when /boolean/i - :boolean - end - end - end - - class IndexDefinition < Struct.new(:table, :name, :unique, :columns) #:nodoc: - end - - class ColumnDefinition < Struct.new(:base, :name, :type, :limit, :default, :null) #:nodoc: - def to_sql - column_sql = "#{base.quote_column_name(name)} #{type_to_sql(type.to_sym, limit)}" - add_column_options!(column_sql, :null => null, :default => default) - column_sql - end - alias to_s :to_sql - - private - def type_to_sql(name, limit) - base.type_to_sql(name, limit) rescue name - end - - def add_column_options!(sql, options) - base.add_column_options!(sql, options.merge(:column => self)) - end - end - - # Represents a SQL table in an abstract way. - # Columns are stored as ColumnDefinition in the #columns attribute. - class TableDefinition - attr_accessor :columns - - def initialize(base) - @columns = [] - @base = base - end - - # Appends a primary key definition to the table definition. - # Can be called multiple times, but this is probably not a good idea. - def primary_key(name) - column(name, native[:primary_key]) - end - - # Returns a ColumnDefinition for the column with name +name+. - def [](name) - @columns.find {|column| column.name.to_s == name.to_s} - end - - # Instantiates a new column for the table. - # The +type+ parameter must be one of the following values: - # :primary_key, :string, :text, - # :integer, :float, :datetime, - # :timestamp, :time, :date, - # :binary, :boolean. - # - # Available options are (none of these exists by default): - # * :limit: - # Requests a maximum column length (:string, :text, - # :binary or :integer columns only) - # * :default: - # The column's default value. You cannot explicitely set the default - # value to +NULL+. Simply leave off this option if you want a +NULL+ - # default value. - # * :null: - # Allows or disallows +NULL+ values in the column. This option could - # have been named :null_allowed. - # - # This method returns self. - # - # ===== Examples - # # Assuming def is an instance of TableDefinition - # def.column(:granted, :boolean) - # #=> granted BOOLEAN - # - # def.column(:picture, :binary, :limit => 2.megabytes) - # #=> picture BLOB(2097152) - # - # def.column(:sales_stage, :string, :limit => 20, :default => 'new', :null => false) - # #=> sales_stage VARCHAR(20) DEFAULT 'new' NOT NULL - def column(name, type, options = {}) - column = self[name] || ColumnDefinition.new(@base, name, type) - column.limit = options[:limit] || native[type.to_sym][:limit] if options[:limit] or native[type.to_sym] - column.default = options[:default] - column.null = options[:null] - @columns << column unless @columns.include? column - self - end - - # Returns a String whose contents are the column definitions - # concatenated together. This string can then be pre and appended to - # to generate the final SQL to create the table. - def to_sql - @columns * ', ' - end - - private - def native - @base.native_database_types - end - end - end -end diff --git a/tracks/vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb b/tracks/vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb deleted file mode 100644 index 09d0a80f..00000000 --- a/tracks/vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb +++ /dev/null @@ -1,250 +0,0 @@ -module ActiveRecord - module ConnectionAdapters # :nodoc: - module SchemaStatements - # Returns a Hash of mappings from the abstract data types to the native - # database types. See TableDefinition#column for details on the recognized - # abstract data types. - def native_database_types - {} - end - - # def tables(name = nil) end - - # Returns an array of indexes for the given table. - # def indexes(table_name, name = nil) end - - # Returns an array of Column objects for the table specified by +table_name+. - # See the concrete implementation for details on the expected parameter values. - def columns(table_name, name = nil) end - - # Creates a new table - # There are two ways to work with #create_table. You can use the block - # form or the regular form, like this: - # - # === Block form - # # create_table() yields a TableDefinition instance - # create_table(:suppliers) do |t| - # t.column :name, :string, :limit => 60 - # # Other fields here - # end - # - # === Regular form - # create_table(:suppliers) - # add_column(:suppliers, :name, :string, {:limit => 60}) - # - # The +options+ hash can include the following keys: - # [:id] - # Set to true or false to add/not add a primary key column - # automatically. Defaults to true. - # [:primary_key] - # The name of the primary key, if one is to be added automatically. - # Defaults to +id+. - # [:options] - # Any extra options you want appended to the table definition. - # [:temporary] - # Make a temporary table. - # [:force] - # Set to true or false to drop the table before creating it. - # Defaults to false. - # - # ===== Examples - # ====== Add a backend specific option to the generated SQL (MySQL) - # create_table(:suppliers, :options => 'ENGINE=InnoDB DEFAULT CHARSET=utf8') - # generates: - # CREATE TABLE suppliers ( - # id int(11) DEFAULT NULL auto_increment PRIMARY KEY - # ) ENGINE=InnoDB DEFAULT CHARSET=utf8 - # - # ====== Rename the primary key column - # create_table(:objects, :primary_key => 'guid') do |t| - # t.column :name, :string, :limit => 80 - # end - # generates: - # CREATE TABLE objects ( - # guid int(11) DEFAULT NULL auto_increment PRIMARY KEY, - # name varchar(80) - # ) - # - # ====== Do not add a primary key column - # create_table(:categories_suppliers, :id => false) do |t| - # t.column :category_id, :integer - # t.column :supplier_id, :integer - # end - # generates: - # CREATE TABLE categories_suppliers_join ( - # category_id int, - # supplier_id int - # ) - # - # See also TableDefinition#column for details on how to create columns. - def create_table(name, options = {}) - table_definition = TableDefinition.new(self) - table_definition.primary_key(options[:primary_key] || "id") unless options[:id] == false - - yield table_definition - - if options[:force] - drop_table(name) rescue nil - end - - create_sql = "CREATE#{' TEMPORARY' if options[:temporary]} TABLE " - create_sql << "#{name} (" - create_sql << table_definition.to_sql - create_sql << ") #{options[:options]}" - execute create_sql - end - - # Renames a table. - # ===== Example - # rename_table('octopuses', 'octopi') - def rename_table(name, new_name) - raise NotImplementedError, "rename_table is not implemented" - end - - # Drops a table from the database. - def drop_table(name) - execute "DROP TABLE #{name}" - end - - # Adds a new column to the named table. - # See TableDefinition#column for details of the options you can use. - def add_column(table_name, column_name, type, options = {}) - add_column_sql = "ALTER TABLE #{table_name} ADD #{column_name} #{type_to_sql(type, options[:limit])}" - add_column_options!(add_column_sql, options) - execute(add_column_sql) - end - - # Removes the column from the table definition. - # ===== Examples - # remove_column(:suppliers, :qualification) - def remove_column(table_name, column_name) - execute "ALTER TABLE #{table_name} DROP #{column_name}" - end - - # Changes the column's definition according to the new options. - # See TableDefinition#column for details of the options you can use. - # ===== Examples - # change_column(:suppliers, :name, :string, :limit => 80) - # change_column(:accounts, :description, :text) - def change_column(table_name, column_name, type, options = {}) - raise NotImplementedError, "change_column is not implemented" - end - - # Sets a new default value for a column. If you want to set the default - # value to +NULL+, you are out of luck. You need to - # DatabaseStatements#execute the apppropriate SQL statement yourself. - # ===== Examples - # change_column_default(:suppliers, :qualification, 'new') - # change_column_default(:accounts, :authorized, 1) - def change_column_default(table_name, column_name, default) - raise NotImplementedError, "change_column_default is not implemented" - end - - # Renames a column. - # ===== Example - # rename_column(:suppliers, :description, :name) - def rename_column(table_name, column_name, new_column_name) - raise NotImplementedError, "rename_column is not implemented" - end - - # Adds a new index to the table. +column_name+ can be a single Symbol, or - # an Array of Symbols. - # - # The index will be named after the table and the first column names, - # unless you pass +:name+ as an option. - # - # ===== Examples - # ====== Creating a simple index - # add_index(:suppliers, :name) - # generates - # CREATE INDEX suppliers_name_index ON suppliers(name) - # ====== Creating a unique index - # add_index(:accounts, [:branch_id, :party_id], :unique => true) - # generates - # CREATE UNIQUE INDEX accounts_branch_id_index ON accounts(branch_id, party_id) - # ====== Creating a named index - # add_index(:accounts, [:branch_id, :party_id], :unique => true, :name => 'by_branch_party') - # generates - # CREATE UNIQUE INDEX by_branch_party ON accounts(branch_id, party_id) - def add_index(table_name, column_name, options = {}) - index_name = "#{table_name}_#{Array(column_name).first}_index" - - if Hash === options # legacy support, since this param was a string - index_type = options[:unique] ? "UNIQUE" : "" - index_name = options[:name] || index_name - else - index_type = options - end - - execute "CREATE #{index_type} INDEX #{index_name} ON #{table_name} (#{Array(column_name).join(", ")})" - end - - # Remove the given index from the table. - # - # Remove the suppliers_name_index in the suppliers table (legacy support, use the second or third forms). - # remove_index :suppliers, :name - # Remove the index named accounts_branch_id in the accounts table. - # remove_index :accounts, :column => :branch_id - # Remove the index named by_branch_party in the accounts table. - # remove_index :accounts, :name => :by_branch_party - - def remove_index(table_name, options = {}) - execute "DROP INDEX #{index_name(table_name, options)} ON #{table_name}" - end - - def index_name(table_name, options) #:nodoc: - if Hash === options # legacy support - if options[:column] - "#{table_name}_#{options[:column]}_index" - elsif options[:name] - options[:name] - else - raise ArgumentError, "You must specify the index name" - end - else - "#{table_name}_#{options}_index" - end - end - - # Returns a string of CREATE TABLE SQL statement(s) for recreating the - # entire structure of the database. - def structure_dump - end - - # Should not be called normally, but this operation is non-destructive. - # The migrations module handles this automatically. - def initialize_schema_information - begin - execute "CREATE TABLE #{ActiveRecord::Migrator.schema_info_table_name} (version #{type_to_sql(:integer)})" - execute "INSERT INTO #{ActiveRecord::Migrator.schema_info_table_name} (version) VALUES(0)" - rescue ActiveRecord::StatementInvalid - # Schema has been intialized - end - end - - def dump_schema_information #:nodoc: - begin - if (current_schema = ActiveRecord::Migrator.current_version) > 0 - return "INSERT INTO #{ActiveRecord::Migrator.schema_info_table_name} (version) VALUES (#{current_schema})" - end - rescue ActiveRecord::StatementInvalid - # No Schema Info - end - end - - - def type_to_sql(type, limit = nil) #:nodoc: - native = native_database_types[type] - limit ||= native[:limit] - column_type_sql = native[:name] - column_type_sql << "(#{limit})" if limit - column_type_sql - end - - def add_column_options!(sql, options) #:nodoc: - sql << " DEFAULT #{quote(options[:default], options[:column])}" unless options[:default].nil? - sql << " NOT NULL" if options[:null] == false - end - end - end -end diff --git a/tracks/vendor/rails/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb b/tracks/vendor/rails/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb deleted file mode 100644 index f120a50f..00000000 --- a/tracks/vendor/rails/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb +++ /dev/null @@ -1,121 +0,0 @@ -require 'benchmark' -require 'date' - -require 'active_record/connection_adapters/abstract/schema_definitions' -require 'active_record/connection_adapters/abstract/schema_statements' -require 'active_record/connection_adapters/abstract/database_statements' -require 'active_record/connection_adapters/abstract/quoting' -require 'active_record/connection_adapters/abstract/connection_specification' - -module ActiveRecord - module ConnectionAdapters # :nodoc: - # All the concrete database adapters follow the interface laid down in this class. - # You can use this interface directly by borrowing the database connection from the Base with - # Base.connection. - # - # Most of the methods in the adapter are useful during migrations. Most - # notably, SchemaStatements#create_table, SchemaStatements#drop_table, - # SchemaStatements#add_index, SchemaStatements#remove_index, - # SchemaStatements#add_column, SchemaStatements#change_column and - # SchemaStatements#remove_column are very useful. - class AbstractAdapter - include Quoting, DatabaseStatements, SchemaStatements - @@row_even = true - - def initialize(connection, logger = nil) #:nodoc: - @connection, @logger = connection, logger - @runtime = 0 - end - - # Returns the human-readable name of the adapter. Use mixed case - one - # can always use downcase if needed. - def adapter_name - 'Abstract' - end - - # Does this adapter support migrations? Backend specific, as the - # abstract adapter always returns +false+. - def supports_migrations? - false - end - - # Should primary key values be selected from their corresponding - # sequence before the insert statement? If true, next_sequence_value - # is called before each insert to set the record's primary key. - # This is false for all adapters but Firebird. - def prefetch_primary_key?(table_name = nil) - false - end - - def reset_runtime #:nodoc: - rt, @runtime = @runtime, 0 - rt - end - - - # CONNECTION MANAGEMENT ==================================== - - # Is this connection active and ready to perform queries? - def active? - true - end - - # Close this connection and open a new one in its place. - def reconnect! - end - - - protected - def log(sql, name) - if block_given? - if @logger and @logger.level <= Logger::INFO - result = nil - seconds = Benchmark.realtime { result = yield } - @runtime += seconds - log_info(sql, name, seconds) - result - else - yield - end - else - log_info(sql, name, 0) - nil - end - rescue Exception => e - # Log message and raise exception. - message = "#{e.class.name}: #{e.message}: #{sql}" - log_info(message, name, 0) - raise ActiveRecord::StatementInvalid, message - end - - def log_info(sql, name, runtime) - return unless @logger - - @logger.debug( - format_log_entry( - "#{name.nil? ? "SQL" : name} (#{sprintf("%f", runtime)})", - sql.gsub(/ +/, " ") - ) - ) - end - - def format_log_entry(message, dump = nil) - if ActiveRecord::Base.colorize_logging - if @@row_even - @@row_even = false - message_color, dump_color = "4;36;1", "0;1" - else - @@row_even = true - message_color, dump_color = "4;35;1", "0" - end - - log_entry = " \e[#{message_color}m#{message}\e[0m " - log_entry << "\e[#{dump_color}m%#{String === dump ? 's' : 'p'}\e[0m" % dump if dump - log_entry - else - "%s %s" % [message, dump] - end - end - end - end -end diff --git a/tracks/vendor/rails/activerecord/lib/active_record/connection_adapters/db2_adapter.rb b/tracks/vendor/rails/activerecord/lib/active_record/connection_adapters/db2_adapter.rb deleted file mode 100644 index 232971e4..00000000 --- a/tracks/vendor/rails/activerecord/lib/active_record/connection_adapters/db2_adapter.rb +++ /dev/null @@ -1,192 +0,0 @@ -# Author/Maintainer: Maik Schmidt - -require 'active_record/connection_adapters/abstract_adapter' - -begin - require 'db2/db2cli' unless self.class.const_defined?(:DB2CLI) - require 'active_record/vendor/db2' - - module ActiveRecord - class Base - # Establishes a connection to the database that's used by - # all Active Record objects - def self.db2_connection(config) # :nodoc: - config = config.symbolize_keys - usr = config[:username] - pwd = config[:password] - - if config.has_key?(:database) - database = config[:database] - else - raise ArgumentError, "No database specified. Missing argument: database." - end - - connection = DB2::Connection.new(DB2::Environment.new) - connection.connect(database, usr, pwd) - ConnectionAdapters::DB2Adapter.new(connection) - end - end - - module ConnectionAdapters - # The DB2 adapter works with the C-based CLI driver (http://rubyforge.org/projects/ruby-dbi/) - # - # Options: - # - # * :username -- Defaults to nothing - # * :password -- Defaults to nothing - # * :database -- The name of the database. No default, must be provided. - class DB2Adapter < AbstractAdapter - def select_all(sql, name = nil) - select(sql, name) - end - - def select_one(sql, name = nil) - select(sql, name).first - end - - def insert(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil) - execute(sql, name = nil) - id_value || last_insert_id - end - - def execute(sql, name = nil) - rows_affected = 0 - - log(sql, name) do - stmt = DB2::Statement.new(@connection) - stmt.exec_direct(sql) - rows_affected = stmt.row_count - stmt.free - end - - rows_affected - end - - alias_method :update, :execute - alias_method :delete, :execute - - def begin_db_transaction - @connection.set_auto_commit_off - end - - def commit_db_transaction - @connection.commit - @connection.set_auto_commit_on - end - - def rollback_db_transaction - @connection.rollback - @connection.set_auto_commit_on - end - - def quote_column_name(column_name) - column_name - end - - def adapter_name() - 'DB2' - end - - def quote_string(string) - string.gsub(/'/, "''") # ' (for ruby-mode) - end - - def add_limit_offset!(sql, options) - if options[:limit] and !options[:limit].nil? - # "FETCH FIRST 0 ROWS ONLY" is not allowed, so we have - # to use a cheap trick. - if options[:limit] == 0 - if sql =~ /WHERE/i - sql.sub!(/WHERE/i, 'WHERE 1 = 2 AND ') - elsif - sql =~ /ORDER\s+BY/i - sql.sub!(/ORDER\s+BY/i, 'WHERE 1 = 2 ORDER BY') - else - sql << 'WHERE 1 = 2' - end - else - sql << " FETCH FIRST #{options[:limit]} ROWS ONLY" - end - end - if options[:offset] and !options[:offset].nil? - raise ArgumentError, ':offset option is not yet supported!' - end - end - - def tables(name = nil) - stmt = DB2::Statement.new(@connection) - result = [] - stmt.tables.each { |t| result << t[2].downcase } - stmt.free - result - end - - def columns(table_name, name = nil) - stmt = DB2::Statement.new(@connection) - result = [] - - stmt.columns(table_name.upcase).each do |c| - c_name = c[3].downcase - c_default = c[12] == 'NULL' ? nil : c[12] - c_type = c[5].downcase - c_type += "(#{c[6]})" if !c[6].nil? && c[6] != '' - result << Column.new(c_name, c_default, c_type) - end - - stmt.free - result - end - - def native_database_types - { - :primary_key => "int generated by default as identity primary key", - :string => { :name => "varchar", :limit => 255 }, - :text => { :name => "clob", :limit => 32768 }, - :integer => { :name => "int" }, - :float => { :name => "float" }, - :datetime => { :name => "timestamp" }, - :timestamp => { :name => "timestamp" }, - :time => { :name => "time" }, - :date => { :name => "date" }, - :binary => { :name => "blob", :limit => 32768 }, - :boolean => { :name => "decimal", :limit => 1 } - } - end - - def quoted_true - '1' - end - - def quoted_false - '0' - end - - private - - def last_insert_id - row = select_one(<<-GETID.strip) - with temp(id) as (values (identity_val_local())) select * from temp - GETID - row['id'].to_i - end - - def select(sql, name = nil) - stmt = nil - log(sql, name) do - stmt = DB2::Statement.new(@connection) - stmt.exec_direct("#{sql.gsub(/=\s*null/i, 'IS NULL')} with ur") - end - - rows = [] - while row = stmt.fetch_as_hash - rows << row - end - stmt.free - rows - end - end - end - end -rescue LoadError - # DB2 driver is unavailable. -end diff --git a/tracks/vendor/rails/activerecord/lib/active_record/connection_adapters/firebird_adapter.rb b/tracks/vendor/rails/activerecord/lib/active_record/connection_adapters/firebird_adapter.rb deleted file mode 100644 index 9bf047f0..00000000 --- a/tracks/vendor/rails/activerecord/lib/active_record/connection_adapters/firebird_adapter.rb +++ /dev/null @@ -1,414 +0,0 @@ -# Author: Ken Kunz - -require 'active_record/connection_adapters/abstract_adapter' - -module FireRuby # :nodoc: all - class Database - def self.new_from_params(database, host, port, service) - db_string = "" - if host - db_string << host - db_string << "/#{service || port}" if service || port - db_string << ":" - end - db_string << database - new(db_string) - end - end -end - -module ActiveRecord - class << Base - def firebird_connection(config) # :nodoc: - require_library_or_gem 'fireruby' - unless defined? FireRuby::SQLType - raise AdapterNotFound, - 'The Firebird adapter requires FireRuby version 0.4.0 or greater; you appear ' << - 'to be running an older version -- please update FireRuby (gem install fireruby).' - end - config = config.symbolize_keys - unless config.has_key?(:database) - raise ArgumentError, "No database specified. Missing argument: database." - end - options = config[:charset] ? { CHARACTER_SET => config[:charset] } : {} - connection_params = [config[:username], config[:password], options] - db = FireRuby::Database.new_from_params(*config.values_at(:database, :host, :port, :service)) - connection = db.connect(*connection_params) - ConnectionAdapters::FirebirdAdapter.new(connection, logger, connection_params) - end - end - - module ConnectionAdapters - class FirebirdColumn < Column # :nodoc: - VARCHAR_MAX_LENGTH = 32_765 - BLOB_MAX_LENGTH = 32_767 - - def initialize(name, domain, type, sub_type, length, precision, scale, default_source, null_flag) - @firebird_type = FireRuby::SQLType.to_base_type(type, sub_type).to_s - super(name.downcase, nil, @firebird_type, !null_flag) - @default = parse_default(default_source) if default_source - @limit = type == 'BLOB' ? BLOB_MAX_LENGTH : length - @domain, @sub_type, @precision, @scale = domain, sub_type, precision, scale - end - - def type - if @domain =~ /BOOLEAN/ - :boolean - elsif @type == :binary and @sub_type == 1 - :text - else - @type - end - end - - # Submits a _CAST_ query to the database, casting the default value to the specified SQL type. - # This enables Firebird to provide an actual value when context variables are used as column - # defaults (such as CURRENT_TIMESTAMP). - def default - if @default - sql = "SELECT CAST(#{@default} AS #{column_def}) FROM RDB$DATABASE" - connection = ActiveRecord::Base.active_connections.values.detect { |conn| conn && conn.adapter_name == 'Firebird' } - if connection - type_cast connection.execute(sql).to_a.first['CAST'] - else - raise ConnectionNotEstablished, "No Firebird connections established." - end - end - end - - def type_cast(value) - if type == :boolean - value == true or value == ActiveRecord::ConnectionAdapters::FirebirdAdapter.boolean_domain[:true] - else - super - end - end - - private - def parse_default(default_source) - default_source =~ /^\s*DEFAULT\s+(.*)\s*$/i - return $1 unless $1.upcase == "NULL" - end - - def column_def - case @firebird_type - when 'BLOB' then "VARCHAR(#{VARCHAR_MAX_LENGTH})" - when 'CHAR', 'VARCHAR' then "#{@firebird_type}(#{@limit})" - when 'NUMERIC', 'DECIMAL' then "#{@firebird_type}(#{@precision},#{@scale.abs})" - when 'DOUBLE' then "DOUBLE PRECISION" - else @firebird_type - end - end - - def simplified_type(field_type) - if field_type == 'TIMESTAMP' - :datetime - else - super - end - end - end - - # The Firebird adapter relies on the FireRuby[http://rubyforge.org/projects/fireruby/] - # extension, version 0.4.0 or later (available as a gem or from - # RubyForge[http://rubyforge.org/projects/fireruby/]). FireRuby works with - # Firebird 1.5.x on Linux, OS X and Win32 platforms. - # - # == Usage Notes - # - # === Sequence (Generator) Names - # The Firebird adapter supports the same approach adopted for the Oracle - # adapter. See ActiveRecord::Base#set_sequence_name for more details. - # - # Note that in general there is no need to create a BEFORE INSERT - # trigger corresponding to a Firebird sequence generator when using - # ActiveRecord. In other words, you don't have to try to make Firebird - # simulate an AUTO_INCREMENT or +IDENTITY+ column. When saving a - # new record, ActiveRecord pre-fetches the next sequence value for the table - # and explicitly includes it in the +INSERT+ statement. (Pre-fetching the - # next primary key value is the only reliable method for the Firebird - # adapter to report back the +id+ after a successful insert.) - # - # === BOOLEAN Domain - # Firebird 1.5 does not provide a native +BOOLEAN+ type. But you can easily - # define a +BOOLEAN+ _domain_ for this purpose, e.g.: - # - # CREATE DOMAIN D_BOOLEAN AS SMALLINT CHECK (VALUE IN (0, 1)); - # - # When the Firebird adapter encounters a column that is based on a domain - # that includes "BOOLEAN" in the domain name, it will attempt to treat - # the column as a +BOOLEAN+. - # - # By default, the Firebird adapter will assume that the BOOLEAN domain is - # defined as above. This can be modified if needed. For example, if you - # have a legacy schema with the following +BOOLEAN+ domain defined: - # - # CREATE DOMAIN BOOLEAN AS CHAR(1) CHECK (VALUE IN ('T', 'F')); - # - # ...you can add the following line to your environment.rb file: - # - # ActiveRecord::ConnectionAdapters::FirebirdAdapter.boolean_domain = { :true => 'T', :false => 'F' } - # - # === BLOB Elements - # The Firebird adapter currently provides only limited support for +BLOB+ - # columns. You cannot currently retrieve or insert a +BLOB+ as an IO stream. - # When selecting a +BLOB+, the entire element is converted into a String. - # When inserting or updating a +BLOB+, the entire value is included in-line - # in the SQL statement, limiting you to values <= 32KB in size. - # - # === Column Name Case Semantics - # Firebird and ActiveRecord have somewhat conflicting case semantics for - # column names. - # - # [*Firebird*] - # The standard practice is to use unquoted column names, which can be - # thought of as case-insensitive. (In fact, Firebird converts them to - # uppercase.) Quoted column names (not typically used) are case-sensitive. - # [*ActiveRecord*] - # Attribute accessors corresponding to column names are case-sensitive. - # The defaults for primary key and inheritance columns are lowercase, and - # in general, people use lowercase attribute names. - # - # In order to map between the differing semantics in a way that conforms - # to common usage for both Firebird and ActiveRecord, uppercase column names - # in Firebird are converted to lowercase attribute names in ActiveRecord, - # and vice-versa. Mixed-case column names retain their case in both - # directions. Lowercase (quoted) Firebird column names are not supported. - # This is similar to the solutions adopted by other adapters. - # - # In general, the best approach is to use unqouted (case-insensitive) column - # names in your Firebird DDL (or if you must quote, use uppercase column - # names). These will correspond to lowercase attributes in ActiveRecord. - # - # For example, a Firebird table based on the following DDL: - # - # CREATE TABLE products ( - # id BIGINT NOT NULL PRIMARY KEY, - # "TYPE" VARCHAR(50), - # name VARCHAR(255) ); - # - # ...will correspond to an ActiveRecord model class called +Product+ with - # the following attributes: +id+, +type+, +name+. - # - # ==== Quoting "TYPE" and other Firebird reserved words: - # In ActiveRecord, the default inheritance column name is +type+. The word - # _type_ is a Firebird reserved word, so it must be quoted in any Firebird - # SQL statements. Because of the case mapping described above, you should - # always reference this column using quoted-uppercase syntax - # ("TYPE") within Firebird DDL or other SQL statements (as in the - # example above). This holds true for any other Firebird reserved words used - # as column names as well. - # - # === Migrations - # The Firebird adapter does not currently support Migrations. I hope to - # add this feature in the near future. - # - # == Connection Options - # The following options are supported by the Firebird adapter. None of the - # options have default values. - # - # :database:: - # Required option. Specifies one of: (i) a Firebird database alias; - # (ii) the full path of a database file; _or_ (iii) a full Firebird - # connection string. Do not specify :host, :service - # or :port as separate options when using a full connection - # string. - # :host:: - # Set to "remote.host.name" for remote database connections. - # May be omitted for local connections if a full database path is - # specified for :database. Some platforms require a value of - # "localhost" for local connections when using a Firebird - # database _alias_. - # :service:: - # Specifies a service name for the connection. Only used if :host - # is provided. Required when connecting to a non-standard service. - # :port:: - # Specifies the connection port. Only used if :host is provided - # and :service is not. Required when connecting to a non-standard - # port and :service is not defined. - # :username:: - # Specifies the database user. May be omitted or set to +nil+ (together - # with :password) to use the underlying operating system user - # credentials on supported platforms. - # :password:: - # Specifies the database password. Must be provided if :username - # is explicitly specified; should be omitted if OS user credentials are - # are being used. - # :charset:: - # Specifies the character set to be used by the connection. Refer to - # Firebird documentation for valid options. - class FirebirdAdapter < AbstractAdapter - @@boolean_domain = { :true => 1, :false => 0 } - cattr_accessor :boolean_domain - - def initialize(connection, logger, connection_params=nil) - super(connection, logger) - @connection_params = connection_params - end - - def adapter_name # :nodoc: - 'Firebird' - end - - # Returns true for Firebird adapter (since Firebird requires primary key - # values to be pre-fetched before insert). See also #next_sequence_value. - def prefetch_primary_key?(table_name = nil) - true - end - - def default_sequence_name(table_name, primary_key) # :nodoc: - "#{table_name}_seq" - end - - - # QUOTING ================================================== - - def quote(value, column = nil) # :nodoc: - if [Time, DateTime].include?(value.class) - "CAST('#{value.strftime("%Y-%m-%d %H:%M:%S")}' AS TIMESTAMP)" - else - super - end - end - - def quote_string(string) # :nodoc: - string.gsub(/'/, "''") - end - - def quote_column_name(column_name) # :nodoc: - %Q("#{ar_to_fb_case(column_name)}") - end - - def quoted_true # :nodoc: - quote(boolean_domain[:true]) - end - - def quoted_false # :nodoc: - quote(boolean_domain[:false]) - end - - - # CONNECTION MANAGEMENT ==================================== - - def active? - not @connection.closed? - end - - def reconnect! - @connection.close - @connection = @connection.database.connect(*@connection_params) - end - - - # DATABASE STATEMENTS ====================================== - - def select_all(sql, name = nil) # :nodoc: - select(sql, name) - end - - def select_one(sql, name = nil) # :nodoc: - result = select(sql, name) - result.nil? ? nil : result.first - end - - def execute(sql, name = nil, &block) # :nodoc: - log(sql, name) do - if @transaction - @connection.execute(sql, @transaction, &block) - else - @connection.execute_immediate(sql, &block) - end - end - end - - def insert(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil) # :nodoc: - execute(sql, name) - id_value - end - - alias_method :update, :execute - alias_method :delete, :execute - - def begin_db_transaction() # :nodoc: - @transaction = @connection.start_transaction - end - - def commit_db_transaction() # :nodoc: - @transaction.commit - ensure - @transaction = nil - end - - def rollback_db_transaction() # :nodoc: - @transaction.rollback - ensure - @transaction = nil - end - - def add_limit_offset!(sql, options) # :nodoc: - if options[:limit] - limit_string = "FIRST #{options[:limit]}" - limit_string << " SKIP #{options[:offset]}" if options[:offset] - sql.sub!(/\A(\s*SELECT\s)/i, '\&' + limit_string + ' ') - end - end - - # Returns the next sequence value from a sequence generator. Not generally - # called directly; used by ActiveRecord to get the next primary key value - # when inserting a new database record (see #prefetch_primary_key?). - def next_sequence_value(sequence_name) - FireRuby::Generator.new(sequence_name, @connection).next(1) - end - - - # SCHEMA STATEMENTS ======================================== - - def columns(table_name, name = nil) # :nodoc: - sql = <<-END_SQL - SELECT r.rdb$field_name, r.rdb$field_source, f.rdb$field_type, f.rdb$field_sub_type, - f.rdb$field_length, f.rdb$field_precision, f.rdb$field_scale, - COALESCE(r.rdb$default_source, f.rdb$default_source) rdb$default_source, - COALESCE(r.rdb$null_flag, f.rdb$null_flag) rdb$null_flag - FROM rdb$relation_fields r - JOIN rdb$fields f ON r.rdb$field_source = f.rdb$field_name - WHERE r.rdb$relation_name = '#{table_name.to_s.upcase}' - ORDER BY r.rdb$field_position - END_SQL - execute(sql, name).collect do |field| - field_values = field.values.collect do |value| - case value - when String then value.rstrip - when FireRuby::Blob then value.to_s - else value - end - end - FirebirdColumn.new(*field_values) - end - end - - private - def select(sql, name = nil) - execute(sql, name).collect do |row| - hashed_row = {} - row.each do |column, value| - value = value.to_s if FireRuby::Blob === value - hashed_row[fb_to_ar_case(column)] = value - end - hashed_row - end - end - - # Maps uppercase Firebird column names to lowercase for ActiveRecord; - # mixed-case columns retain their original case. - def fb_to_ar_case(column_name) - column_name =~ /[[:lower:]]/ ? column_name : column_name.downcase - end - - # Maps lowercase ActiveRecord column names to uppercase for Fierbird; - # mixed-case columns retain their original case. - def ar_to_fb_case(column_name) - column_name =~ /[[:upper:]]/ ? column_name : column_name.upcase - end - end - end -end diff --git a/tracks/vendor/rails/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb b/tracks/vendor/rails/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb deleted file mode 100644 index 4cc08c01..00000000 --- a/tracks/vendor/rails/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb +++ /dev/null @@ -1,335 +0,0 @@ -require 'active_record/connection_adapters/abstract_adapter' - -module ActiveRecord - class Base - # Establishes a connection to the database that's used by all Active Record objects. - def self.mysql_connection(config) # :nodoc: - # Only include the MySQL driver if one hasn't already been loaded - unless defined? Mysql - begin - require_library_or_gem 'mysql' - rescue LoadError => cannot_require_mysql - # Only use the supplied backup Ruby/MySQL driver if no driver is already in place - begin - require 'active_record/vendor/mysql' - rescue LoadError - raise cannot_require_mysql - end - end - end - - - config = config.symbolize_keys - host = config[:host] - port = config[:port] - socket = config[:socket] - username = config[:username] ? config[:username].to_s : 'root' - password = config[:password].to_s - - if config.has_key?(:database) - database = config[:database] - else - raise ArgumentError, "No database specified. Missing argument: database." - end - - mysql = Mysql.init - mysql.ssl_set(config[:sslkey], config[:sslcert], config[:sslca], config[:sslcapath], config[:sslcipher]) if config[:sslkey] - ConnectionAdapters::MysqlAdapter.new(mysql, logger, [host, username, password, database, port, socket], config) - end - end - - module ConnectionAdapters - class MysqlColumn < Column #:nodoc: - private - def simplified_type(field_type) - return :boolean if MysqlAdapter.emulate_booleans && field_type.downcase == "tinyint(1)" - super - end - end - - # The MySQL adapter will work with both Ruby/MySQL, which is a Ruby-based MySQL adapter that comes bundled with Active Record, and with - # the faster C-based MySQL/Ruby adapter (available both as a gem and from http://www.tmtm.org/en/mysql/ruby/). - # - # Options: - # - # * :host -- Defaults to localhost - # * :port -- Defaults to 3306 - # * :socket -- Defaults to /tmp/mysql.sock - # * :username -- Defaults to root - # * :password -- Defaults to nothing - # * :database -- The name of the database. No default, must be provided. - # * :sslkey -- Necessary to use MySQL with an SSL connection - # * :sslcert -- Necessary to use MySQL with an SSL connection - # * :sslcapath -- Necessary to use MySQL with an SSL connection - # * :sslcipher -- Necessary to use MySQL with an SSL connection - # - # By default, the MysqlAdapter will consider all columns of type tinyint(1) - # as boolean. If you wish to disable this emulation (which was the default - # behavior in versions 0.13.1 and earlier) you can add the following line - # to your environment.rb file: - # - # ActiveRecord::ConnectionAdapters::MysqlAdapter.emulate_booleans = false - class MysqlAdapter < AbstractAdapter - @@emulate_booleans = true - cattr_accessor :emulate_booleans - - LOST_CONNECTION_ERROR_MESSAGES = [ - "Server shutdown in progress", - "Broken pipe", - "Lost connection to MySQL server during query", - "MySQL server has gone away" - ] - - def initialize(connection, logger, connection_options, config) - super(connection, logger) - @connection_options, @config = connection_options, config - @null_values_in_each_hash = Mysql.const_defined?(:VERSION) - connect - end - - def adapter_name #:nodoc: - 'MySQL' - end - - def supports_migrations? #:nodoc: - true - end - - def native_database_types #:nodoc - { - :primary_key => "int(11) DEFAULT NULL auto_increment PRIMARY KEY", - :string => { :name => "varchar", :limit => 255 }, - :text => { :name => "text" }, - :integer => { :name => "int", :limit => 11 }, - :float => { :name => "float" }, - :datetime => { :name => "datetime" }, - :timestamp => { :name => "datetime" }, - :time => { :name => "time" }, - :date => { :name => "date" }, - :binary => { :name => "blob" }, - :boolean => { :name => "tinyint", :limit => 1 } - } - end - - - # QUOTING ================================================== - - def quote(value, column = nil) - if value.kind_of?(String) && column && column.type == :binary - s = column.class.string_to_binary(value).unpack("H*")[0] - "x'#{s}'" - else - super - end - end - - def quote_column_name(name) #:nodoc: - "`#{name}`" - end - - def quote_string(string) #:nodoc: - @connection.quote(string) - end - - def quoted_true - "1" - end - - def quoted_false - "0" - end - - - # CONNECTION MANAGEMENT ==================================== - - def active? - if @connection.respond_to?(:stat) - @connection.stat - else - @connection.query 'select 1' - end - - # mysql-ruby doesn't raise an exception when stat fails. - if @connection.respond_to?(:errno) - @connection.errno.zero? - else - true - end - rescue Mysql::Error - false - end - - def reconnect! - @connection.close rescue nil - connect - end - - - # DATABASE STATEMENTS ====================================== - - def select_all(sql, name = nil) #:nodoc: - select(sql, name) - end - - def select_one(sql, name = nil) #:nodoc: - result = select(sql, name) - result.nil? ? nil : result.first - end - - def execute(sql, name = nil, retries = 2) #:nodoc: - log(sql, name) { @connection.query(sql) } - rescue ActiveRecord::StatementInvalid => exception - if exception.message.split(":").first =~ /Packets out of order/ - raise ActiveRecord::StatementInvalid, "'Packets out of order' error was received from the database. Please update your mysql bindings (gem install mysql) and read http://dev.mysql.com/doc/mysql/en/password-hashing.html for more information. If you're on Windows, use the Instant Rails installer to get the updated mysql bindings." - else - raise - end - end - - def insert(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil) #:nodoc: - execute(sql, name = nil) - id_value || @connection.insert_id - end - - def update(sql, name = nil) #:nodoc: - execute(sql, name) - @connection.affected_rows - end - - alias_method :delete, :update #:nodoc: - - - def begin_db_transaction #:nodoc: - execute "BEGIN" - rescue Exception - # Transactions aren't supported - end - - def commit_db_transaction #:nodoc: - execute "COMMIT" - rescue Exception - # Transactions aren't supported - end - - def rollback_db_transaction #:nodoc: - execute "ROLLBACK" - rescue Exception - # Transactions aren't supported - end - - - def add_limit_offset!(sql, options) #:nodoc - if limit = options[:limit] - unless offset = options[:offset] - sql << " LIMIT #{limit}" - else - sql << " LIMIT #{offset}, #{limit}" - end - end - end - - - # SCHEMA STATEMENTS ======================================== - - def structure_dump #:nodoc: - select_all("SHOW TABLES").inject("") do |structure, table| - structure += select_one("SHOW CREATE TABLE #{table.to_a.first.last}")["Create Table"] + ";\n\n" - end - end - - def recreate_database(name) #:nodoc: - drop_database(name) - create_database(name) - end - - def create_database(name) #:nodoc: - execute "CREATE DATABASE #{name}" - end - - def drop_database(name) #:nodoc: - execute "DROP DATABASE IF EXISTS #{name}" - end - - - def tables(name = nil) #:nodoc: - tables = [] - execute("SHOW TABLES", name).each { |field| tables << field[0] } - tables - end - - def indexes(table_name, name = nil)#:nodoc: - indexes = [] - current_index = nil - execute("SHOW KEYS FROM #{table_name}", name).each do |row| - if current_index != row[2] - next if row[2] == "PRIMARY" # skip the primary key - current_index = row[2] - indexes << IndexDefinition.new(row[0], row[2], row[1] == "0", []) - end - - indexes.last.columns << row[4] - end - indexes - end - - def columns(table_name, name = nil)#:nodoc: - sql = "SHOW FIELDS FROM #{table_name}" - columns = [] - execute(sql, name).each { |field| columns << MysqlColumn.new(field[0], field[4], field[1], field[2] == "YES") } - columns - end - - def create_table(name, options = {}) #:nodoc: - super(name, {:options => "ENGINE=InnoDB"}.merge(options)) - end - - def rename_table(name, new_name) - execute "RENAME TABLE #{name} TO #{new_name}" - end - - def change_column_default(table_name, column_name, default) #:nodoc: - current_type = select_one("SHOW COLUMNS FROM #{table_name} LIKE '#{column_name}'")["Type"] - - change_column(table_name, column_name, current_type, { :default => default }) - end - - def change_column(table_name, column_name, type, options = {}) #:nodoc: - options[:default] ||= select_one("SHOW COLUMNS FROM #{table_name} LIKE '#{column_name}'")["Default"] - - change_column_sql = "ALTER TABLE #{table_name} CHANGE #{column_name} #{column_name} #{type_to_sql(type, options[:limit])}" - add_column_options!(change_column_sql, options) - execute(change_column_sql) - end - - def rename_column(table_name, column_name, new_column_name) #:nodoc: - current_type = select_one("SHOW COLUMNS FROM #{table_name} LIKE '#{column_name}'")["Type"] - execute "ALTER TABLE #{table_name} CHANGE #{column_name} #{new_column_name} #{current_type}" - end - - - private - def connect - encoding = @config[:encoding] - if encoding - @connection.options(Mysql::SET_CHARSET_NAME, encoding) rescue nil - end - @connection.real_connect(*@connection_options) - execute("SET NAMES '#{encoding}'") if encoding - end - - def select(sql, name = nil) - @connection.query_with_result = true - result = execute(sql, name) - rows = [] - if @null_values_in_each_hash - result.each_hash { |row| rows << row } - else - all_fields = result.fetch_fields.inject({}) { |fields, f| fields[f.name] = nil; fields } - result.each_hash { |row| rows << all_fields.dup.update(row) } - end - result.free - rows - end - end - end -end diff --git a/tracks/vendor/rails/activerecord/lib/active_record/connection_adapters/oci_adapter.rb b/tracks/vendor/rails/activerecord/lib/active_record/connection_adapters/oci_adapter.rb deleted file mode 100644 index 01e3d4df..00000000 --- a/tracks/vendor/rails/activerecord/lib/active_record/connection_adapters/oci_adapter.rb +++ /dev/null @@ -1,601 +0,0 @@ -# oci_adapter.rb -- ActiveRecord adapter for Oracle 8i, 9i, 10g -# -# Original author: Graham Jenkins -# -# Current maintainer: Michael Schoen -# -######################################################################### -# -# Implementation notes: -# 1. Redefines (safely) a method in ActiveRecord to make it possible to -# implement an autonumbering solution for Oracle. -# 2. The OCI8 driver is patched to properly handle values for LONG and -# TIMESTAMP columns. The driver-author has indicated that a future -# release of the driver will obviate this patch. -# 3. LOB support is implemented through an after_save callback. -# 4. Oracle does not offer native LIMIT and OFFSET options; this -# functionality is mimiced through the use of nested selects. -# See http://asktom.oracle.com/pls/ask/f?p=4950:8:::::F4950_P8_DISPLAYID:127412348064 -# -# Do what you want with this code, at your own peril, but if any -# significant portion of my code remains then please acknowledge my -# contribution. -# portions Copyright 2005 Graham Jenkins - -require 'active_record/connection_adapters/abstract_adapter' -require 'delegate' - -begin - require_library_or_gem 'oci8' unless self.class.const_defined? :OCI8 - - module ActiveRecord - class Base - def self.oci_connection(config) #:nodoc: - # Use OCI8AutoRecover instead of normal OCI8 driver. - ConnectionAdapters::OCIAdapter.new OCI8AutoRecover.new(config), logger - end - - # Enable the id column to be bound into the sql later, by the adapter's insert method. - # This is preferable to inserting the hard-coded value here, because the insert method - # needs to know the id value explicitly. - alias :attributes_with_quotes_pre_oci :attributes_with_quotes #:nodoc: - def attributes_with_quotes(creating = true) #:nodoc: - aq = attributes_with_quotes_pre_oci creating - if connection.class == ConnectionAdapters::OCIAdapter - aq[self.class.primary_key] = ":id" if creating && aq[self.class.primary_key].nil? - end - aq - end - - # After setting large objects to empty, select the OCI8::LOB - # and write back the data. - after_save :write_lobs - def write_lobs() #:nodoc: - if connection.is_a?(ConnectionAdapters::OCIAdapter) - self.class.columns.select { |c| c.type == :binary }.each { |c| - value = self[c.name] - next if value.nil? || (value == '') - lob = connection.select_one( - "select #{ c.name} from #{ self.class.table_name } WHERE #{ self.class.primary_key} = #{quote(id)}", - 'Writable Large Object')[c.name] - lob.write value - } - end - end - - private :write_lobs - end - - - module ConnectionAdapters #:nodoc: - class OCIColumn < Column #:nodoc: - attr_reader :sql_type - - # overridden to add the concept of scale, required to differentiate - # between integer and float fields - def initialize(name, default, sql_type, limit, scale, null) - @name, @limit, @sql_type, @scale, @null = name, limit, sql_type, scale, null - - @type = simplified_type(sql_type) - @default = type_cast(default) - - @primary = nil - @text = [:string, :text].include? @type - @number = [:float, :integer].include? @type - end - - def type_cast(value) - return nil if value.nil? || value =~ /^\s*null\s*$/i - case type - when :string then value - when :integer then defined?(value.to_i) ? value.to_i : (value ? 1 : 0) - when :float then value.to_f - when :datetime then cast_to_date_or_time(value) - when :time then cast_to_time(value) - else value - end - end - - private - def simplified_type(field_type) - case field_type - when /char/i : :string - when /num|float|double|dec|real|int/i : @scale == 0 ? :integer : :float - when /date|time/i : @name =~ /_at$/ ? :time : :datetime - when /lob/i : :binary - end - end - - def cast_to_date_or_time(value) - return value if value.is_a? Date - return nil if value.blank? - guess_date_or_time (value.is_a? Time) ? value : cast_to_time(value) - end - - def cast_to_time(value) - return value if value.is_a? Time - time_array = ParseDate.parsedate value - time_array[0] ||= 2000; time_array[1] ||= 1; time_array[2] ||= 1; - Time.send(Base.default_timezone, *time_array) rescue nil - end - - def guess_date_or_time(value) - (value.hour == 0 and value.min == 0 and value.sec == 0) ? - Date.new(value.year, value.month, value.day) : value - end - end - - - # This is an Oracle/OCI adapter for the ActiveRecord persistence - # framework. It relies upon the OCI8 driver, which works with Oracle 8i - # and above. Most recent development has been on Debian Linux against - # a 10g database, ActiveRecord 1.12.1 and OCI8 0.1.13. - # See: http://rubyforge.org/projects/ruby-oci8/ - # - # Usage notes: - # * Key generation assumes a "${table_name}_seq" sequence is available - # for all tables; the sequence name can be changed using - # ActiveRecord::Base.set_sequence_name. When using Migrations, these - # sequences are created automatically. - # * Oracle uses DATE or TIMESTAMP datatypes for both dates and times. - # Consequently some hacks are employed to map data back to Date or Time - # in Ruby. If the column_name ends in _time it's created as a Ruby Time. - # Else if the hours/minutes/seconds are 0, I make it a Ruby Date. Else - # it's a Ruby Time. This is a bit nasty - but if you use Duck Typing - # you'll probably not care very much. In 9i and up it's tempting to - # map DATE to Date and TIMESTAMP to Time, but too many databases use - # DATE for both. Timezones and sub-second precision on timestamps are - # not supported. - # * Default values that are functions (such as "SYSDATE") are not - # supported. This is a restriction of the way ActiveRecord supports - # default values. - # - # Options: - # - # * :username -- Defaults to root - # * :password -- Defaults to nothing - # * :host -- Defaults to localhost - class OCIAdapter < AbstractAdapter - - def adapter_name #:nodoc: - 'OCI' - end - - def supports_migrations? #:nodoc: - true - end - - def native_database_types #:nodoc - { - :primary_key => "NUMBER(38) NOT NULL", - :string => { :name => "VARCHAR2", :limit => 255 }, - :text => { :name => "LONG" }, - :integer => { :name => "NUMBER", :limit => 38 }, - :float => { :name => "NUMBER" }, - :datetime => { :name => "DATE" }, - :timestamp => { :name => "DATE" }, - :time => { :name => "DATE" }, - :date => { :name => "DATE" }, - :binary => { :name => "BLOB" }, - :boolean => { :name => "NUMBER", :limit => 1 } - } - end - - - # QUOTING ================================================== - # - # see: abstract/quoting.rb - - # camelCase column names need to be quoted; not that anyone using Oracle - # would really do this, but handling this case means we pass the test... - def quote_column_name(name) #:nodoc: - name =~ /[A-Z]/ ? "\"#{name}\"" : name - end - - def quote_string(string) #:nodoc: - string.gsub(/'/, "''") - end - - def quote(value, column = nil) #:nodoc: - if column and column.type == :binary then %Q{empty_#{ column.sql_type }()} - else case value - when String then %Q{'#{quote_string(value)}'} - when NilClass then 'null' - when TrueClass then '1' - when FalseClass then '0' - when Numeric then value.to_s - when Date, Time then %Q{'#{value.strftime("%Y-%m-%d %H:%M:%S")}'} - else %Q{'#{quote_string(value.to_yaml)}'} - end - end - end - - - # CONNECTION MANAGEMENT ====================================# - - # Returns true if the connection is active. - def active? - # Pings the connection to check if it's still good. Note that an - # #active? method is also available, but that simply returns the - # last known state, which isn't good enough if the connection has - # gone stale since the last use. - @connection.ping - rescue OCIError - false - end - - # Reconnects to the database. - def reconnect! - @connection.reset! - rescue OCIError => e - @logger.warn "#{adapter_name} automatic reconnection failed: #{e.message}" - end - - - # DATABASE STATEMENTS ====================================== - # - # see: abstract/database_statements.rb - - def select_all(sql, name = nil) #:nodoc: - select(sql, name) - end - - def select_one(sql, name = nil) #:nodoc: - result = select_all(sql, name) - result.size > 0 ? result.first : nil - end - - def execute(sql, name = nil) #:nodoc: - log(sql, name) { @connection.exec sql } - end - - def insert(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil) #:nodoc: - if pk.nil? # Who called us? What does the sql look like? No idea! - execute sql, name - elsif id_value # Pre-assigned id - log(sql, name) { @connection.exec sql } - else # Assume the sql contains a bind-variable for the id - id_value = select_one("select #{sequence_name}.nextval id from dual")['id'] - log(sql, name) { @connection.exec sql, id_value } - end - - id_value - end - - alias :update :execute #:nodoc: - alias :delete :execute #:nodoc: - - def begin_db_transaction #:nodoc: - @connection.autocommit = false - end - - def commit_db_transaction #:nodoc: - @connection.commit - ensure - @connection.autocommit = true - end - - def rollback_db_transaction #:nodoc: - @connection.rollback - ensure - @connection.autocommit = true - end - - def add_limit_offset!(sql, options) #:nodoc: - offset = options[:offset] || 0 - - if limit = options[:limit] - sql.replace "select * from (select raw_sql_.*, rownum raw_rnum_ from (#{sql}) raw_sql_ where rownum <= #{offset+limit}) where raw_rnum_ > #{offset}" - elsif offset > 0 - sql.replace "select * from (select raw_sql_.*, rownum raw_rnum_ from (#{sql}) raw_sql_) where raw_rnum_ > #{offset}" - end - end - - def default_sequence_name(table, column) #:nodoc: - "#{table}_seq" - end - - - # SCHEMA STATEMENTS ======================================== - # - # see: abstract/schema_statements.rb - - def tables(name = nil) #:nodoc: - select_all("select lower(table_name) from user_tables").inject([]) do | tabs, t | - tabs << t.to_a.first.last - end - end - - def indexes(table_name, name = nil) #:nodoc: - result = select_all(<<-SQL, name) - SELECT lower(i.index_name) as index_name, i.uniqueness, lower(c.column_name) as column_name - FROM user_indexes i, user_ind_columns c - WHERE i.table_name = '#{table_name.to_s.upcase}' - AND c.index_name = i.index_name - AND i.index_name NOT IN (SELECT index_name FROM user_constraints WHERE constraint_type = 'P') - ORDER BY i.index_name, c.column_position - SQL - - current_index = nil - indexes = [] - - result.each do |row| - if current_index != row['index_name'] - indexes << IndexDefinition.new(table_name, row['index_name'], row['uniqueness'] == "UNIQUE", []) - current_index = row['index_name'] - end - - indexes.last.columns << row['column_name'] - end - - indexes - end - - def columns(table_name, name = nil) #:nodoc: - table_name = table_name.to_s.upcase - owner = table_name.include?('.') ? "'#{table_name.split('.').first}'" : "user" - table = "'#{table_name.split('.').last}'" - scope = (owner == "user" ? "user" : "all") - - table_cols = %Q{ - select column_name, data_type, data_default, nullable, - decode(data_type, 'NUMBER', data_precision, - 'VARCHAR2', data_length, - null) as length, - decode(data_type, 'NUMBER', data_scale, null) as scale - from #{scope}_catalog cat, #{scope}_synonyms syn, all_tab_columns col - where cat.table_name = #{table} - and syn.synonym_name (+)= cat.table_name - and col.table_name = nvl(syn.table_name, cat.table_name) - and col.owner = nvl(syn.table_owner, #{(scope == "all" ? "cat.owner" : "user")}) } - - if scope == "all" - table_cols << %Q{ - and cat.owner = #{owner} - and syn.owner (+)= cat.owner } - end - - select_all(table_cols, name).map do |row| - row['data_default'].sub!(/^'(.*)'\s*$/, '\1') if row['data_default'] - OCIColumn.new( - oci_downcase(row['column_name']), - row['data_default'], - row['data_type'], - row['length'], - row['scale'], - row['nullable'] == 'Y' - ) - end - end - - def create_table(name, options = {}) #:nodoc: - super(name, options) - execute "CREATE SEQUENCE #{name}_seq" - end - - def rename_table(name, new_name) #:nodoc: - execute "RENAME #{name} TO #{new_name}" - execute "RENAME #{name}_seq TO #{new_name}_seq" - end - - def drop_table(name) #:nodoc: - super(name) - execute "DROP SEQUENCE #{name}_seq" - end - - def remove_index(table_name, options = {}) #:nodoc: - execute "DROP INDEX #{index_name(table_name, options)}" - end - - def change_column_default(table_name, column_name, default) #:nodoc: - execute "ALTER TABLE #{table_name} MODIFY #{column_name} DEFAULT #{quote(default)}" - end - - def change_column(table_name, column_name, type, options = {}) #:nodoc: - change_column_sql = "ALTER TABLE #{table_name} MODIFY #{column_name} #{type_to_sql(type, options[:limit])}" - add_column_options!(change_column_sql, options) - execute(change_column_sql) - end - - def rename_column(table_name, column_name, new_column_name) #:nodoc: - execute "ALTER TABLE #{table_name} RENAME COLUMN #{column_name} to #{new_column_name}" - end - - def remove_column(table_name, column_name) #:nodoc: - execute "ALTER TABLE #{table_name} DROP COLUMN #{column_name}" - end - - def structure_dump #:nodoc: - s = select_all("select sequence_name from user_sequences").inject("") do |structure, seq| - structure << "create sequence #{seq.to_a.first.last};\n\n" - end - - select_all("select table_name from user_tables").inject(s) do |structure, table| - ddl = "create table #{table.to_a.first.last} (\n " - cols = select_all(%Q{ - select column_name, data_type, data_length, data_precision, data_scale, data_default, nullable - from user_tab_columns - where table_name = '#{table.to_a.first.last}' - order by column_id - }).map do |row| - col = "#{row['column_name'].downcase} #{row['data_type'].downcase}" - if row['data_type'] =='NUMBER' and !row['data_precision'].nil? - col << "(#{row['data_precision'].to_i}" - col << ",#{row['data_scale'].to_i}" if !row['data_scale'].nil? - col << ')' - elsif row['data_type'].include?('CHAR') - col << "(#{row['data_length'].to_i})" - end - col << " default #{row['data_default']}" if !row['data_default'].nil? - col << ' not null' if row['nullable'] == 'N' - col - end - ddl << cols.join(",\n ") - ddl << ");\n\n" - structure << ddl - end - end - - def structure_drop #:nodoc: - s = select_all("select sequence_name from user_sequences").inject("") do |drop, seq| - drop << "drop sequence #{seq.to_a.first.last};\n\n" - end - - select_all("select table_name from user_tables").inject(s) do |drop, table| - drop << "drop table #{table.to_a.first.last} cascade constraints;\n\n" - end - end - - - private - - def select(sql, name = nil) - cursor = log(sql, name) { @connection.exec sql } - cols = cursor.get_col_names.map { |x| oci_downcase(x) } - rows = [] - - while row = cursor.fetch - hash = Hash.new - - cols.each_with_index do |col, i| - hash[col] = - case row[i] - when OCI8::LOB - name == 'Writable Large Object' ? row[i]: row[i].read - when OraDate - (row[i].hour == 0 and row[i].minute == 0 and row[i].second == 0) ? - row[i].to_date : row[i].to_time - else row[i] - end unless col == 'raw_rnum_' - end - - rows << hash - end - - rows - ensure - cursor.close if cursor - end - - # Oracle column names by default are case-insensitive, but treated as upcase; - # for neatness, we'll downcase within Rails. EXCEPT that folks CAN quote - # their column names when creating Oracle tables, which makes then case-sensitive. - # I don't know anybody who does this, but we'll handle the theoretical case of a - # camelCase column name. I imagine other dbs handle this different, since there's a - # unit test that's currently failing test_oci. - def oci_downcase(column_name) - column_name =~ /[a-z]/ ? column_name : column_name.downcase - end - - end - end - end - - - # This OCI8 patch may not longer be required with the upcoming - # release of version 0.2. - class OCI8 #:nodoc: - class Cursor #:nodoc: - alias :define_a_column_pre_ar :define_a_column - def define_a_column(i) - case do_ocicall(@ctx) { @parms[i - 1].attrGet(OCI_ATTR_DATA_TYPE) } - when 8 : @stmt.defineByPos(i, String, 65535) # Read LONG values - when 187 : @stmt.defineByPos(i, OraDate) # Read TIMESTAMP values - else define_a_column_pre_ar i - end - end - end - end - - - # The OCIConnectionFactory factors out the code necessary to connect and - # configure an OCI connection. - class OCIConnectionFactory #:nodoc: - def new_connection(username, password, host) - conn = OCI8.new username, password, host - conn.exec %q{alter session set nls_date_format = 'YYYY-MM-DD HH24:MI:SS'} - conn.exec %q{alter session set nls_timestamp_format = 'YYYY-MM-DD HH24:MI:SS'} rescue nil - conn.autocommit = true - conn - end - end - - - # The OCI8AutoRecover class enhances the OCI8 driver with auto-recover and - # reset functionality. If a call to #exec fails, and autocommit is turned on - # (ie., we're not in the middle of a longer transaction), it will - # automatically reconnect and try again. If autocommit is turned off, - # this would be dangerous (as the earlier part of the implied transaction - # may have failed silently if the connection died) -- so instead the - # connection is marked as dead, to be reconnected on it's next use. - class OCI8AutoRecover < DelegateClass(OCI8) #:nodoc: - attr_accessor :active - alias :active? :active - - cattr_accessor :auto_retry - class << self - alias :auto_retry? :auto_retry - end - @@auto_retry = false - - def initialize(config, factory = OCIConnectionFactory.new) - @active = true - @username, @password, @host = config[:username], config[:password], config[:host] - @factory = factory - @connection = @factory.new_connection @username, @password, @host - super @connection - end - - # Checks connection, returns true if active. Note that ping actively - # checks the connection, while #active? simply returns the last - # known state. - def ping - @connection.exec("select 1 from dual") { |r| nil } - @active = true - rescue - @active = false - raise - end - - # Resets connection, by logging off and creating a new connection. - def reset! - logoff rescue nil - begin - @connection = @factory.new_connection @username, @password, @host - __setobj__ @connection - @active = true - rescue - @active = false - raise - end - end - - # ORA-00028: your session has been killed - # ORA-01012: not logged on - # ORA-03113: end-of-file on communication channel - # ORA-03114: not connected to ORACLE - LOST_CONNECTION_ERROR_CODES = [ 28, 1012, 3113, 3114 ] - - # Adds auto-recovery functionality. - # - # See: http://www.jiubao.org/ruby-oci8/api.en.html#label-11 - def exec(sql, *bindvars) - should_retry = self.class.auto_retry? && autocommit? - - begin - @connection.exec(sql, *bindvars) - rescue OCIError => e - raise unless LOST_CONNECTION_ERROR_CODES.include?(e.code) - @active = false - raise unless should_retry - should_retry = false - reset! rescue nil - retry - end - end - - end - -rescue LoadError - # OCI8 driver is unavailable. -end diff --git a/tracks/vendor/rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb b/tracks/vendor/rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb deleted file mode 100644 index 8f2ba6e6..00000000 --- a/tracks/vendor/rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb +++ /dev/null @@ -1,487 +0,0 @@ -require 'active_record/connection_adapters/abstract_adapter' - -module ActiveRecord - class Base - # Establishes a connection to the database that's used by all Active Record objects - def self.postgresql_connection(config) # :nodoc: - require_library_or_gem 'postgres' unless self.class.const_defined?(:PGconn) - - config = config.symbolize_keys - host = config[:host] - port = config[:port] || 5432 unless host.nil? - username = config[:username].to_s - password = config[:password].to_s - - min_messages = config[:min_messages] - - if config.has_key?(:database) - database = config[:database] - else - raise ArgumentError, "No database specified. Missing argument: database." - end - - pga = ConnectionAdapters::PostgreSQLAdapter.new( - PGconn.connect(host, port, "", "", database, username, password), logger, config - ) - - pga.schema_search_path = config[:schema_search_path] || config[:schema_order] - - pga - end - end - - module ConnectionAdapters - # The PostgreSQL adapter works both with the C-based (http://www.postgresql.jp/interfaces/ruby/) and the Ruby-base - # (available both as gem and from http://rubyforge.org/frs/?group_id=234&release_id=1145) drivers. - # - # Options: - # - # * :host -- Defaults to localhost - # * :port -- Defaults to 5432 - # * :username -- Defaults to nothing - # * :password -- Defaults to nothing - # * :database -- The name of the database. No default, must be provided. - # * :schema_search_path -- An optional schema search path for the connection given as a string of comma-separated schema names. This is backward-compatible with the :schema_order option. - # * :encoding -- An optional client encoding that is using in a SET client_encoding TO call on connection. - # * :min_messages -- An optional client min messages that is using in a SET client_min_messages TO call on connection. - class PostgreSQLAdapter < AbstractAdapter - def adapter_name - 'PostgreSQL' - end - - def initialize(connection, logger, config = {}) - super(connection, logger) - @config = config - configure_connection - end - - # Is this connection alive and ready for queries? - def active? - if @connection.respond_to?(:status) - @connection.status == PGconn::CONNECTION_OK - else - @connection.query 'SELECT 1' - true - end - rescue PGError - false - end - - # Close then reopen the connection. - def reconnect! - # TODO: postgres-pr doesn't have PGconn#reset. - if @connection.respond_to?(:reset) - @connection.reset - configure_connection - end - end - - def native_database_types - { - :primary_key => "serial primary key", - :string => { :name => "character varying", :limit => 255 }, - :text => { :name => "text" }, - :integer => { :name => "integer" }, - :float => { :name => "float" }, - :datetime => { :name => "timestamp" }, - :timestamp => { :name => "timestamp" }, - :time => { :name => "time" }, - :date => { :name => "date" }, - :binary => { :name => "bytea" }, - :boolean => { :name => "boolean" } - } - end - - def supports_migrations? - true - end - - - # QUOTING ================================================== - - def quote(value, column = nil) - if value.kind_of?(String) && column && column.type == :binary - "'#{escape_bytea(value)}'" - else - super - end - end - - def quote_column_name(name) - %("#{name}") - end - - - # DATABASE STATEMENTS ====================================== - - def select_all(sql, name = nil) #:nodoc: - select(sql, name) - end - - def select_one(sql, name = nil) #:nodoc: - result = select(sql, name) - result.first if result - end - - def insert(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil) #:nodoc: - execute(sql, name) - table = sql.split(" ", 4)[2] - id_value || last_insert_id(table, sequence_name || default_sequence_name(table, pk)) - end - - def query(sql, name = nil) #:nodoc: - log(sql, name) { @connection.query(sql) } - end - - def execute(sql, name = nil) #:nodoc: - log(sql, name) { @connection.exec(sql) } - end - - def update(sql, name = nil) #:nodoc: - execute(sql, name).cmdtuples - end - - alias_method :delete, :update #:nodoc: - - - def begin_db_transaction #:nodoc: - execute "BEGIN" - end - - def commit_db_transaction #:nodoc: - execute "COMMIT" - end - - def rollback_db_transaction #:nodoc: - execute "ROLLBACK" - end - - - # SCHEMA STATEMENTS ======================================== - - # Return the list of all tables in the schema search path. - def tables(name = nil) #:nodoc: - schemas = schema_search_path.split(/,/).map { |p| quote(p) }.join(',') - query(<<-SQL, name).map { |row| row[0] } - SELECT tablename - FROM pg_tables - WHERE schemaname IN (#{schemas}) - SQL - end - - def indexes(table_name, name = nil) #:nodoc: - result = query(<<-SQL, name) - SELECT i.relname, d.indisunique, a.attname - FROM pg_class t, pg_class i, pg_index d, pg_attribute a - WHERE i.relkind = 'i' - AND d.indexrelid = i.oid - AND d.indisprimary = 'f' - AND t.oid = d.indrelid - AND t.relname = '#{table_name}' - AND a.attrelid = t.oid - AND ( d.indkey[0]=a.attnum OR d.indkey[1]=a.attnum - OR d.indkey[2]=a.attnum OR d.indkey[3]=a.attnum - OR d.indkey[4]=a.attnum OR d.indkey[5]=a.attnum - OR d.indkey[6]=a.attnum OR d.indkey[7]=a.attnum - OR d.indkey[8]=a.attnum OR d.indkey[9]=a.attnum ) - ORDER BY i.relname - SQL - - current_index = nil - indexes = [] - - result.each do |row| - if current_index != row[0] - indexes << IndexDefinition.new(table_name, row[0], row[1] == "t", []) - current_index = row[0] - end - - indexes.last.columns << row[2] - end - - indexes - end - - def columns(table_name, name = nil) #:nodoc: - column_definitions(table_name).collect do |name, type, default, notnull| - Column.new(name, default_value(default), translate_field_type(type), - notnull == "f") - end - end - - # Set the schema search path to a string of comma-separated schema names. - # Names beginning with $ are quoted (e.g. $user => '$user') - # See http://www.postgresql.org/docs/8.0/interactive/ddl-schemas.html - def schema_search_path=(schema_csv) #:nodoc: - if schema_csv - execute "SET search_path TO #{schema_csv}" - @schema_search_path = nil - end - end - - def schema_search_path #:nodoc: - @schema_search_path ||= query('SHOW search_path')[0][0] - end - - def default_sequence_name(table_name, pk = nil) - default_pk, default_seq = pk_and_sequence_for(table_name) - default_seq || "#{table_name}_#{pk || default_pk || 'id'}_seq" - end - - # Resets sequence to the max value of the table's pk if present. - def reset_pk_sequence!(table, pk = nil, sequence = nil) - unless pk and sequence - default_pk, default_sequence = pk_and_sequence_for(table) - pk ||= default_pk - sequence ||= default_sequence - end - if pk - if sequence - select_value <<-end_sql, 'Reset sequence' - SELECT setval('#{sequence}', (SELECT COALESCE(MAX(#{pk})+(SELECT increment_by FROM #{sequence}), (SELECT min_value FROM #{sequence})) FROM #{table}), false) - end_sql - else - @logger.warn "#{table} has primary key #{pk} with no default sequence" if @logger - end - end - end - - # Find a table's primary key and sequence. - def pk_and_sequence_for(table) - # First try looking for a sequence with a dependency on the - # given table's primary key. - result = execute(<<-end_sql, 'PK and serial sequence')[0] - SELECT attr.attname, name.nspname, seq.relname - FROM pg_class seq, - pg_attribute attr, - pg_depend dep, - pg_namespace name, - pg_constraint cons - WHERE seq.oid = dep.objid - AND seq.relnamespace = name.oid - AND seq.relkind = 'S' - AND attr.attrelid = dep.refobjid - AND attr.attnum = dep.refobjsubid - AND attr.attrelid = cons.conrelid - AND attr.attnum = cons.conkey[1] - AND cons.contype = 'p' - AND dep.refobjid = '#{table}'::regclass - end_sql - - if result.nil? or result.empty? - # If that fails, try parsing the primary key's default value. - # Support the 7.x and 8.0 nextval('foo'::text) as well as - # the 8.1+ nextval('foo'::regclass). - # TODO: assumes sequence is in same schema as table. - result = execute(<<-end_sql, 'PK and custom sequence')[0] - SELECT attr.attname, name.nspname, split_part(def.adsrc, '\\\'', 2) - FROM pg_class t - JOIN pg_namespace name ON (t.relnamespace = name.oid) - JOIN pg_attribute attr ON (t.oid = attrelid) - JOIN pg_attrdef def ON (adrelid = attrelid AND adnum = attnum) - JOIN pg_constraint cons ON (conrelid = adrelid AND adnum = conkey[1]) - WHERE t.oid = '#{table}'::regclass - AND cons.contype = 'p' - AND def.adsrc ~* 'nextval' - end_sql - end - # check for existence of . in sequence name as in public.foo_sequence. if it does not exist, join the current namespace - result.last['.'] ? [result.first, result.last] : [result.first, "#{result[1]}.#{result[2]}"] - rescue - nil - end - - def rename_table(name, new_name) - execute "ALTER TABLE #{name} RENAME TO #{new_name}" - end - - def add_column(table_name, column_name, type, options = {}) - native_type = native_database_types[type] - sql_commands = ["ALTER TABLE #{table_name} ADD #{column_name} #{type_to_sql(type, options[:limit])}"] - if options[:default] - sql_commands << "ALTER TABLE #{table_name} ALTER #{column_name} SET DEFAULT '#{options[:default]}'" - end - if options[:null] == false - sql_commands << "ALTER TABLE #{table_name} ALTER #{column_name} SET NOT NULL" - end - sql_commands.each { |cmd| execute(cmd) } - end - - def change_column(table_name, column_name, type, options = {}) #:nodoc: - execute = "ALTER TABLE #{table_name} ALTER #{column_name} TYPE #{type}" - change_column_default(table_name, column_name, options[:default]) unless options[:default].nil? - end - - def change_column_default(table_name, column_name, default) #:nodoc: - execute "ALTER TABLE #{table_name} ALTER COLUMN #{column_name} SET DEFAULT '#{default}'" - end - - def rename_column(table_name, column_name, new_column_name) #:nodoc: - execute "ALTER TABLE #{table_name} RENAME COLUMN #{column_name} TO #{new_column_name}" - end - - def remove_index(table_name, options) #:nodoc: - if Hash === options - index_name = options[:name] - else - index_name = "#{table_name}_#{options}_index" - end - - execute "DROP INDEX #{index_name}" - end - - - private - BYTEA_COLUMN_TYPE_OID = 17 - - def configure_connection - if @config[:encoding] - execute("SET client_encoding TO '#{@config[:encoding]}'") - end - if @config[:min_messages] - execute("SET client_min_messages TO '#{@config[:min_messages]}'") - end - end - - def last_insert_id(table, sequence_name) - Integer(select_value("SELECT currval('#{sequence_name}')")) - end - - def select(sql, name = nil) - res = execute(sql, name) - results = res.result - rows = [] - if results.length > 0 - fields = res.fields - results.each do |row| - hashed_row = {} - row.each_index do |cel_index| - column = row[cel_index] - if res.type(cel_index) == BYTEA_COLUMN_TYPE_OID - column = unescape_bytea(column) - end - hashed_row[fields[cel_index]] = column - end - rows << hashed_row - end - end - return rows - end - - def escape_bytea(s) - if PGconn.respond_to? :escape_bytea - self.class.send(:define_method, :escape_bytea) do |s| - PGconn.escape_bytea(s) if s - end - else - self.class.send(:define_method, :escape_bytea) do |s| - if s - result = '' - s.each_byte { |c| result << sprintf('\\\\%03o', c) } - result - end - end - end - escape_bytea(s) - end - - def unescape_bytea(s) - if PGconn.respond_to? :unescape_bytea - self.class.send(:define_method, :unescape_bytea) do |s| - PGconn.unescape_bytea(s) if s - end - else - self.class.send(:define_method, :unescape_bytea) do |s| - if s - result = '' - i, max = 0, s.size - while i < max - char = s[i] - if char == ?\\ - if s[i+1] == ?\\ - char = ?\\ - i += 1 - else - char = s[i+1..i+3].oct - i += 3 - end - end - result << char - i += 1 - end - result - end - end - end - unescape_bytea(s) - end - - # Query a table's column names, default values, and types. - # - # The underlying query is roughly: - # SELECT column.name, column.type, default.value - # FROM column LEFT JOIN default - # ON column.table_id = default.table_id - # AND column.num = default.column_num - # WHERE column.table_id = get_table_id('table_name') - # AND column.num > 0 - # AND NOT column.is_dropped - # ORDER BY column.num - # - # If the table name is not prefixed with a schema, the database will - # take the first match from the schema search path. - # - # Query implementation notes: - # - format_type includes the column size constraint, e.g. varchar(50) - # - ::regclass is a function that gives the id for a table name - def column_definitions(table_name) - query <<-end_sql - SELECT a.attname, format_type(a.atttypid, a.atttypmod), d.adsrc, a.attnotnull - FROM pg_attribute a LEFT JOIN pg_attrdef d - ON a.attrelid = d.adrelid AND a.attnum = d.adnum - WHERE a.attrelid = '#{table_name}'::regclass - AND a.attnum > 0 AND NOT a.attisdropped - ORDER BY a.attnum - end_sql - end - - # Translate PostgreSQL-specific types into simplified SQL types. - # These are special cases; standard types are handled by - # ConnectionAdapters::Column#simplified_type. - def translate_field_type(field_type) - # Match the beginning of field_type since it may have a size constraint on the end. - case field_type - when /^timestamp/i then 'datetime' - when /^real|^money/i then 'float' - when /^interval/i then 'string' - # geometric types (the line type is currently not implemented in postgresql) - when /^(?:point|lseg|box|"?path"?|polygon|circle)/i then 'string' - when /^bytea/i then 'binary' - else field_type # Pass through standard types. - end - end - - def default_value(value) - # Boolean types - return "t" if value =~ /true/i - return "f" if value =~ /false/i - - # Char/String type values - return $1 if value =~ /^'(.*)'::(bpchar|text|character varying)$/ - - # Numeric values - return value if value =~ /^[0-9]+(\.[0-9]*)?/ - - # Date / Time magic values - return Time.now.to_s if value =~ /^now\(\)|^\('now'::text\)::(date|timestamp)/i - - # Fixed dates / times - return $1 if value =~ /^'(.+)'::(date|timestamp)/ - - # Anything else is blank, some user type, or some function - # and we can't know the value of that, so return nil. - return nil - end - end - end -end diff --git a/tracks/vendor/rails/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb b/tracks/vendor/rails/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb deleted file mode 100644 index 44011a09..00000000 --- a/tracks/vendor/rails/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb +++ /dev/null @@ -1,338 +0,0 @@ -# Author: Luke Holden -# Updated for SQLite3: Jamis Buck - -require 'active_record/connection_adapters/abstract_adapter' - -module ActiveRecord - class Base - class << self - # sqlite3 adapter reuses sqlite_connection. - def sqlite3_connection(config) # :nodoc: - parse_config!(config) - - unless self.class.const_defined?(:SQLite3) - require_library_or_gem(config[:adapter]) - end - - db = SQLite3::Database.new( - config[:database], - :results_as_hash => true, - :type_translation => false - ) - ConnectionAdapters::SQLiteAdapter.new(db, logger) - end - - # Establishes a connection to the database that's used by all Active Record objects - def sqlite_connection(config) # :nodoc: - parse_config!(config) - - unless self.class.const_defined?(:SQLite) - require_library_or_gem(config[:adapter]) - - db = SQLite::Database.new(config[:database], 0) - db.show_datatypes = "ON" if !defined? SQLite::Version - db.results_as_hash = true if defined? SQLite::Version - db.type_translation = false - - # "Downgrade" deprecated sqlite API - if SQLite.const_defined?(:Version) - ConnectionAdapters::SQLiteAdapter.new(db, logger) - else - ConnectionAdapters::DeprecatedSQLiteAdapter.new(db, logger) - end - end - end - - private - def parse_config!(config) - config[:database] ||= config[:dbfile] - # Require database. - unless config[:database] - raise ArgumentError, "No database file specified. Missing argument: database" - end - - # Allow database path relative to RAILS_ROOT, but only if - # the database path is not the special path that tells - # Sqlite build a database only in memory. - if Object.const_defined?(:RAILS_ROOT) && ':memory:' != config[:database] - config[:database] = File.expand_path(config[:database], RAILS_ROOT) - end - end - end - end - - module ConnectionAdapters #:nodoc: - class SQLiteColumn < Column #:nodoc: - class << self - def string_to_binary(value) - value.gsub(/\0|\%/) do |b| - case b - when "\0" then "%00" - when "%" then "%25" - end - end - end - - def binary_to_string(value) - value.gsub(/%00|%25/) do |b| - case b - when "%00" then "\0" - when "%25" then "%" - end - end - end - end - end - - # The SQLite adapter works with both the 2.x and 3.x series of SQLite with the sqlite-ruby drivers (available both as gems and - # from http://rubyforge.org/projects/sqlite-ruby/). - # - # Options: - # - # * :database -- Path to the database file. - class SQLiteAdapter < AbstractAdapter - def adapter_name #:nodoc: - 'SQLite' - end - - def supports_migrations? #:nodoc: - true - end - - def native_database_types #:nodoc: - { - :primary_key => "INTEGER PRIMARY KEY NOT NULL", - :string => { :name => "varchar", :limit => 255 }, - :text => { :name => "text" }, - :integer => { :name => "integer" }, - :float => { :name => "float" }, - :datetime => { :name => "datetime" }, - :timestamp => { :name => "datetime" }, - :time => { :name => "datetime" }, - :date => { :name => "date" }, - :binary => { :name => "blob" }, - :boolean => { :name => "boolean" } - } - end - - - # QUOTING ================================================== - - def quote_string(s) #:nodoc: - @connection.class.quote(s) - end - - def quote_column_name(name) #:nodoc: - %Q("#{name}") - end - - - # DATABASE STATEMENTS ====================================== - - def execute(sql, name = nil) #:nodoc: - log(sql, name) { @connection.execute(sql) } - end - - def update(sql, name = nil) #:nodoc: - execute(sql, name) - @connection.changes - end - - def delete(sql, name = nil) #:nodoc: - sql += " WHERE 1=1" unless sql =~ /WHERE/i - execute(sql, name) - @connection.changes - end - - def insert(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil) #:nodoc: - execute(sql, name = nil) - id_value || @connection.last_insert_row_id - end - - def select_all(sql, name = nil) #:nodoc: - execute(sql, name).map do |row| - record = {} - row.each_key do |key| - if key.is_a?(String) - record[key.sub(/^\w+\./, '')] = row[key] - end - end - record - end - end - - def select_one(sql, name = nil) #:nodoc: - result = select_all(sql, name) - result.nil? ? nil : result.first - end - - - def begin_db_transaction #:nodoc: - @connection.transaction - end - - def commit_db_transaction #:nodoc: - @connection.commit - end - - def rollback_db_transaction #:nodoc: - @connection.rollback - end - - - # SCHEMA STATEMENTS ======================================== - - def tables(name = nil) #:nodoc: - execute("SELECT name FROM sqlite_master WHERE type = 'table'", name).map do |row| - row[0] - end - end - - def columns(table_name, name = nil) #:nodoc: - table_structure(table_name).map { |field| - SQLiteColumn.new(field['name'], field['dflt_value'], field['type'], field['notnull'] == "0") - } - end - - def indexes(table_name, name = nil) #:nodoc: - execute("PRAGMA index_list(#{table_name})", name).map do |row| - index = IndexDefinition.new(table_name, row['name']) - index.unique = row['unique'] != '0' - index.columns = execute("PRAGMA index_info('#{index.name}')").map { |col| col['name'] } - index - end - end - - def primary_key(table_name) #:nodoc: - column = table_structure(table_name).find {|field| field['pk'].to_i == 1} - column ? column['name'] : nil - end - - def remove_index(table_name, options={}) #:nodoc: - if Hash === options - index_name = options[:name] - else - index_name = "#{table_name}_#{options}_index" - end - - execute "DROP INDEX #{index_name}" - end - - def rename_table(name, new_name) - move_table(name, new_name) - end - - def add_column(table_name, column_name, type, options = {}) #:nodoc: - alter_table(table_name) do |definition| - definition.column(column_name, type, options) - end - end - - def remove_column(table_name, column_name) #:nodoc: - alter_table(table_name) do |definition| - definition.columns.delete(definition[column_name]) - end - end - - def change_column_default(table_name, column_name, default) #:nodoc: - alter_table(table_name) do |definition| - definition[column_name].default = default - end - end - - def change_column(table_name, column_name, type, options = {}) #:nodoc: - alter_table(table_name) do |definition| - definition[column_name].instance_eval do - self.type = type - self.limit = options[:limit] if options[:limit] - self.default = options[:default] if options[:default] - end - end - end - - def rename_column(table_name, column_name, new_column_name) #:nodoc: - alter_table(table_name, :rename => {column_name => new_column_name}) - end - - - protected - def table_structure(table_name) - returning structure = execute("PRAGMA table_info(#{table_name})") do - raise ActiveRecord::StatementInvalid if structure.empty? - end - end - - def alter_table(table_name, options = {}) #:nodoc: - altered_table_name = "altered_#{table_name}" - caller = lambda {|definition| yield definition if block_given?} - - transaction do - move_table(table_name, altered_table_name, - options.merge(:temporary => true)) - move_table(altered_table_name, table_name, &caller) - end - end - - def move_table(from, to, options = {}, &block) #:nodoc: - copy_table(from, to, options, &block) - drop_table(from) - end - - def copy_table(from, to, options = {}) #:nodoc: - create_table(to, options) do |@definition| - columns(from).each do |column| - column_name = options[:rename] ? - (options[:rename][column.name] || - options[:rename][column.name.to_sym] || - column.name) : column.name - - @definition.column(column_name, column.type, - :limit => column.limit, :default => column.default, - :null => column.null) - end - @definition.primary_key(primary_key(from)) - yield @definition if block_given? - end - - copy_table_indexes(from, to) - copy_table_contents(from, to, - @definition.columns.map {|column| column.name}, - options[:rename] || {}) - end - - def copy_table_indexes(from, to) #:nodoc: - indexes(from).each do |index| - name = index.name - if to == "altered_#{from}" - name = "temp_#{name}" - elsif from == "altered_#{to}" - name = name[5..-1] - end - - opts = { :name => name } - opts[:unique] = true if index.unique - add_index(to, index.columns, opts) - end - end - - def copy_table_contents(from, to, columns, rename = {}) #:nodoc: - column_mappings = Hash[*columns.map {|name| [name, name]}.flatten] - rename.inject(column_mappings) {|map, a| map[a.last] = a.first; map} - - @connection.execute "SELECT * FROM #{from}" do |row| - sql = "INSERT INTO #{to} VALUES (" - sql << columns.map {|col| quote row[column_mappings[col]]} * ', ' - sql << ')' - @connection.execute sql - end - end - end - - class DeprecatedSQLiteAdapter < SQLiteAdapter # :nodoc: - def insert(sql, name = nil, pk = nil, id_value = nil) - execute(sql, name = nil) - id_value || @connection.last_insert_rowid - end - end - end -end diff --git a/tracks/vendor/rails/activerecord/lib/active_record/connection_adapters/sqlserver_adapter.rb b/tracks/vendor/rails/activerecord/lib/active_record/connection_adapters/sqlserver_adapter.rb deleted file mode 100644 index 9d717400..00000000 --- a/tracks/vendor/rails/activerecord/lib/active_record/connection_adapters/sqlserver_adapter.rb +++ /dev/null @@ -1,543 +0,0 @@ -require 'active_record/connection_adapters/abstract_adapter' - -# sqlserver_adapter.rb -- ActiveRecord adapter for Microsoft SQL Server -# -# Author: Joey Gibson -# Date: 10/14/2004 -# -# Modifications: DeLynn Berry -# Date: 3/22/2005 -# -# Modifications (ODBC): Mark Imbriaco -# Date: 6/26/2005 -# -# Current maintainer: Ryan Tomayko -# -# Modifications (Migrations): Tom Ward -# Date: 27/10/2005 -# - -module ActiveRecord - class Base - def self.sqlserver_connection(config) #:nodoc: - require_library_or_gem 'dbi' unless self.class.const_defined?(:DBI) - - config = config.symbolize_keys - - mode = config[:mode] ? config[:mode].to_s.upcase : 'ADO' - username = config[:username] ? config[:username].to_s : 'sa' - password = config[:password] ? config[:password].to_s : '' - if mode == "ODBC" - raise ArgumentError, "Missing DSN. Argument ':dsn' must be set in order for this adapter to work." unless config.has_key?(:dsn) - dsn = config[:dsn] - driver_url = "DBI:ODBC:#{dsn}" - else - raise ArgumentError, "Missing Database. Argument ':database' must be set in order for this adapter to work." unless config.has_key?(:database) - database = config[:database] - host = config[:host] ? config[:host].to_s : 'localhost' - driver_url = "DBI:ADO:Provider=SQLOLEDB;Data Source=#{host};Initial Catalog=#{database};User Id=#{username};Password=#{password};" - end - conn = DBI.connect(driver_url, username, password) - - conn["AutoCommit"] = true - ConnectionAdapters::SQLServerAdapter.new(conn, logger, [driver_url, username, password]) - end - end # class Base - - module ConnectionAdapters - class ColumnWithIdentity < Column# :nodoc: - attr_reader :identity, :is_special, :scale - - def initialize(name, default, sql_type = nil, is_identity = false, scale_value = 0) - super(name, default, sql_type) - @identity = is_identity - @is_special = sql_type =~ /text|ntext|image/i ? true : false - @scale = scale_value - # SQL Server only supports limits on *char and float types - @limit = nil unless @type == :float or @type == :string - end - - def simplified_type(field_type) - case field_type - when /int|bigint|smallint|tinyint/i then :integer - when /float|double|decimal|money|numeric|real|smallmoney/i then @scale == 0 ? :integer : :float - when /datetime|smalldatetime/i then :datetime - when /timestamp/i then :timestamp - when /time/i then :time - when /text|ntext/i then :text - when /binary|image|varbinary/i then :binary - when /char|nchar|nvarchar|string|varchar/i then :string - when /bit/i then :boolean - when /uniqueidentifier/i then :string - end - end - - def type_cast(value) - return nil if value.nil? || value =~ /^\s*null\s*$/i - case type - when :string then value - when :integer then value == true || value == false ? value == true ? 1 : 0 : value.to_i - when :float then value.to_f - when :datetime then cast_to_datetime(value) - when :timestamp then cast_to_time(value) - when :time then cast_to_time(value) - when :date then cast_to_datetime(value) - when :boolean then value == true or (value =~ /^t(rue)?$/i) == 0 or value.to_s == '1' - else value - end - end - - def cast_to_time(value) - return value if value.is_a?(Time) - time_array = ParseDate.parsedate(value) - time_array[0] ||= 2000 - time_array[1] ||= 1 - time_array[2] ||= 1 - Time.send(Base.default_timezone, *time_array) rescue nil - end - - def cast_to_datetime(value) - if value.is_a?(Time) - if value.year != 0 and value.month != 0 and value.day != 0 - return value - else - return Time.mktime(2000, 1, 1, value.hour, value.min, value.sec) rescue nil - end - end - return cast_to_time(value) if value.is_a?(Date) or value.is_a?(String) rescue nil - value - end - - # These methods will only allow the adapter to insert binary data with a length of 7K or less - # because of a SQL Server statement length policy. - def self.string_to_binary(value) - value.gsub(/(\r|\n|\0|\x1a)/) do - case $1 - when "\r" then "%00" - when "\n" then "%01" - when "\0" then "%02" - when "\x1a" then "%03" - end - end - end - - def self.binary_to_string(value) - value.gsub(/(%00|%01|%02|%03)/) do - case $1 - when "%00" then "\r" - when "%01" then "\n" - when "%02\0" then "\0" - when "%03" then "\x1a" - end - end - end - end - - # In ADO mode, this adapter will ONLY work on Windows systems, - # since it relies on Win32OLE, which, to my knowledge, is only - # available on Windows. - # - # This mode also relies on the ADO support in the DBI module. If you are using the - # one-click installer of Ruby, then you already have DBI installed, but - # the ADO module is *NOT* installed. You will need to get the latest - # source distribution of Ruby-DBI from http://ruby-dbi.sourceforge.net/ - # unzip it, and copy the file - # src/lib/dbd_ado/ADO.rb - # to - # X:/Ruby/lib/ruby/site_ruby/1.8/DBD/ADO/ADO.rb - # (you will more than likely need to create the ADO directory). - # Once you've installed that file, you are ready to go. - # - # In ODBC mode, the adapter requires the ODBC support in the DBI module which requires - # the Ruby ODBC module. Ruby ODBC 0.996 was used in development and testing, - # and it is available at http://www.ch-werner.de/rubyodbc/ - # - # Options: - # - # * :mode -- ADO or ODBC. Defaults to ADO. - # * :username -- Defaults to sa. - # * :password -- Defaults to empty string. - # - # ADO specific options: - # - # * :host -- Defaults to localhost. - # * :database -- The name of the database. No default, must be provided. - # - # ODBC specific options: - # - # * :dsn -- Defaults to nothing. - # - # ADO code tested on Windows 2000 and higher systems, - # running ruby 1.8.2 (2004-07-29) [i386-mswin32], and SQL Server 2000 SP3. - # - # ODBC code tested on a Fedora Core 4 system, running FreeTDS 0.63, - # unixODBC 2.2.11, Ruby ODBC 0.996, Ruby DBI 0.0.23 and Ruby 1.8.2. - # [Linux strongmad 2.6.11-1.1369_FC4 #1 Thu Jun 2 22:55:56 EDT 2005 i686 i686 i386 GNU/Linux] - class SQLServerAdapter < AbstractAdapter - - def initialize(connection, logger, connection_options=nil) - super(connection, logger) - @connection_options = connection_options - end - - def native_database_types - { - :primary_key => "int NOT NULL IDENTITY(1, 1) PRIMARY KEY", - :string => { :name => "varchar", :limit => 255 }, - :text => { :name => "text" }, - :integer => { :name => "int" }, - :float => { :name => "float", :limit => 8 }, - :datetime => { :name => "datetime" }, - :timestamp => { :name => "datetime" }, - :time => { :name => "datetime" }, - :date => { :name => "datetime" }, - :binary => { :name => "image"}, - :boolean => { :name => "bit"} - } - end - - def adapter_name - 'SQLServer' - end - - def supports_migrations? #:nodoc: - true - end - - # CONNECTION MANAGEMENT ====================================# - - # Returns true if the connection is active. - def active? - @connection.execute("SELECT 1") { } - true - rescue DBI::DatabaseError, DBI::InterfaceError - false - end - - # Reconnects to the database, returns false if no connection could be made. - def reconnect! - @connection.disconnect rescue nil - @connection = DBI.connect(*@connection_options) - rescue DBI::DatabaseError => e - @logger.warn "#{adapter_name} reconnection failed: #{e.message}" if @logger - false - end - - def select_all(sql, name = nil) - select(sql, name) - end - - def select_one(sql, name = nil) - add_limit!(sql, :limit => 1) - result = select(sql, name) - result.nil? ? nil : result.first - end - - def columns(table_name, name = nil) - return [] if table_name.blank? - table_name = table_name.to_s if table_name.is_a?(Symbol) - table_name = table_name.split('.')[-1] unless table_name.nil? - sql = "SELECT COLUMN_NAME as ColName, COLUMN_DEFAULT as DefaultValue, DATA_TYPE as ColType, COL_LENGTH('#{table_name}', COLUMN_NAME) as Length, COLUMNPROPERTY(OBJECT_ID('#{table_name}'), COLUMN_NAME, 'IsIdentity') as IsIdentity, NUMERIC_SCALE as Scale FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = '#{table_name}'" - # Comment out if you want to have the Columns select statment logged. - # Personnally, I think it adds unneccessary bloat to the log. - # If you do comment it out, make sure to un-comment the "result" line that follows - result = log(sql, name) { @connection.select_all(sql) } - #result = @connection.select_all(sql) - columns = [] - result.each { |field| columns << ColumnWithIdentity.new(field[:ColName], field[:DefaultValue].to_s.gsub!(/[()\']/,"") =~ /null/ ? nil : field[:DefaultValue], "#{field[:ColType]}(#{field[:Length]})", field[:IsIdentity] == 1 ? true : false, field[:Scale]) } - columns - end - - def insert(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil) - begin - table_name = get_table_name(sql) - col = get_identity_column(table_name) - ii_enabled = false - - if col != nil - if query_contains_identity_column(sql, col) - begin - execute enable_identity_insert(table_name, true) - ii_enabled = true - rescue Exception => e - raise ActiveRecordError, "IDENTITY_INSERT could not be turned ON" - end - end - end - log(sql, name) do - @connection.execute(sql) - id_value || select_one("SELECT @@IDENTITY AS Ident")["Ident"] - end - ensure - if ii_enabled - begin - execute enable_identity_insert(table_name, false) - rescue Exception => e - raise ActiveRecordError, "IDENTITY_INSERT could not be turned OFF" - end - end - end - end - - def execute(sql, name = nil) - if sql =~ /^\s*INSERT/i - insert(sql, name) - elsif sql =~ /^\s*UPDATE|^\s*DELETE/i - log(sql, name) do - @connection.execute(sql) - retVal = select_one("SELECT @@ROWCOUNT AS AffectedRows")["AffectedRows"] - end - else - log(sql, name) { @connection.execute(sql) } - end - end - - def update(sql, name = nil) - execute(sql, name) - end - alias_method :delete, :update - - def begin_db_transaction - @connection["AutoCommit"] = false - rescue Exception => e - @connection["AutoCommit"] = true - end - - def commit_db_transaction - @connection.commit - ensure - @connection["AutoCommit"] = true - end - - def rollback_db_transaction - @connection.rollback - ensure - @connection["AutoCommit"] = true - end - - def quote(value, column = nil) - case value - when String - if column && column.type == :binary - "'#{quote_string(column.class.string_to_binary(value))}'" - else - "'#{quote_string(value)}'" - end - when NilClass then "NULL" - when TrueClass then '1' - when FalseClass then '0' - when Float, Fixnum, Bignum then value.to_s - when Date then "'#{value.to_s}'" - when Time, DateTime then "'#{value.strftime("%Y-%m-%d %H:%M:%S")}'" - else "'#{quote_string(value.to_yaml)}'" - end - end - - def quote_string(string) - string.gsub(/\'/, "''") - end - - def quoted_true - "1" - end - - def quoted_false - "0" - end - - def quote_column_name(name) - "[#{name}]" - end - - def add_limit_offset!(sql, options) - if options[:limit] and options[:offset] - total_rows = @connection.select_all("SELECT count(*) as TotalRows from (#{sql.gsub(/\bSELECT\b/i, "SELECT TOP 1000000000")}) tally")[0][:TotalRows].to_i - if (options[:limit] + options[:offset]) >= total_rows - options[:limit] = (total_rows - options[:offset] >= 0) ? (total_rows - options[:offset]) : 0 - end - sql.sub!(/^\s*SELECT/i, "SELECT * FROM (SELECT TOP #{options[:limit]} * FROM (SELECT TOP #{options[:limit] + options[:offset]} ") - sql << ") AS tmp1" - if options[:order] - options[:order] = options[:order].split(',').map do |field| - parts = field.split(" ") - tc = parts[0] - if sql =~ /\.\[/ and tc =~ /\./ # if column quoting used in query - tc.gsub!(/\./, '\\.\\[') - tc << '\\]' - end - if sql =~ /#{tc} AS (t\d_r\d\d?)/ - parts[0] = $1 - end - parts.join(' ') - end.join(', ') - sql << " ORDER BY #{change_order_direction(options[:order])}) AS tmp2 ORDER BY #{options[:order]}" - else - sql << " ) AS tmp2" - end - elsif sql !~ /^\s*SELECT (@@|COUNT\()/i - sql.sub!(/^\s*SELECT/i, "SELECT TOP #{options[:limit]}") unless options[:limit].nil? - end - end - - def recreate_database(name) - drop_database(name) - create_database(name) - end - - def drop_database(name) - execute "DROP DATABASE #{name}" - end - - def create_database(name) - execute "CREATE DATABASE #{name}" - end - - def tables(name = nil) - execute("SELECT table_name from information_schema.tables WHERE table_type = 'BASE TABLE'", name).inject([]) do |tables, field| - table_name = field[0] - tables << table_name unless table_name == 'dtproperties' - tables - end - end - - def indexes(table_name, name = nil) - indexes = [] - execute("EXEC sp_helpindex #{table_name}", name).each do |index| - unique = index[1] =~ /unique/ - primary = index[1] =~ /primary key/ - if !primary - indexes << IndexDefinition.new(table_name, index[0], unique, index[2].split(", ")) - end - end - indexes - end - - def rename_table(name, new_name) - execute "EXEC sp_rename '#{name}', '#{new_name}'" - end - - def remove_column(table_name, column_name) - execute "ALTER TABLE #{table_name} DROP COLUMN #{column_name}" - end - - def rename_column(table, column, new_column_name) - execute "EXEC sp_rename '#{table}.#{column}', '#{new_column_name}'" - end - - def change_column(table_name, column_name, type, options = {}) #:nodoc: - sql_commands = ["ALTER TABLE #{table_name} ALTER COLUMN #{column_name} #{type_to_sql(type, options[:limit])}"] - if options[:default] - remove_default_constraint(table_name, column_name) - sql_commands << "ALTER TABLE #{table_name} ADD CONSTRAINT DF_#{table_name}_#{column_name} DEFAULT #{options[:default]} FOR #{column_name}" - end - sql_commands.each {|c| - execute(c) - } - end - - def remove_column(table_name, column_name) - remove_default_constraint(table_name, column_name) - execute "ALTER TABLE #{table_name} DROP COLUMN #{column_name}" - end - - def remove_default_constraint(table_name, column_name) - defaults = select "select def.name from sysobjects def, syscolumns col, sysobjects tab where col.cdefault = def.id and col.name = '#{column_name}' and tab.name = '#{table_name}' and col.id = tab.id" - defaults.each {|constraint| - execute "ALTER TABLE #{table_name} DROP CONSTRAINT #{constraint["name"]}" - } - end - - def remove_index(table_name, options = {}) - execute "DROP INDEX #{table_name}.#{index_name(table_name, options)}" - end - - def type_to_sql(type, limit = nil) #:nodoc: - native = native_database_types[type] - # if there's no :limit in the default type definition, assume that type doesn't support limits - limit = native[:limit] ? limit || native[:limit] : nil - column_type_sql = native[:name] - column_type_sql << "(#{limit})" if limit - column_type_sql - end - - private - def select(sql, name = nil) - rows = [] - repair_special_columns(sql) - log(sql, name) do - @connection.select_all(sql) do |row| - record = {} - row.column_names.each do |col| - record[col] = row[col] - record[col] = record[col].to_time if record[col].is_a? DBI::Timestamp - end - rows << record - end - end - rows - end - - def enable_identity_insert(table_name, enable = true) - if has_identity_column(table_name) - "SET IDENTITY_INSERT #{table_name} #{enable ? 'ON' : 'OFF'}" - end - end - - def get_table_name(sql) - if sql =~ /^\s*insert\s+into\s+([^\(\s]+)\s*|^\s*update\s+([^\(\s]+)\s*/i - $1 - elsif sql =~ /from\s+([^\(\s]+)\s*/i - $1 - else - nil - end - end - - def has_identity_column(table_name) - !get_identity_column(table_name).nil? - end - - def get_identity_column(table_name) - @table_columns = {} unless @table_columns - @table_columns[table_name] = columns(table_name) if @table_columns[table_name] == nil - @table_columns[table_name].each do |col| - return col.name if col.identity - end - - return nil - end - - def query_contains_identity_column(sql, col) - sql =~ /\[#{col}\]/ - end - - def change_order_direction(order) - case order - when /\bDESC\b/i then order.gsub(/\bDESC\b/i, "ASC") - when /\bASC\b/i then order.gsub(/\bASC\b/i, "DESC") - else String.new(order).split(',').join(' DESC,') + ' DESC' - end - end - - def get_special_columns(table_name) - special = [] - @table_columns ||= {} - @table_columns[table_name] ||= columns(table_name) - @table_columns[table_name].each do |col| - special << col.name if col.is_special - end - special - end - - def repair_special_columns(sql) - special_cols = get_special_columns(get_table_name(sql)) - for col in special_cols.to_a - sql.gsub!(Regexp.new(" #{col.to_s} = "), " #{col.to_s} LIKE ") - sql.gsub!(/ORDER BY #{col.to_s}/i, '') - end - sql - end - - end #class SQLServerAdapter < AbstractAdapter - end #module ConnectionAdapters -end #module ActiveRecord diff --git a/tracks/vendor/rails/activerecord/lib/active_record/deprecated_associations.rb b/tracks/vendor/rails/activerecord/lib/active_record/deprecated_associations.rb deleted file mode 100644 index 077ac1de..00000000 --- a/tracks/vendor/rails/activerecord/lib/active_record/deprecated_associations.rb +++ /dev/null @@ -1,90 +0,0 @@ -module ActiveRecord - module Associations # :nodoc: - module ClassMethods - def deprecated_collection_count_method(collection_name)# :nodoc: - module_eval <<-"end_eval", __FILE__, __LINE__ - def #{collection_name}_count(force_reload = false) - #{collection_name}.reload if force_reload - #{collection_name}.size - end - end_eval - end - - def deprecated_add_association_relation(association_name)# :nodoc: - module_eval <<-"end_eval", __FILE__, __LINE__ - def add_#{association_name}(*items) - #{association_name}.concat(items) - end - end_eval - end - - def deprecated_remove_association_relation(association_name)# :nodoc: - module_eval <<-"end_eval", __FILE__, __LINE__ - def remove_#{association_name}(*items) - #{association_name}.delete(items) - end - end_eval - end - - def deprecated_has_collection_method(collection_name)# :nodoc: - module_eval <<-"end_eval", __FILE__, __LINE__ - def has_#{collection_name}?(force_reload = false) - !#{collection_name}(force_reload).empty? - end - end_eval - end - - def deprecated_find_in_collection_method(collection_name)# :nodoc: - module_eval <<-"end_eval", __FILE__, __LINE__ - def find_in_#{collection_name}(association_id) - #{collection_name}.find(association_id) - end - end_eval - end - - def deprecated_find_all_in_collection_method(collection_name)# :nodoc: - module_eval <<-"end_eval", __FILE__, __LINE__ - def find_all_in_#{collection_name}(runtime_conditions = nil, orderings = nil, limit = nil, joins = nil) - #{collection_name}.find_all(runtime_conditions, orderings, limit, joins) - end - end_eval - end - - def deprecated_collection_create_method(collection_name)# :nodoc: - module_eval <<-"end_eval", __FILE__, __LINE__ - def create_in_#{collection_name}(attributes = {}) - #{collection_name}.create(attributes) - end - end_eval - end - - def deprecated_collection_build_method(collection_name)# :nodoc: - module_eval <<-"end_eval", __FILE__, __LINE__ - def build_to_#{collection_name}(attributes = {}) - #{collection_name}.build(attributes) - end - end_eval - end - - def deprecated_association_comparison_method(association_name, association_class_name) # :nodoc: - module_eval <<-"end_eval", __FILE__, __LINE__ - def #{association_name}?(comparison_object, force_reload = false) - if comparison_object.kind_of?(#{association_class_name}) - #{association_name}(force_reload) == comparison_object - else - raise "Comparison object is a #{association_class_name}, should have been \#{comparison_object.class.name}" - end - end - end_eval - end - - def deprecated_has_association_method(association_name) # :nodoc: - module_eval <<-"end_eval", __FILE__, __LINE__ - def has_#{association_name}?(force_reload = false) - !#{association_name}(force_reload).nil? - end - end_eval - end - end - end -end diff --git a/tracks/vendor/rails/activerecord/lib/active_record/deprecated_finders.rb b/tracks/vendor/rails/activerecord/lib/active_record/deprecated_finders.rb deleted file mode 100644 index 6f56bf55..00000000 --- a/tracks/vendor/rails/activerecord/lib/active_record/deprecated_finders.rb +++ /dev/null @@ -1,41 +0,0 @@ -module ActiveRecord - class Base - class << self - # This method is deprecated in favor of find with the :conditions option. - # - # Works like find, but the record matching +id+ must also meet the +conditions+. - # +RecordNotFound+ is raised if no record can be found matching the +id+ or meeting the condition. - # Example: - # Person.find_on_conditions 5, "first_name LIKE '%dav%' AND last_name = 'heinemeier'" - def find_on_conditions(ids, conditions) # :nodoc: - find(ids, :conditions => conditions) - end - - # This method is deprecated in favor of find(:first, options). - # - # Returns the object for the first record responding to the conditions in +conditions+, - # such as "group = 'master'". If more than one record is returned from the query, it's the first that'll - # be used to create the object. In such cases, it might be beneficial to also specify - # +orderings+, like "income DESC, name", to control exactly which record is to be used. Example: - # Employee.find_first "income > 50000", "income DESC, name" - def find_first(conditions = nil, orderings = nil, joins = nil) # :nodoc: - find(:first, :conditions => conditions, :order => orderings, :joins => joins) - end - - # This method is deprecated in favor of find(:all, options). - # - # Returns an array of all the objects that could be instantiated from the associated - # table in the database. The +conditions+ can be used to narrow the selection of objects (WHERE-part), - # such as by "color = 'red'", and arrangement of the selection can be done through +orderings+ (ORDER BY-part), - # such as by "last_name, first_name DESC". A maximum of returned objects and their offset can be specified in - # +limit+ with either just a single integer as the limit or as an array with the first element as the limit, - # the second as the offset. Examples: - # Project.find_all "category = 'accounts'", "last_accessed DESC", 15 - # Project.find_all ["category = ?", category_name], "created ASC", [15, 20] - def find_all(conditions = nil, orderings = nil, limit = nil, joins = nil) # :nodoc: - limit, offset = limit.is_a?(Array) ? limit : [ limit, nil ] - find(:all, :conditions => conditions, :order => orderings, :joins => joins, :limit => limit, :offset => offset) - end - end - end -end \ No newline at end of file diff --git a/tracks/vendor/rails/activerecord/lib/active_record/fixtures.rb b/tracks/vendor/rails/activerecord/lib/active_record/fixtures.rb deleted file mode 100644 index 2c3609aa..00000000 --- a/tracks/vendor/rails/activerecord/lib/active_record/fixtures.rb +++ /dev/null @@ -1,575 +0,0 @@ -require 'erb' -require 'yaml' -require 'csv' - -module YAML #:nodoc: - class Omap #:nodoc: - def keys; map { |k, v| k } end - def values; map { |k, v| v } end - end -end - -# Fixtures are a way of organizing data that you want to test against; in short, sample data. They come in 3 flavours: -# -# 1. YAML fixtures -# 2. CSV fixtures -# 3. Single-file fixtures -# -# = YAML fixtures -# -# This type of fixture is in YAML format and the preferred default. YAML is a file format which describes data structures -# in a non-verbose, humanly-readable format. It ships with Ruby 1.8.1+. -# -# Unlike single-file fixtures, YAML fixtures are stored in a single file per model, which are placed in the directory appointed -# by Test::Unit::TestCase.fixture_path=(path) (this is automatically configured for Rails, so you can just -# put your files in /test/fixtures/). The fixture file ends with the .yml file extension (Rails example: -# "/test/fixtures/web_sites.yml"). The format of a YAML fixture file looks like this: -# -# rubyonrails: -# id: 1 -# name: Ruby on Rails -# url: http://www.rubyonrails.org -# -# google: -# id: 2 -# name: Google -# url: http://www.google.com -# -# This YAML fixture file includes two fixtures. Each YAML fixture (ie. record) is given a name and is followed by an -# indented list of key/value pairs in the "key: value" format. Records are separated by a blank line for your viewing -# pleasure. -# -# Note that YAML fixtures are unordered. If you want ordered fixtures, use the omap YAML type. See http://yaml.org/type/omap.html -# for the specification. You will need ordered fixtures when you have foreign key constraints on keys in the same table. -# This is commonly needed for tree structures. Example: -# -# --- !omap -# - parent: -# id: 1 -# parent_id: NULL -# title: Parent -# - child: -# id: 2 -# parent_id: 1 -# title: Child -# -# = CSV fixtures -# -# Fixtures can also be kept in the Comma Separated Value format. Akin to YAML fixtures, CSV fixtures are stored -# in a single file, but instead end with the .csv file extension (Rails example: "/test/fixtures/web_sites.csv") -# -# The format of this type of fixture file is much more compact than the others, but also a little harder to read by us -# humans. The first line of the CSV file is a comma-separated list of field names. The rest of the file is then comprised -# of the actual data (1 per line). Here's an example: -# -# id, name, url -# 1, Ruby On Rails, http://www.rubyonrails.org -# 2, Google, http://www.google.com -# -# Should you have a piece of data with a comma character in it, you can place double quotes around that value. If you -# need to use a double quote character, you must escape it with another double quote. -# -# Another unique attribute of the CSV fixture is that it has *no* fixture name like the other two formats. Instead, the -# fixture names are automatically generated by deriving the class name of the fixture file and adding an incrementing -# number to the end. In our example, the 1st fixture would be called "web_site_1" and the 2nd one would be called -# "web_site_2". -# -# Most databases and spreadsheets support exporting to CSV format, so this is a great format for you to choose if you -# have existing data somewhere already. -# -# = Single-file fixtures -# -# This type of fixtures was the original format for Active Record that has since been deprecated in favor of the YAML and CSV formats. -# Fixtures for this format are created by placing text files in a sub-directory (with the name of the model) to the directory -# appointed by Test::Unit::TestCase.fixture_path=(path) (this is automatically configured for Rails, so you can just -# put your files in /test/fixtures// -- like /test/fixtures/web_sites/ for the WebSite -# model). -# -# Each text file placed in this directory represents a "record". Usually these types of fixtures are named without -# extensions, but if you are on a Windows machine, you might consider adding .txt as the extension. Here's what the -# above example might look like: -# -# web_sites/google -# web_sites/yahoo.txt -# web_sites/ruby-on-rails -# -# The file format of a standard fixture is simple. Each line is a property (or column in db speak) and has the syntax -# of "name => value". Here's an example of the ruby-on-rails fixture above: -# -# id => 1 -# name => Ruby on Rails -# url => http://www.rubyonrails.org -# -# = Using Fixtures -# -# Since fixtures are a testing construct, we use them in our unit and functional tests. There are two ways to use the -# fixtures, but first let's take a look at a sample unit test found: -# -# require 'web_site' -# -# class WebSiteTest < Test::Unit::TestCase -# def test_web_site_count -# assert_equal 2, WebSite.count -# end -# end -# -# As it stands, unless we pre-load the web_site table in our database with two records, this test will fail. Here's the -# easiest way to add fixtures to the database: -# -# ... -# class WebSiteTest < Test::Unit::TestCase -# fixtures :web_sites # add more by separating the symbols with commas -# ... -# -# By adding a "fixtures" method to the test case and passing it a list of symbols (only one is shown here tho), we trigger -# the testing environment to automatically load the appropriate fixtures into the database before each test. -# To ensure consistent data, the environment deletes the fixtures before running the load. -# -# In addition to being available in the database, the fixtures are also loaded into a hash stored in an instance variable -# of the test case. It is named after the symbol... so, in our example, there would be a hash available called -# @web_sites. This is where the "fixture name" comes into play. -# -# On top of that, each record is automatically "found" (using Model.find(id)) and placed in the instance variable of its name. -# So for the YAML fixtures, we'd get @rubyonrails and @google, which could be interrogated using regular Active Record semantics: -# -# # test if the object created from the fixture data has the same attributes as the data itself -# def test_find -# assert_equal @web_sites["rubyonrails"]["name"], @rubyonrails.name -# end -# -# As seen above, the data hash created from the YAML fixtures would have @web_sites["rubyonrails"]["url"] return -# "http://www.rubyonrails.org" and @web_sites["google"]["name"] would return "Google". The same fixtures, but loaded -# from a CSV fixture file, would be accessible via @web_sites["web_site_1"]["name"] == "Ruby on Rails" and have the individual -# fixtures available as instance variables @web_site_1 and @web_site_2. -# -# If you do not wish to use instantiated fixtures (usually for performance reasons) there are two options. -# -# - to completely disable instantiated fixtures: -# self.use_instantiated_fixtures = false -# -# - to keep the fixture instance (@web_sites) available, but do not automatically 'find' each instance: -# self.use_instantiated_fixtures = :no_instances -# -# Even if auto-instantiated fixtures are disabled, you can still access them -# by name via special dynamic methods. Each method has the same name as the -# model, and accepts the name of the fixture to instantiate: -# -# fixtures :web_sites -# -# def test_find -# assert_equal "Ruby on Rails", web_sites(:rubyonrails).name -# end -# -# = Dynamic fixtures with ERb -# -# Some times you don't care about the content of the fixtures as much as you care about the volume. In these cases, you can -# mix ERb in with your YAML or CSV fixtures to create a bunch of fixtures for load testing, like: -# -# <% for i in 1..1000 %> -# fix_<%= i %>: -# id: <%= i %> -# name: guy_<%= 1 %> -# <% end %> -# -# This will create 1000 very simple YAML fixtures. -# -# Using ERb, you can also inject dynamic values into your fixtures with inserts like <%= Date.today.strftime("%Y-%m-%d") %>. -# This is however a feature to be used with some caution. The point of fixtures are that they're stable units of predictable -# sample data. If you feel that you need to inject dynamic values, then perhaps you should reexamine whether your application -# is properly testable. Hence, dynamic values in fixtures are to be considered a code smell. -# -# = Transactional fixtures -# -# TestCases can use begin+rollback to isolate their changes to the database instead of having to delete+insert for every test case. -# They can also turn off auto-instantiation of fixture data since the feature is costly and often unused. -# -# class FooTest < Test::Unit::TestCase -# self.use_transactional_fixtures = true -# self.use_instantiated_fixtures = false -# -# fixtures :foos -# -# def test_godzilla -# assert !Foo.find(:all).empty? -# Foo.destroy_all -# assert Foo.find(:all).empty? -# end -# -# def test_godzilla_aftermath -# assert !Foo.find(:all).empty? -# end -# end -# -# If you preload your test database with all fixture data (probably in the Rakefile task) and use transactional fixtures, -# then you may omit all fixtures declarations in your test cases since all the data's already there and every case rolls back its changes. -# -# In order to use instantiated fixtures with preloaded data, set +self.pre_loaded_fixtures+ to true. This will provide -# access to fixture data for every table that has been loaded through fixtures (depending on the value of +use_instantiated_fixtures+) -# -# When *not* to use transactional fixtures: -# 1. You're testing whether a transaction works correctly. Nested transactions don't commit until all parent transactions commit, -# particularly, the fixtures transaction which is begun in setup and rolled back in teardown. Thus, you won't be able to verify -# the results of your transaction until Active Record supports nested transactions or savepoints (in progress.) -# 2. Your database does not support transactions. Every Active Record database supports transactions except MySQL MyISAM. -# Use InnoDB, MaxDB, or NDB instead. -class Fixtures < YAML::Omap - DEFAULT_FILTER_RE = /\.ya?ml$/ - - def self.instantiate_fixtures(object, table_name, fixtures, load_instances=true) - object.instance_variable_set "@#{table_name.to_s.gsub('.','_')}", fixtures - if load_instances - ActiveRecord::Base.silence do - fixtures.each do |name, fixture| - if model = fixture.find - object.instance_variable_set "@#{name}", model - end - end - end - end - end - - def self.instantiate_all_loaded_fixtures(object, load_instances=true) - all_loaded_fixtures.each do |table_name, fixtures| - Fixtures.instantiate_fixtures(object, table_name, fixtures, load_instances) - end - end - - cattr_accessor :all_loaded_fixtures - self.all_loaded_fixtures = {} - - def self.create_fixtures(fixtures_directory, *table_names) - table_names = table_names.flatten.map { |n| n.to_s } - connection = block_given? ? yield : ActiveRecord::Base.connection - - ActiveRecord::Base.silence do - fixtures_map = {} - fixtures = table_names.map do |table_name| - fixtures_map[table_name] = Fixtures.new(connection, File.split(table_name.to_s).last, File.join(fixtures_directory, table_name.to_s)) - end - all_loaded_fixtures.merge! fixtures_map - - connection.transaction do - fixtures.reverse.each { |fixture| fixture.delete_existing_fixtures } - fixtures.each { |fixture| fixture.insert_fixtures } - - # Cap primary key sequences to max(pk). - if connection.respond_to?(:reset_pk_sequence!) - table_names.each do |table_name| - connection.reset_pk_sequence!(table_name) - end - end - end - - return fixtures.size > 1 ? fixtures : fixtures.first - end - end - - - attr_reader :table_name - - def initialize(connection, table_name, fixture_path, file_filter = DEFAULT_FILTER_RE) - @connection, @table_name, @fixture_path, @file_filter = connection, table_name, fixture_path, file_filter - - @class_name = ActiveRecord::Base.pluralize_table_names ? @table_name.singularize.camelize : @table_name.camelize - @table_name = ActiveRecord::Base.table_name_prefix + @table_name + ActiveRecord::Base.table_name_suffix - read_fixture_files - end - - def delete_existing_fixtures - @connection.delete "DELETE FROM #{@table_name}", 'Fixture Delete' - end - - def insert_fixtures - values.each do |fixture| - @connection.execute "INSERT INTO #{@table_name} (#{fixture.key_list}) VALUES (#{fixture.value_list})", 'Fixture Insert' - end - end - - private - def read_fixture_files - if File.file?(yaml_file_path) - # YAML fixtures - begin - if yaml = YAML::load(erb_render(IO.read(yaml_file_path))) - yaml = yaml.value if yaml.respond_to?(:type_id) and yaml.respond_to?(:value) - yaml.each do |name, data| - self[name] = Fixture.new(data, @class_name) - end - end - rescue Exception=>boom - raise Fixture::FormatError, "a YAML error occured parsing #{yaml_file_path}. Please note that YAML must be consistently indented using spaces. Tabs are not allowed. Please have a look at http://www.yaml.org/faq.html\nThe exact error was:\n #{boom.class}: #{boom}" - end - elsif File.file?(csv_file_path) - # CSV fixtures - reader = CSV::Reader.create(erb_render(IO.read(csv_file_path))) - header = reader.shift - i = 0 - reader.each do |row| - data = {} - row.each_with_index { |cell, j| data[header[j].to_s.strip] = cell.to_s.strip } - self["#{Inflector::underscore(@class_name)}_#{i+=1}"]= Fixture.new(data, @class_name) - end - elsif File.file?(deprecated_yaml_file_path) - raise Fixture::FormatError, ".yml extension required: rename #{deprecated_yaml_file_path} to #{yaml_file_path}" - else - # Standard fixtures - Dir.entries(@fixture_path).each do |file| - path = File.join(@fixture_path, file) - if File.file?(path) and file !~ @file_filter - self[file] = Fixture.new(path, @class_name) - end - end - end - end - - def yaml_file_path - "#{@fixture_path}.yml" - end - - def deprecated_yaml_file_path - "#{@fixture_path}.yaml" - end - - def csv_file_path - @fixture_path + ".csv" - end - - def yaml_fixtures_key(path) - File.basename(@fixture_path).split(".").first - end - - def erb_render(fixture_content) - ERB.new(fixture_content).result - end -end - -class Fixture #:nodoc: - include Enumerable - class FixtureError < StandardError#:nodoc: - end - class FormatError < FixtureError#:nodoc: - end - - def initialize(fixture, class_name) - case fixture - when Hash, YAML::Omap - @fixture = fixture - when String - @fixture = read_fixture_file(fixture) - else - raise ArgumentError, "Bad fixture argument #{fixture.inspect}" - end - - @class_name = class_name - end - - def each - @fixture.each { |item| yield item } - end - - def [](key) - @fixture[key] - end - - def to_hash - @fixture - end - - def key_list - columns = @fixture.keys.collect{ |column_name| ActiveRecord::Base.connection.quote_column_name(column_name) } - columns.join(", ") - end - - def value_list - @fixture.values.map { |v| ActiveRecord::Base.connection.quote(v).gsub('\\n', "\n").gsub('\\r', "\r") }.join(", ") - end - - def find - if Object.const_defined?(@class_name) - klass = Object.const_get(@class_name) - klass.find(self[klass.primary_key]) - end - end - - private - def read_fixture_file(fixture_file_path) - IO.readlines(fixture_file_path).inject({}) do |fixture, line| - # Mercifully skip empty lines. - next if line =~ /^\s*$/ - - # Use the same regular expression for attributes as Active Record. - unless md = /^\s*([a-zA-Z][-_\w]*)\s*=>\s*(.+)\s*$/.match(line) - raise FormatError, "#{fixture_file_path}: fixture format error at '#{line}'. Expecting 'key => value'." - end - key, value = md.captures - - # Disallow duplicate keys to catch typos. - raise FormatError, "#{fixture_file_path}: duplicate '#{key}' in fixture." if fixture[key] - fixture[key] = value.strip - fixture - end - end -end - -module Test #:nodoc: - module Unit #:nodoc: - class TestCase #:nodoc: - cattr_accessor :fixture_path - class_inheritable_accessor :fixture_table_names - class_inheritable_accessor :use_transactional_fixtures - class_inheritable_accessor :use_instantiated_fixtures # true, false, or :no_instances - class_inheritable_accessor :pre_loaded_fixtures - - self.fixture_table_names = [] - self.use_transactional_fixtures = false - self.use_instantiated_fixtures = true - self.pre_loaded_fixtures = false - - @@already_loaded_fixtures = {} - - def self.fixtures(*table_names) - table_names = table_names.flatten.map { |n| n.to_s } - self.fixture_table_names |= table_names - require_fixture_classes(table_names) - setup_fixture_accessors(table_names) - end - - def self.require_fixture_classes(table_names=nil) - (table_names || fixture_table_names).each do |table_name| - file_name = table_name.to_s - file_name = file_name.singularize if ActiveRecord::Base.pluralize_table_names - begin - require file_name - rescue LoadError - # Let's hope the developer has included it himself - end - end - end - - def self.setup_fixture_accessors(table_names=nil) - (table_names || fixture_table_names).each do |table_name| - table_name = table_name.to_s.tr('.','_') - define_method(table_name) do |fixture, *optionals| - force_reload = optionals.shift - @fixture_cache[table_name] ||= Hash.new - @fixture_cache[table_name][fixture] = nil if force_reload - @fixture_cache[table_name][fixture] ||= @loaded_fixtures[table_name][fixture.to_s].find - end - end - end - - def self.uses_transaction(*methods) - @uses_transaction ||= [] - @uses_transaction.concat methods.map { |m| m.to_s } - end - - def self.uses_transaction?(method) - @uses_transaction && @uses_transaction.include?(method.to_s) - end - - def use_transactional_fixtures? - use_transactional_fixtures && - !self.class.uses_transaction?(method_name) - end - - def setup_with_fixtures - if pre_loaded_fixtures && !use_transactional_fixtures - raise RuntimeError, 'pre_loaded_fixtures requires use_transactional_fixtures' - end - - @fixture_cache = Hash.new - - # Load fixtures once and begin transaction. - if use_transactional_fixtures? - if @@already_loaded_fixtures[self.class] - @loaded_fixtures = @@already_loaded_fixtures[self.class] - else - load_fixtures - @@already_loaded_fixtures[self.class] = @loaded_fixtures - end - ActiveRecord::Base.lock_mutex - ActiveRecord::Base.connection.begin_db_transaction - - # Load fixtures for every test. - else - @@already_loaded_fixtures[self.class] = nil - load_fixtures - end - - # Instantiate fixtures for every test if requested. - instantiate_fixtures if use_instantiated_fixtures - end - - alias_method :setup, :setup_with_fixtures - - def teardown_with_fixtures - # Rollback changes. - if use_transactional_fixtures? - ActiveRecord::Base.connection.rollback_db_transaction - ActiveRecord::Base.unlock_mutex - end - ActiveRecord::Base.clear_connection_cache! - end - - alias_method :teardown, :teardown_with_fixtures - - def self.method_added(method) - case method.to_s - when 'setup' - unless method_defined?(:setup_without_fixtures) - alias_method :setup_without_fixtures, :setup - define_method(:setup) do - setup_with_fixtures - setup_without_fixtures - end - end - when 'teardown' - unless method_defined?(:teardown_without_fixtures) - alias_method :teardown_without_fixtures, :teardown - define_method(:teardown) do - teardown_without_fixtures - teardown_with_fixtures - end - end - end - end - - private - def load_fixtures - @loaded_fixtures = {} - fixtures = Fixtures.create_fixtures(fixture_path, fixture_table_names) - unless fixtures.nil? - if fixtures.instance_of?(Fixtures) - @loaded_fixtures[fixtures.table_name] = fixtures - else - fixtures.each { |f| @loaded_fixtures[f.table_name] = f } - end - end - end - - # for pre_loaded_fixtures, only require the classes once. huge speed improvement - @@required_fixture_classes = false - - def instantiate_fixtures - if pre_loaded_fixtures - raise RuntimeError, 'Load fixtures before instantiating them.' if Fixtures.all_loaded_fixtures.empty? - unless @@required_fixture_classes - self.class.require_fixture_classes Fixtures.all_loaded_fixtures.keys - @@required_fixture_classes = true - end - Fixtures.instantiate_all_loaded_fixtures(self, load_instances?) - else - raise RuntimeError, 'Load fixtures before instantiating them.' if @loaded_fixtures.nil? - @loaded_fixtures.each do |table_name, fixtures| - Fixtures.instantiate_fixtures(self, table_name, fixtures, load_instances?) - end - end - end - - def load_instances? - use_instantiated_fixtures != :no_instances - end - end - - end -end diff --git a/tracks/vendor/rails/activerecord/lib/active_record/locking.rb b/tracks/vendor/rails/activerecord/lib/active_record/locking.rb deleted file mode 100644 index 71a4666e..00000000 --- a/tracks/vendor/rails/activerecord/lib/active_record/locking.rb +++ /dev/null @@ -1,58 +0,0 @@ -module ActiveRecord - # Active Records support optimistic locking if the field lock_version is present. Each update to the - # record increments the lock_version column and the locking facilities ensure that records instantiated twice - # will let the last one saved raise a StaleObjectError if the first was also updated. Example: - # - # p1 = Person.find(1) - # p2 = Person.find(1) - # - # p1.first_name = "Michael" - # p1.save - # - # p2.first_name = "should fail" - # p2.save # Raises a ActiveRecord::StaleObjectError - # - # You're then responsible for dealing with the conflict by rescuing the exception and either rolling back, merging, - # or otherwise apply the business logic needed to resolve the conflict. - # - # You must ensure that your database schema defaults the lock_version column to 0. - # - # This behavior can be turned off by setting ActiveRecord::Base.lock_optimistically = false. - module Locking - def self.append_features(base) #:nodoc: - super - base.class_eval do - alias_method :update_without_lock, :update - alias_method :update, :update_with_lock - end - end - - def update_with_lock #:nodoc: - if locking_enabled? - previous_value = self.lock_version - self.lock_version = previous_value + 1 - - affected_rows = connection.update(<<-end_sql, "#{self.class.name} Update with optimistic locking") - UPDATE #{self.class.table_name} - SET #{quoted_comma_pair_list(connection, attributes_with_quotes(false))} - WHERE #{self.class.primary_key} = #{quote(id)} AND lock_version = #{quote(previous_value)} - end_sql - - unless affected_rows == 1 - raise ActiveRecord::StaleObjectError, "Attempted to update a stale object" - end - else - update_without_lock - end - end - end - - class Base - @@lock_optimistically = true - cattr_accessor :lock_optimistically - - def locking_enabled? #:nodoc: - lock_optimistically && respond_to?(:lock_version) - end - end -end diff --git a/tracks/vendor/rails/activerecord/lib/active_record/migration.rb b/tracks/vendor/rails/activerecord/lib/active_record/migration.rb deleted file mode 100644 index 71994dc6..00000000 --- a/tracks/vendor/rails/activerecord/lib/active_record/migration.rb +++ /dev/null @@ -1,286 +0,0 @@ -module ActiveRecord - class IrreversibleMigration < ActiveRecordError#:nodoc: - end - - class DuplicateMigrationVersionError < ActiveRecordError#:nodoc: - def initialize(version) - super("Multiple migrations have the version number #{version}") - end - end - - # Migrations can manage the evolution of a schema used by several physical databases. It's a solution - # to the common problem of adding a field to make a new feature work in your local database, but being unsure of how to - # push that change to other developers and to the production server. With migrations, you can describe the transformations - # in self-contained classes that can be checked into version control systems and executed against another database that - # might be one, two, or five versions behind. - # - # Example of a simple migration: - # - # class AddSsl < ActiveRecord::Migration - # def self.up - # add_column :accounts, :ssl_enabled, :boolean, :default => 1 - # end - # - # def self.down - # remove_column :accounts, :ssl_enabled - # end - # end - # - # This migration will add a boolean flag to the accounts table and remove it again, if you're backing out of the migration. - # It shows how all migrations have two class methods +up+ and +down+ that describes the transformations required to implement - # or remove the migration. These methods can consist of both the migration specific methods, like add_column and remove_column, - # but may also contain regular Ruby code for generating data needed for the transformations. - # - # Example of a more complex migration that also needs to initialize data: - # - # class AddSystemSettings < ActiveRecord::Migration - # def self.up - # create_table :system_settings do |t| - # t.column :name, :string - # t.column :label, :string - # t.column :value, :text - # t.column :type, :string - # t.column :position, :integer - # end - # - # SystemSetting.create :name => "notice", :label => "Use notice?", :value => 1 - # end - # - # def self.down - # drop_table :system_settings - # end - # end - # - # This migration first adds the system_settings table, then creates the very first row in it using the Active Record model - # that relies on the table. It also uses the more advanced create_table syntax where you can specify a complete table schema - # in one block call. - # - # == Available transformations - # - # * create_table(name, options) Creates a table called +name+ and makes the table object available to a block - # that can then add columns to it, following the same format as add_column. See example above. The options hash is for - # fragments like "DEFAULT CHARSET=UTF-8" that are appended to the create table definition. - # * drop_table(name): Drops the table called +name+. - # * add_column(table_name, column_name, type, options): Adds a new column to the table called +table_name+ - # named +column_name+ specified to be one of the following types: - # :string, :text, :integer, :float, :datetime, :timestamp, :time, :date, :binary, :boolean. A default value can be specified - # by passing an +options+ hash like { :default => 11 }. - # * rename_column(table_name, column_name, new_column_name): Renames a column but keeps the type and content. - # * change_column(table_name, column_name, type, options): Changes the column to a different type using the same - # parameters as add_column. - # * remove_column(table_name, column_name): Removes the column named +column_name+ from the table called +table_name+. - # * add_index(table_name, column_name, index_type): Add a new index with the name of the column on the column. Specify an optional index_type (e.g. UNIQUE). - # * remove_index(table_name, column_name): Remove the index called the same as the column. - # - # == Irreversible transformations - # - # Some transformations are destructive in a manner that cannot be reversed. Migrations of that kind should raise - # an IrreversibleMigration exception in their +down+ method. - # - # == Running migrations from within Rails - # - # The Rails package has several tools to help create and apply migrations. - # - # To generate a new migration, use script/generate migration MyNewMigration - # where MyNewMigration is the name of your migration. The generator will - # create a file nnn_my_new_migration.rb in the db/migrate/ - # directory, where nnn is the next largest migration number. - # You may then edit the self.up and self.down methods of - # n MyNewMigration. - # - # To run migrations against the currently configured database, use - # rake migrate. This will update the database by running all of the - # pending migrations, creating the schema_info table if missing. - # - # To roll the database back to a previous migration version, use - # rake migrate version=X where X is the version to which - # you wish to downgrade. If any of the migrations throw an - # IrreversibleMigration exception, that step will fail and you'll - # have some manual work to do. - # - # == Database support - # - # Migrations are currently supported in MySQL, PostgreSQL, SQLite, - # SQL Server, and Oracle (all supported databases except DB2). - # - # == More examples - # - # Not all migrations change the schema. Some just fix the data: - # - # class RemoveEmptyTags < ActiveRecord::Migration - # def self.up - # Tag.find(:all).each { |tag| tag.destroy if tag.pages.empty? } - # end - # - # def self.down - # # not much we can do to restore deleted data - # raise IrreversibleMigration - # end - # end - # - # Others remove columns when they migrate up instead of down: - # - # class RemoveUnnecessaryItemAttributes < ActiveRecord::Migration - # def self.up - # remove_column :items, :incomplete_items_count - # remove_column :items, :completed_items_count - # end - # - # def self.down - # add_column :items, :incomplete_items_count - # add_column :items, :completed_items_count - # end - # end - # - # And sometimes you need to do something in SQL not abstracted directly by migrations: - # - # class MakeJoinUnique < ActiveRecord::Migration - # def self.up - # execute "ALTER TABLE `pages_linked_pages` ADD UNIQUE `page_id_linked_page_id` (`page_id`,`linked_page_id`)" - # end - # - # def self.down - # execute "ALTER TABLE `pages_linked_pages` DROP INDEX `page_id_linked_page_id`" - # end - # end - # - # == Using a model after changing its table - # - # Sometimes you'll want to add a column in a migration and populate it immediately after. In that case, you'll need - # to make a call to Base#reset_column_information in order to ensure that the model has the latest column data from - # after the new column was added. Example: - # - # class AddPeopleSalary < ActiveRecord::Migration - # def self.up - # add_column :people, :salary, :integer - # Person.reset_column_information - # Person.find(:all).each do |p| - # p.salary = SalaryCalculator.compute(p) - # end - # end - # end - class Migration - class << self - def up() end - def down() end - - private - def method_missing(method, *arguments, &block) - arguments[0] = Migrator.proper_table_name(arguments.first) unless arguments.empty? - ActiveRecord::Base.connection.send(method, *arguments, &block) - end - end - end - - class Migrator#:nodoc: - class << self - def migrate(migrations_path, target_version = nil) - Base.connection.initialize_schema_information - case - when target_version.nil?, current_version < target_version - up(migrations_path, target_version) - when current_version > target_version - down(migrations_path, target_version) - when current_version == target_version - return # You're on the right version - end - end - - def up(migrations_path, target_version = nil) - self.new(:up, migrations_path, target_version).migrate - end - - def down(migrations_path, target_version = nil) - self.new(:down, migrations_path, target_version).migrate - end - - def schema_info_table_name - Base.table_name_prefix + "schema_info" + Base.table_name_suffix - end - - def current_version - (Base.connection.select_one("SELECT version FROM #{schema_info_table_name}") || {"version" => 0})["version"].to_i - end - - def proper_table_name(name) - # Use the ActiveRecord objects own table_name, or pre/suffix from ActiveRecord::Base if name is a symbol/string - name.table_name rescue "#{ActiveRecord::Base.table_name_prefix}#{name}#{ActiveRecord::Base.table_name_suffix}" - end - - end - - def initialize(direction, migrations_path, target_version = nil) - raise StandardError.new("This database does not yet support migrations") unless Base.connection.supports_migrations? - @direction, @migrations_path, @target_version = direction, migrations_path, target_version - Base.connection.initialize_schema_information - end - - def current_version - self.class.current_version - end - - def migrate - migration_classes.each do |(version, migration_class)| - Base.logger.info("Reached target version: #{@target_version}") and break if reached_target_version?(version) - next if irrelevant_migration?(version) - - Base.logger.info "Migrating to #{migration_class} (#{version})" - migration_class.send(@direction) - set_schema_version(version) - end - end - - private - def migration_classes - migrations = migration_files.inject([]) do |migrations, migration_file| - load(migration_file) - version, name = migration_version_and_name(migration_file) - assert_unique_migration_version(migrations, version.to_i) - migrations << [ version.to_i, migration_class(name) ] - end - - down? ? migrations.sort.reverse : migrations.sort - end - - def assert_unique_migration_version(migrations, version) - if !migrations.empty? && migrations.transpose.first.include?(version) - raise DuplicateMigrationVersionError.new(version) - end - end - - def migration_files - files = Dir["#{@migrations_path}/[0-9]*_*.rb"].sort_by do |f| - migration_version_and_name(f).first.to_i - end - down? ? files.reverse : files - end - - def migration_class(migration_name) - migration_name.camelize.constantize - end - - def migration_version_and_name(migration_file) - return *migration_file.scan(/([0-9]+)_([_a-z0-9]*).rb/).first - end - - def set_schema_version(version) - Base.connection.update("UPDATE #{self.class.schema_info_table_name} SET version = #{down? ? version.to_i - 1 : version.to_i}") - end - - def up? - @direction == :up - end - - def down? - @direction == :down - end - - def reached_target_version?(version) - (up? && version.to_i - 1 == @target_version) || (down? && version.to_i == @target_version) - end - - def irrelevant_migration?(version) - (up? && version.to_i <= current_version) || (down? && version.to_i > current_version) - end - end -end diff --git a/tracks/vendor/rails/activerecord/lib/active_record/observer.rb b/tracks/vendor/rails/activerecord/lib/active_record/observer.rb deleted file mode 100644 index 7d33509c..00000000 --- a/tracks/vendor/rails/activerecord/lib/active_record/observer.rb +++ /dev/null @@ -1,115 +0,0 @@ -require 'singleton' - -module ActiveRecord - module Observing # :nodoc: - def self.append_features(base) - super - base.extend(ClassMethods) - end - - module ClassMethods - # Activates the observers assigned. Examples: - # - # # Calls PersonObserver.instance - # ActiveRecord::Base.observers = :person_observer - # - # # Calls Cacher.instance and GarbageCollector.instance - # ActiveRecord::Base.observers = :cacher, :garbage_collector - # - # # Same as above, just using explicit class references - # ActiveRecord::Base.observers = Cacher, GarbageCollector - def observers=(*observers) - observers = [ observers ].flatten.each do |observer| - observer.is_a?(Symbol) ? - observer.to_s.camelize.constantize.instance : - observer.instance - end - end - end - end - - # Observer classes respond to lifecycle callbacks to implement trigger-like - # behavior outside the original class. This is a great way to reduce the - # clutter that normally comes when the model class is burdened with - # functionality that doesn't pertain to the core responsibility of the - # class. Example: - # - # class CommentObserver < ActiveRecord::Observer - # def after_save(comment) - # Notifications.deliver_comment("admin@do.com", "New comment was posted", comment) - # end - # end - # - # This Observer sends an email when a Comment#save is finished. - # - # == Observing a class that can't be inferred - # - # Observers will by default be mapped to the class with which they share a name. So CommentObserver will - # be tied to observing Comment, ProductManagerObserver to ProductManager, and so on. If you want to name your observer - # differently than the class you're interested in observing, you can use the Observer.observe class method: - # - # class AuditObserver < ActiveRecord::Observer - # observe Account - # - # def after_update(account) - # AuditTrail.new(account, "UPDATED") - # end - # end - # - # If the audit observer needs to watch more than one kind of object, this can be specified with multiple arguments: - # - # class AuditObserver < ActiveRecord::Observer - # observe Account, Balance - # - # def after_update(record) - # AuditTrail.new(record, "UPDATED") - # end - # end - # - # The AuditObserver will now act on both updates to Account and Balance by treating them both as records. - # - # == Available callback methods - # - # The observer can implement callback methods for each of the methods described in the Callbacks module. - # - # == Triggering Observers - # - # In order to activate an observer, list it in the config.active_record.observers configuration setting in your - # config/environment.rb file. - # - # config.active_record.observers = :comment_observer, :signup_observer - class Observer - include Singleton - - # Attaches the observer to the supplied model classes. - def self.observe(*models) - define_method(:observed_class) { models } - end - - def initialize - observed_classes = [ observed_class ].flatten - observed_subclasses_class = observed_classes.collect {|c| c.send(:subclasses) }.flatten! - (observed_classes + observed_subclasses_class).each do |klass| - klass.add_observer(self) - klass.send(:define_method, :after_find) unless klass.respond_to?(:after_find) - end - end - - def update(callback_method, object) #:nodoc: - send(callback_method, object) if respond_to?(callback_method) - end - - private - def observed_class - if self.class.respond_to? "observed_class" - self.class.observed_class - else - Object.const_get(infer_observed_class_name) - end - end - - def infer_observed_class_name - self.class.name.scan(/(.*)Observer/)[0][0] - end - end -end diff --git a/tracks/vendor/rails/activerecord/lib/active_record/query_cache.rb b/tracks/vendor/rails/activerecord/lib/active_record/query_cache.rb deleted file mode 100644 index e79b3e05..00000000 --- a/tracks/vendor/rails/activerecord/lib/active_record/query_cache.rb +++ /dev/null @@ -1,64 +0,0 @@ -module ActiveRecord - class QueryCache #:nodoc: - def initialize(connection) - @connection = connection - @query_cache = {} - end - - def clear_query_cache - @query_cache = {} - end - - def select_all(sql, name = nil) - (@query_cache[sql] ||= @connection.select_all(sql, name)).dup - end - - def select_one(sql, name = nil) - @query_cache[sql] ||= @connection.select_one(sql, name) - end - - def columns(table_name, name = nil) - @query_cache["SHOW FIELDS FROM #{table_name}"] ||= @connection.columns(table_name, name) - end - - def insert(sql, name = nil, pk = nil, id_value = nil) - clear_query_cache - @connection.insert(sql, name, pk, id_value) - end - - def update(sql, name = nil) - clear_query_cache - @connection.update(sql, name) - end - - def delete(sql, name = nil) - clear_query_cache - @connection.delete(sql, name) - end - - private - def method_missing(method, *arguments, &proc) - @connection.send(method, *arguments, &proc) - end - end - - class Base - # Set the connection for the class with caching on - class << self - alias_method :connection_without_query_cache=, :connection= - - def connection=(spec) - if spec.is_a?(ConnectionSpecification) and spec.config[:query_cache] - spec = QueryCache.new(self.send(spec.adapter_method, spec.config)) - end - self.connection_without_query_cache = spec - end - end - end - - class AbstractAdapter #:nodoc: - # Stub method to be able to treat the connection the same whether the query cache has been turned on or not - def clear_query_cache - end - end -end diff --git a/tracks/vendor/rails/activerecord/lib/active_record/reflection.rb b/tracks/vendor/rails/activerecord/lib/active_record/reflection.rb deleted file mode 100644 index affbb65c..00000000 --- a/tracks/vendor/rails/activerecord/lib/active_record/reflection.rb +++ /dev/null @@ -1,138 +0,0 @@ -module ActiveRecord - module Reflection # :nodoc: - def self.append_features(base) - super - base.extend(ClassMethods) - - base.class_eval do - class << self - alias_method :composed_of_without_reflection, :composed_of - - def composed_of_with_reflection(part_id, options = {}) - composed_of_without_reflection(part_id, options) - reflect_on_all_aggregations << AggregateReflection.new(:composed_of, part_id, options, self) - end - - alias_method :composed_of, :composed_of_with_reflection - end - end - - for association_type in %w( belongs_to has_one has_many has_and_belongs_to_many ) - base.module_eval <<-"end_eval" - class << self - alias_method :#{association_type}_without_reflection, :#{association_type} - - def #{association_type}_with_reflection(association_id, options = {}, &block) - #{association_type}_without_reflection(association_id, options, &block) - reflect_on_all_associations << AssociationReflection.new(:#{association_type}, association_id, options, self) - end - - alias_method :#{association_type}, :#{association_type}_with_reflection - end - end_eval - end - end - - # Reflection allows you to interrogate Active Record classes and objects about their associations and aggregations. - # This information can, for example, be used in a form builder that took an Active Record object and created input - # fields for all of the attributes depending on their type and displayed the associations to other objects. - # - # You can find the interface for the AggregateReflection and AssociationReflection classes in the abstract MacroReflection class. - module ClassMethods - # Returns an array of AggregateReflection objects for all the aggregations in the class. - def reflect_on_all_aggregations - read_inheritable_attribute(:aggregations) or write_inheritable_attribute(:aggregations, []) - end - - # Returns the AggregateReflection object for the named +aggregation+ (use the symbol). Example: - # Account.reflect_on_aggregation(:balance) # returns the balance AggregateReflection - def reflect_on_aggregation(aggregation) - reflect_on_all_aggregations.find { |reflection| reflection.name == aggregation } unless reflect_on_all_aggregations.nil? - end - - # Returns an array of AssociationReflection objects for all the aggregations in the class. - def reflect_on_all_associations - read_inheritable_attribute(:associations) or write_inheritable_attribute(:associations, []) - end - - # Returns the AssociationReflection object for the named +aggregation+ (use the symbol). Example: - # Account.reflect_on_association(:owner) # returns the owner AssociationReflection - def reflect_on_association(association) - reflect_on_all_associations.find { |reflection| reflection.name == association } - end - end - - - # Abstract base class for AggregateReflection and AssociationReflection that describes the interface available for both of - # those classes. Objects of AggregateReflection and AssociationReflection are returned by the Reflection::ClassMethods. - class MacroReflection - attr_reader :active_record - def initialize(macro, name, options, active_record) - @macro, @name, @options, @active_record = macro, name, options, active_record - end - - # Returns the name of the macro, so it would return :balance for "composed_of :balance, :class_name => 'Money'" or - # :clients for "has_many :clients". - def name - @name - end - - # Returns the name of the macro, so it would return :composed_of for - # "composed_of :balance, :class_name => 'Money'" or :has_many for "has_many :clients". - def macro - @macro - end - - # Returns the hash of options used for the macro, so it would return { :class_name => "Money" } for - # "composed_of :balance, :class_name => 'Money'" or {} for "has_many :clients". - def options - @options - end - - # Returns the class for the macro, so "composed_of :balance, :class_name => 'Money'" would return the Money class and - # "has_many :clients" would return the Client class. - def klass() end - - def ==(other_aggregation) - name == other_aggregation.name && other_aggregation.options && active_record == other_aggregation.active_record - end - end - - - # Holds all the meta-data about an aggregation as it was specified in the Active Record class. - class AggregateReflection < MacroReflection #:nodoc: - def klass - Object.const_get(options[:class_name] || name_to_class_name(name.id2name)) - end - - private - def name_to_class_name(name) - name.capitalize.gsub(/_(.)/) { |s| $1.capitalize } - end - end - - # Holds all the meta-data about an association as it was specified in the Active Record class. - class AssociationReflection < MacroReflection #:nodoc: - def klass - @klass ||= active_record.send(:compute_type, (name_to_class_name(name.id2name))) - end - - def table_name - @table_name ||= klass.table_name - end - - private - def name_to_class_name(name) - if name =~ /::/ - name - else - unless class_name = options[:class_name] - class_name = name.to_s.camelize - class_name = class_name.singularize if [:has_many, :has_and_belongs_to_many].include?(macro) - end - active_record.send(:type_name_with_module, class_name) - end - end - end - end -end diff --git a/tracks/vendor/rails/activerecord/lib/active_record/schema.rb b/tracks/vendor/rails/activerecord/lib/active_record/schema.rb deleted file mode 100644 index c9863808..00000000 --- a/tracks/vendor/rails/activerecord/lib/active_record/schema.rb +++ /dev/null @@ -1,58 +0,0 @@ -module ActiveRecord - # Allows programmers to programmatically define a schema in a portable - # DSL. This means you can define tables, indexes, etc. without using SQL - # directly, so your applications can more easily support multiple - # databases. - # - # Usage: - # - # ActiveRecord::Schema.define do - # create_table :authors do |t| - # t.column :name, :string, :null => false - # end - # - # add_index :authors, :name, :unique - # - # create_table :posts do |t| - # t.column :author_id, :integer, :null => false - # t.column :subject, :string - # t.column :body, :text - # t.column :private, :boolean, :default => false - # end - # - # add_index :posts, :author_id - # end - # - # ActiveRecord::Schema is only supported by database adapters that also - # support migrations, the two features being very similar. - class Schema < Migration - private_class_method :new - - # Eval the given block. All methods available to the current connection - # adapter are available within the block, so you can easily use the - # database definition DSL to build up your schema (#create_table, - # #add_index, etc.). - # - # The +info+ hash is optional, and if given is used to define metadata - # about the current schema (like the schema's version): - # - # ActiveRecord::Schema.define(:version => 15) do - # ... - # end - def self.define(info={}, &block) - instance_eval(&block) - - unless info.empty? - initialize_schema_information - cols = columns('schema_info') - - info = info.map do |k,v| - v = quote(v, cols.detect { |c| c.name == k.to_s }) - "#{k} = #{v}" - end - - update "UPDATE schema_info SET #{info.join(", ")}" - end - end - end -end diff --git a/tracks/vendor/rails/activerecord/lib/active_record/schema_dumper.rb b/tracks/vendor/rails/activerecord/lib/active_record/schema_dumper.rb deleted file mode 100644 index cd6a665a..00000000 --- a/tracks/vendor/rails/activerecord/lib/active_record/schema_dumper.rb +++ /dev/null @@ -1,84 +0,0 @@ -module ActiveRecord - # This class is used to dump the database schema for some connection to some - # output format (i.e., ActiveRecord::Schema). - class SchemaDumper #:nodoc: - private_class_method :new - - def self.dump(connection=ActiveRecord::Base.connection, stream=STDOUT) - new(connection).dump(stream) - stream - end - - def dump(stream) - header(stream) - tables(stream) - trailer(stream) - stream - end - - private - - def initialize(connection) - @connection = connection - @types = @connection.native_database_types - @info = @connection.select_one("SELECT * FROM schema_info") rescue nil - end - - def header(stream) - define_params = @info ? ":version => #{@info['version']}" : "" - - stream.puts <
    false" if !columns.detect { |c| c.name == "id" } - stream.print ", :force => true" - stream.puts " do |t|" - - columns.each do |column| - next if column.name == "id" - stream.print " t.column #{column.name.inspect}, #{column.type.inspect}" - stream.print ", :limit => #{column.limit.inspect}" if column.limit != @types[column.type][:limit] - stream.print ", :default => #{column.default.inspect}" if !column.default.nil? - stream.print ", :null => false" if !column.null - stream.puts - end - - stream.puts " end" - stream.puts - - indexes(table, stream) - end - - def indexes(table, stream) - indexes = @connection.indexes(table) - indexes.each do |index| - stream.print " add_index #{index.table.inspect}, #{index.columns.inspect}, :name => #{index.name.inspect}" - stream.print ", :unique => true" if index.unique - stream.puts - end - stream.puts unless indexes.empty? - end - end -end diff --git a/tracks/vendor/rails/activerecord/lib/active_record/timestamp.rb b/tracks/vendor/rails/activerecord/lib/active_record/timestamp.rb deleted file mode 100644 index eb82728a..00000000 --- a/tracks/vendor/rails/activerecord/lib/active_record/timestamp.rb +++ /dev/null @@ -1,62 +0,0 @@ -module ActiveRecord - # Active Records will automatically record creation and/or update timestamps of database objects - # if fields of the names created_at/created_on or updated_at/updated_on are present. This module is - # automatically included, so you don't need to do that manually. - # - # This behavior can be turned off by setting ActiveRecord::Base.record_timestamps = false. - # This behavior can use GMT by setting ActiveRecord::Base.timestamps_gmt = true - module Timestamp - def self.append_features(base) # :nodoc: - super - - base.class_eval do - alias_method :create_without_timestamps, :create - alias_method :create, :create_with_timestamps - - alias_method :update_without_timestamps, :update - alias_method :update, :update_with_timestamps - end - end - - def create_with_timestamps #:nodoc: - if record_timestamps - t = ( self.class.default_timezone == :utc ? Time.now.utc : Time.now ) - write_attribute('created_at', t) if respond_to?(:created_at) && created_at.nil? - write_attribute('created_on', t) if respond_to?(:created_on) && created_on.nil? - - write_attribute('updated_at', t) if respond_to?(:updated_at) - write_attribute('updated_on', t) if respond_to?(:updated_on) - end - create_without_timestamps - end - - def update_with_timestamps #:nodoc: - if record_timestamps - t = ( self.class.default_timezone == :utc ? Time.now.utc : Time.now ) - write_attribute('updated_at', t) if respond_to?(:updated_at) - write_attribute('updated_on', t) if respond_to?(:updated_on) - end - update_without_timestamps - end - end - - class Base - # Records the creation date and possibly time in created_on (date only) or created_at (date and time) and the update date and possibly - # time in updated_on and updated_at. This only happens if the object responds to either of these messages, which they will do automatically - # if the table has columns of either of these names. This feature is turned on by default. - @@record_timestamps = true - cattr_accessor :record_timestamps - - # deprecated: use ActiveRecord::Base.default_timezone instead. - @@timestamps_gmt = false - def self.timestamps_gmt=( gmt ) #:nodoc: - warn "timestamps_gmt= is deprecated. use default_timezone= instead" - self.default_timezone = ( gmt ? :utc : :local ) - end - - def self.timestamps_gmt #:nodoc: - warn "timestamps_gmt is deprecated. use default_timezone instead" - self.default_timezone == :utc - end - end -end diff --git a/tracks/vendor/rails/activerecord/lib/active_record/transactions.rb b/tracks/vendor/rails/activerecord/lib/active_record/transactions.rb deleted file mode 100644 index 2c5692c0..00000000 --- a/tracks/vendor/rails/activerecord/lib/active_record/transactions.rb +++ /dev/null @@ -1,129 +0,0 @@ -require 'active_record/vendor/simple.rb' -Transaction::Simple.send(:remove_method, :transaction) -require 'thread' - -module ActiveRecord - module Transactions # :nodoc: - TRANSACTION_MUTEX = Mutex.new - - class TransactionError < ActiveRecordError # :nodoc: - end - - def self.append_features(base) - super - base.extend(ClassMethods) - - base.class_eval do - alias_method :destroy_without_transactions, :destroy - alias_method :destroy, :destroy_with_transactions - - alias_method :save_without_transactions, :save - alias_method :save, :save_with_transactions - end - end - - # Transactions are protective blocks where SQL statements are only permanent if they can all succeed as one atomic action. - # The classic example is a transfer between two accounts where you can only have a deposit if the withdrawal succeeded and - # vice versa. Transactions enforce the integrity of the database and guard the data against program errors or database break-downs. - # So basically you should use transaction blocks whenever you have a number of statements that must be executed together or - # not at all. Example: - # - # transaction do - # david.withdrawal(100) - # mary.deposit(100) - # end - # - # This example will only take money from David and give to Mary if neither +withdrawal+ nor +deposit+ raises an exception. - # Exceptions will force a ROLLBACK that returns the database to the state before the transaction was begun. Be aware, though, - # that the objects by default will _not_ have their instance data returned to their pre-transactional state. - # - # == Transactions are not distributed across database connections - # - # A transaction acts on a single database connection. If you have - # multiple class-specific databases, the transaction will not protect - # interaction among them. One workaround is to begin a transaction - # on each class whose models you alter: - # - # Student.transaction do - # Course.transaction do - # course.enroll(student) - # student.units += course.units - # end - # end - # - # This is a poor solution, but full distributed transactions are beyond - # the scope of Active Record. - # - # == Save and destroy are automatically wrapped in a transaction - # - # Both Base#save and Base#destroy come wrapped in a transaction that ensures that whatever you do in validations or callbacks - # will happen under the protected cover of a transaction. So you can use validations to check for values that the transaction - # depend on or you can raise exceptions in the callbacks to rollback. - # - # == Object-level transactions - # - # You can enable object-level transactions for Active Record objects, though. You do this by naming each of the Active Records - # that you want to enable object-level transactions for, like this: - # - # Account.transaction(david, mary) do - # david.withdrawal(100) - # mary.deposit(100) - # end - # - # If the transaction fails, David and Mary will be returned to their pre-transactional state. No money will have changed hands in - # neither object nor database. - # - # == Exception handling - # - # Also have in mind that exceptions thrown within a transaction block will be propagated (after triggering the ROLLBACK), so you - # should be ready to catch those in your application code. - # - # Tribute: Object-level transactions are implemented by Transaction::Simple by Austin Ziegler. - module ClassMethods - def transaction(*objects, &block) - previous_handler = trap('TERM') { raise TransactionError, "Transaction aborted" } - lock_mutex - - begin - objects.each { |o| o.extend(Transaction::Simple) } - objects.each { |o| o.start_transaction } - - result = connection.transaction(Thread.current['start_db_transaction'], &block) - - objects.each { |o| o.commit_transaction } - return result - rescue Exception => object_transaction_rollback - objects.each { |o| o.abort_transaction } - raise - ensure - unlock_mutex - trap('TERM', previous_handler) - end - end - - def lock_mutex#:nodoc: - Thread.current['open_transactions'] ||= 0 - TRANSACTION_MUTEX.lock if Thread.current['open_transactions'] == 0 - Thread.current['start_db_transaction'] = (Thread.current['open_transactions'] == 0) - Thread.current['open_transactions'] += 1 - end - - def unlock_mutex#:nodoc: - Thread.current['open_transactions'] -= 1 - TRANSACTION_MUTEX.unlock if Thread.current['open_transactions'] == 0 - end - end - - def transaction(*objects, &block) - self.class.transaction(*objects, &block) - end - - def destroy_with_transactions #:nodoc: - transaction { destroy_without_transactions } - end - - def save_with_transactions(perform_validation = true) #:nodoc: - transaction { save_without_transactions(perform_validation) } - end - end -end diff --git a/tracks/vendor/rails/activerecord/lib/active_record/validations.rb b/tracks/vendor/rails/activerecord/lib/active_record/validations.rb deleted file mode 100644 index b6c9647b..00000000 --- a/tracks/vendor/rails/activerecord/lib/active_record/validations.rb +++ /dev/null @@ -1,790 +0,0 @@ -module ActiveRecord - # Raised by save! and create! when the record is invalid. Use the - # record method to retrieve the record which did not validate. - # begin - # complex_operation_that_calls_save!_internally - # rescue ActiveRecord::RecordInvalid => invalid - # puts invalid.record.errors - # end - class RecordInvalid < ActiveRecordError - attr_reader :record - def initialize(record, *args) - @record = record - super(*args) - end - end - - # Active Record validation is reported to and from this object, which is used by Base#save to - # determine whether the object in a valid state to be saved. See usage example in Validations. - class Errors - include Enumerable - - def initialize(base) # :nodoc: - @base, @errors = base, {} - end - - @@default_error_messages = { - :inclusion => "is not included in the list", - :exclusion => "is reserved", - :invalid => "is invalid", - :confirmation => "doesn't match confirmation", - :accepted => "must be accepted", - :empty => "can't be empty", - :blank => "can't be blank", - :too_long => "is too long (max is %d characters)", - :too_short => "is too short (min is %d characters)", - :wrong_length => "is the wrong length (should be %d characters)", - :taken => "has already been taken", - :not_a_number => "is not a number" - } - - # Holds a hash with all the default error messages, such that they can be replaced by your own copy or localizations. - cattr_accessor :default_error_messages - - - # Adds an error to the base object instead of any particular attribute. This is used - # to report errors that don't tie to any specific attribute, but rather to the object - # as a whole. These error messages don't get prepended with any field name when iterating - # with each_full, so they should be complete sentences. - def add_to_base(msg) - add(:base, msg) - end - - # Adds an error message (+msg+) to the +attribute+, which will be returned on a call to on(attribute) - # for the same attribute and ensure that this error object returns false when asked if empty?. More than one - # error can be added to the same +attribute+ in which case an array will be returned on a call to on(attribute). - # If no +msg+ is supplied, "invalid" is assumed. - def add(attribute, msg = @@default_error_messages[:invalid]) - @errors[attribute.to_s] = [] if @errors[attribute.to_s].nil? - @errors[attribute.to_s] << msg - end - - # Will add an error message to each of the attributes in +attributes+ that is empty. - def add_on_empty(attributes, msg = @@default_error_messages[:empty]) - for attr in [attributes].flatten - value = @base.respond_to?(attr.to_s) ? @base.send(attr.to_s) : @base[attr.to_s] - is_empty = value.respond_to?("empty?") ? value.empty? : false - add(attr, msg) unless !value.nil? && !is_empty - end - end - - # Will add an error message to each of the attributes in +attributes+ that is blank (using Object#blank?). - def add_on_blank(attributes, msg = @@default_error_messages[:blank]) - for attr in [attributes].flatten - value = @base.respond_to?(attr.to_s) ? @base.send(attr.to_s) : @base[attr.to_s] - add(attr, msg) if value.blank? - end - end - - # Will add an error message to each of the attributes in +attributes+ that has a length outside of the passed boundary +range+. - # If the length is above the boundary, the too_long_msg message will be used. If below, the too_short_msg. - def add_on_boundary_breaking(attributes, range, too_long_msg = @@default_error_messages[:too_long], too_short_msg = @@default_error_messages[:too_short]) - for attr in [attributes].flatten - value = @base.respond_to?(attr.to_s) ? @base.send(attr.to_s) : @base[attr.to_s] - add(attr, too_short_msg % range.begin) if value && value.length < range.begin - add(attr, too_long_msg % range.end) if value && value.length > range.end - end - end - - alias :add_on_boundry_breaking :add_on_boundary_breaking - - # Returns true if the specified +attribute+ has errors associated with it. - def invalid?(attribute) - !@errors[attribute.to_s].nil? - end - - # * Returns nil, if no errors are associated with the specified +attribute+. - # * Returns the error message, if one error is associated with the specified +attribute+. - # * Returns an array of error messages, if more than one error is associated with the specified +attribute+. - def on(attribute) - if @errors[attribute.to_s].nil? - nil - elsif @errors[attribute.to_s].length == 1 - @errors[attribute.to_s].first - else - @errors[attribute.to_s] - end - end - - alias :[] :on - - # Returns errors assigned to base object through add_to_base according to the normal rules of on(attribute). - def on_base - on(:base) - end - - # Yields each attribute and associated message per error added. - def each - @errors.each_key { |attr| @errors[attr].each { |msg| yield attr, msg } } - end - - # Yields each full error message added. So Person.errors.add("first_name", "can't be empty") will be returned - # through iteration as "First name can't be empty". - def each_full - full_messages.each { |msg| yield msg } - end - - # Returns all the full error messages in an array. - def full_messages - full_messages = [] - - @errors.each_key do |attr| - @errors[attr].each do |msg| - next if msg.nil? - - if attr == "base" - full_messages << msg - else - full_messages << @base.class.human_attribute_name(attr) + " " + msg - end - end - end - - return full_messages - end - - # Returns true if no errors have been added. - def empty? - return @errors.empty? - end - - # Removes all the errors that have been added. - def clear - @errors = {} - end - - # Returns the total number of errors added. Two errors added to the same attribute will be counted as such - # with this as well. - def count - error_count = 0 - @errors.each_value { |attribute| error_count += attribute.length } - error_count - end - end - - - # Active Records implement validation by overwriting Base#validate (or the variations, +validate_on_create+ and - # +validate_on_update+). Each of these methods can inspect the state of the object, which usually means ensuring - # that a number of attributes have a certain value (such as not empty, within a given range, matching a certain regular expression). - # - # Example: - # - # class Person < ActiveRecord::Base - # protected - # def validate - # errors.add_on_empty %w( first_name last_name ) - # errors.add("phone_number", "has invalid format") unless phone_number =~ /[0-9]*/ - # end - # - # def validate_on_create # is only run the first time a new object is saved - # unless valid_discount?(membership_discount) - # errors.add("membership_discount", "has expired") - # end - # end - # - # def validate_on_update - # errors.add_to_base("No changes have occurred") if unchanged_attributes? - # end - # end - # - # person = Person.new("first_name" => "David", "phone_number" => "what?") - # person.save # => false (and doesn't do the save) - # person.errors.empty? # => false - # person.errors.count # => 2 - # person.errors.on "last_name" # => "can't be empty" - # person.errors.on "phone_number" # => "has invalid format" - # person.errors.each_full { |msg| puts msg } - # # => "Last name can't be empty\n" + - # "Phone number has invalid format" - # - # person.attributes = { "last_name" => "Heinemeier", "phone_number" => "555-555" } - # person.save # => true (and person is now saved in the database) - # - # An +Errors+ object is automatically created for every Active Record. - # - # Please do have a look at ActiveRecord::Validations::ClassMethods for a higher level of validations. - module Validations - VALIDATIONS = %w( validate validate_on_create validate_on_update ) - - def self.append_features(base) # :nodoc: - super - base.extend ClassMethods - base.class_eval do - alias_method :save_without_validation, :save - alias_method :save, :save_with_validation - - alias_method :update_attribute_without_validation_skipping, :update_attribute - alias_method :update_attribute, :update_attribute_with_validation_skipping - end - end - - # All of the following validations are defined in the class scope of the model that you're interested in validating. - # They offer a more declarative way of specifying when the model is valid and when it is not. It is recommended to use - # these over the low-level calls to validate and validate_on_create when possible. - module ClassMethods - DEFAULT_VALIDATION_OPTIONS = { - :on => :save, - :allow_nil => false, - :message => nil - }.freeze - - ALL_RANGE_OPTIONS = [ :is, :within, :in, :minimum, :maximum ].freeze - - def validate(*methods, &block) - methods << block if block_given? - write_inheritable_set(:validate, methods) - end - - def validate_on_create(*methods, &block) - methods << block if block_given? - write_inheritable_set(:validate_on_create, methods) - end - - def validate_on_update(*methods, &block) - methods << block if block_given? - write_inheritable_set(:validate_on_update, methods) - end - - def condition_block?(condition) - condition.respond_to?("call") && (condition.arity == 1 || condition.arity == -1) - end - - # Determine from the given condition (whether a block, procedure, method or string) - # whether or not to validate the record. See #validates_each. - def evaluate_condition(condition, record) - case condition - when Symbol: record.send(condition) - when String: eval(condition, binding) - else - if condition_block?(condition) - condition.call(record) - else - raise( - ActiveRecordError, - "Validations need to be either a symbol, string (to be eval'ed), proc/method, or " + - "class implementing a static validation method" - ) - end - end - end - - # Validates each attribute against a block. - # - # class Person < ActiveRecord::Base - # validates_each :first_name, :last_name do |record, attr| - # record.errors.add attr, 'starts with z.' if attr[0] == ?z - # end - # end - # - # Options: - # * on - Specifies when this validation is active (default is :save, other options :create, :update) - # * allow_nil - Skip validation if attribute is nil. - # * if - Specifies a method, proc or string to call to determine if the validation should - # occur (e.g. :if => :allow_validation, or :if => Proc.new { |user| user.signup_step > 2 }). The - # method, proc or string should return or evaluate to a true or false value. - def validates_each(*attrs) - options = attrs.last.is_a?(Hash) ? attrs.pop.symbolize_keys : {} - attrs = attrs.flatten - - # Declare the validation. - send(validation_method(options[:on] || :save)) do |record| - # Don't validate when there is an :if condition and that condition is false - unless options[:if] && !evaluate_condition(options[:if], record) - attrs.each do |attr| - value = record.send(attr) - next if value.nil? && options[:allow_nil] - yield record, attr, value - end - end - end - end - - # Encapsulates the pattern of wanting to validate a password or email address field with a confirmation. Example: - # - # Model: - # class Person < ActiveRecord::Base - # validates_confirmation_of :user_name, :password - # validates_confirmation_of :email_address, :message => "should match confirmation" - # end - # - # View: - # <%= password_field "person", "password" %> - # <%= password_field "person", "password_confirmation" %> - # - # The person has to already have a password attribute (a column in the people table), but the password_confirmation is virtual. - # It exists only as an in-memory variable for validating the password. This check is performed only if password_confirmation - # is not nil and by default on save. - # - # Configuration options: - # * message - A custom error message (default is: "doesn't match confirmation") - # * on - Specifies when this validation is active (default is :save, other options :create, :update) - # * if - Specifies a method, proc or string to call to determine if the validation should - # occur (e.g. :if => :allow_validation, or :if => Proc.new { |user| user.signup_step > 2 }). The - # method, proc or string should return or evaluate to a true or false value. - def validates_confirmation_of(*attr_names) - configuration = { :message => ActiveRecord::Errors.default_error_messages[:confirmation], :on => :save } - configuration.update(attr_names.pop) if attr_names.last.is_a?(Hash) - - attr_accessor *(attr_names.map { |n| "#{n}_confirmation" }) - - validates_each(attr_names, configuration) do |record, attr_name, value| - record.errors.add(attr_name, configuration[:message]) unless record.send("#{attr_name}_confirmation").nil? or value == record.send("#{attr_name}_confirmation") - end - end - - # Encapsulates the pattern of wanting to validate the acceptance of a terms of service check box (or similar agreement). Example: - # - # class Person < ActiveRecord::Base - # validates_acceptance_of :terms_of_service - # validates_acceptance_of :eula, :message => "must be abided" - # end - # - # The terms_of_service attribute is entirely virtual. No database column is needed. This check is performed only if - # terms_of_service is not nil and by default on save. - # - # Configuration options: - # * message - A custom error message (default is: "must be accepted") - # * on - Specifies when this validation is active (default is :save, other options :create, :update) - # * accept - Specifies value that is considered accepted. The default value is a string "1", which - # makes it easy to relate to an HTML checkbox. - # * if - Specifies a method, proc or string to call to determine if the validation should - # occur (e.g. :if => :allow_validation, or :if => Proc.new { |user| user.signup_step > 2 }). The - # method, proc or string should return or evaluate to a true or false value. - def validates_acceptance_of(*attr_names) - configuration = { :message => ActiveRecord::Errors.default_error_messages[:accepted], :on => :save, :allow_nil => true, :accept => "1" } - configuration.update(attr_names.pop) if attr_names.last.is_a?(Hash) - - attr_accessor *attr_names - - validates_each(attr_names,configuration) do |record, attr_name, value| - record.errors.add(attr_name, configuration[:message]) unless value == configuration[:accept] - end - end - - # Validates that the specified attributes are not blank (as defined by Object#blank?). Happens by default on save. - # - # Configuration options: - # * message - A custom error message (default is: "can't be blank") - # * on - Specifies when this validation is active (default is :save, other options :create, :update) - # * if - Specifies a method, proc or string to call to determine if the validation should - # occur (e.g. :if => :allow_validation, or :if => Proc.new { |user| user.signup_step > 2 }). The - # method, proc or string should return or evaluate to a true or false value. - def validates_presence_of(*attr_names) - configuration = { :message => ActiveRecord::Errors.default_error_messages[:blank], :on => :save } - configuration.update(attr_names.pop) if attr_names.last.is_a?(Hash) - - # can't use validates_each here, because it cannot cope with nonexistent attributes, - # while errors.add_on_empty can - attr_names.each do |attr_name| - send(validation_method(configuration[:on])) do |record| - unless configuration[:if] and not evaluate_condition(configuration[:if], record) - record.errors.add_on_blank(attr_name,configuration[:message]) - end - end - end - end - - # Validates that the specified attribute matches the length restrictions supplied. Only one option can be used at a time: - # - # class Person < ActiveRecord::Base - # validates_length_of :first_name, :maximum=>30 - # validates_length_of :last_name, :maximum=>30, :message=>"less than %d if you don't mind" - # validates_length_of :fax, :in => 7..32, :allow_nil => true - # validates_length_of :user_name, :within => 6..20, :too_long => "pick a shorter name", :too_short => "pick a longer name" - # validates_length_of :fav_bra_size, :minimum=>1, :too_short=>"please enter at least %d character" - # validates_length_of :smurf_leader, :is=>4, :message=>"papa is spelled with %d characters... don't play me." - # end - # - # Configuration options: - # * minimum - The minimum size of the attribute - # * maximum - The maximum size of the attribute - # * is - The exact size of the attribute - # * within - A range specifying the minimum and maximum size of the attribute - # * in - A synonym(or alias) for :within - # * allow_nil - Attribute may be nil; skip validation. - # - # * too_long - The error message if the attribute goes over the maximum (default is: "is too long (max is %d characters)") - # * too_short - The error message if the attribute goes under the minimum (default is: "is too short (min is %d characters)") - # * wrong_length - The error message if using the :is method and the attribute is the wrong size (default is: "is the wrong length (should be %d characters)") - # * message - The error message to use for a :minimum, :maximum, or :is violation. An alias of the appropriate too_long/too_short/wrong_length message - # * on - Specifies when this validation is active (default is :save, other options :create, :update) - # * if - Specifies a method, proc or string to call to determine if the validation should - # occur (e.g. :if => :allow_validation, or :if => Proc.new { |user| user.signup_step > 2 }). The - # method, proc or string should return or evaluate to a true or false value. - def validates_length_of(*attrs) - # Merge given options with defaults. - options = { - :too_long => ActiveRecord::Errors.default_error_messages[:too_long], - :too_short => ActiveRecord::Errors.default_error_messages[:too_short], - :wrong_length => ActiveRecord::Errors.default_error_messages[:wrong_length] - }.merge(DEFAULT_VALIDATION_OPTIONS) - options.update(attrs.pop.symbolize_keys) if attrs.last.is_a?(Hash) - - # Ensure that one and only one range option is specified. - range_options = ALL_RANGE_OPTIONS & options.keys - case range_options.size - when 0 - raise ArgumentError, 'Range unspecified. Specify the :within, :maximum, :minimum, or :is option.' - when 1 - # Valid number of options; do nothing. - else - raise ArgumentError, 'Too many range options specified. Choose only one.' - end - - # Get range option and value. - option = range_options.first - option_value = options[range_options.first] - - case option - when :within, :in - raise ArgumentError, ":#{option} must be a Range" unless option_value.is_a?(Range) - - too_short = options[:too_short] % option_value.begin - too_long = options[:too_long] % option_value.end - - validates_each(attrs, options) do |record, attr, value| - if value.nil? or value.size < option_value.begin - record.errors.add(attr, too_short) - elsif value.size > option_value.end - record.errors.add(attr, too_long) - end - end - when :is, :minimum, :maximum - raise ArgumentError, ":#{option} must be a nonnegative Integer" unless option_value.is_a?(Integer) and option_value >= 0 - - # Declare different validations per option. - validity_checks = { :is => "==", :minimum => ">=", :maximum => "<=" } - message_options = { :is => :wrong_length, :minimum => :too_short, :maximum => :too_long } - - message = (options[:message] || options[message_options[option]]) % option_value - - validates_each(attrs, options) do |record, attr, value| - record.errors.add(attr, message) unless !value.nil? and value.size.method(validity_checks[option])[option_value] - end - end - end - - alias_method :validates_size_of, :validates_length_of - - - # Validates whether the value of the specified attributes are unique across the system. Useful for making sure that only one user - # can be named "davidhh". - # - # class Person < ActiveRecord::Base - # validates_uniqueness_of :user_name, :scope => "account_id" - # end - # - # When the record is created, a check is performed to make sure that no record exists in the database with the given value for the specified - # attribute (that maps to a column). When the record is updated, the same check is made but disregarding the record itself. - # - # Configuration options: - # * message - Specifies a custom error message (default is: "has already been taken") - # * scope - Ensures that the uniqueness is restricted to a condition of "scope = record.scope" - # * if - Specifies a method, proc or string to call to determine if the validation should - # occur (e.g. :if => :allow_validation, or :if => Proc.new { |user| user.signup_step > 2 }). The - # method, proc or string should return or evaluate to a true or false value. - def validates_uniqueness_of(*attr_names) - configuration = { :message => ActiveRecord::Errors.default_error_messages[:taken] } - configuration.update(attr_names.pop) if attr_names.last.is_a?(Hash) - - validates_each(attr_names,configuration) do |record, attr_name, value| - condition_sql = "#{attr_name} #{attribute_condition(value)}" - condition_params = [value] - if scope = configuration[:scope] - scope_value = record.send(scope) - condition_sql << " AND #{scope} #{attribute_condition(scope_value)}" - condition_params << scope_value - end - unless record.new_record? - condition_sql << " AND #{record.class.primary_key} <> ?" - condition_params << record.send(:id) - end - if record.class.find(:first, :conditions => [condition_sql, *condition_params]) - record.errors.add(attr_name, configuration[:message]) - end - end - end - - # Validates whether the value of the specified attribute is of the correct form by matching it against the regular expression - # provided. - # - # class Person < ActiveRecord::Base - # validates_format_of :email, :with => /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i, :on => :create - # end - # - # A regular expression must be provided or else an exception will be raised. - # - # Configuration options: - # * message - A custom error message (default is: "is invalid") - # * with - The regular expression used to validate the format with (note: must be supplied!) - # * on Specifies when this validation is active (default is :save, other options :create, :update) - # * if - Specifies a method, proc or string to call to determine if the validation should - # occur (e.g. :if => :allow_validation, or :if => Proc.new { |user| user.signup_step > 2 }). The - # method, proc or string should return or evaluate to a true or false value. - def validates_format_of(*attr_names) - configuration = { :message => ActiveRecord::Errors.default_error_messages[:invalid], :on => :save, :with => nil } - configuration.update(attr_names.pop) if attr_names.last.is_a?(Hash) - - raise(ArgumentError, "A regular expression must be supplied as the :with option of the configuration hash") unless configuration[:with].is_a?(Regexp) - - validates_each(attr_names, configuration) do |record, attr_name, value| - record.errors.add(attr_name, configuration[:message]) unless value.to_s =~ configuration[:with] - end - end - - # Validates whether the value of the specified attribute is available in a particular enumerable object. - # - # class Person < ActiveRecord::Base - # validates_inclusion_of :gender, :in=>%w( m f ), :message=>"woah! what are you then!??!!" - # validates_inclusion_of :age, :in=>0..99 - # end - # - # Configuration options: - # * in - An enumerable object of available items - # * message - Specifies a customer error message (default is: "is not included in the list") - # * allow_nil - If set to true, skips this validation if the attribute is null (default is: false) - # * if - Specifies a method, proc or string to call to determine if the validation should - # occur (e.g. :if => :allow_validation, or :if => Proc.new { |user| user.signup_step > 2 }). The - # method, proc or string should return or evaluate to a true or false value. - def validates_inclusion_of(*attr_names) - configuration = { :message => ActiveRecord::Errors.default_error_messages[:inclusion], :on => :save } - configuration.update(attr_names.pop) if attr_names.last.is_a?(Hash) - - enum = configuration[:in] || configuration[:within] - - raise(ArgumentError, "An object with the method include? is required must be supplied as the :in option of the configuration hash") unless enum.respond_to?("include?") - - validates_each(attr_names, configuration) do |record, attr_name, value| - record.errors.add(attr_name, configuration[:message]) unless enum.include?(value) - end - end - - # Validates that the value of the specified attribute is not in a particular enumerable object. - # - # class Person < ActiveRecord::Base - # validates_exclusion_of :username, :in => %w( admin superuser ), :message => "You don't belong here" - # validates_exclusion_of :age, :in => 30..60, :message => "This site is only for under 30 and over 60" - # end - # - # Configuration options: - # * in - An enumerable object of items that the value shouldn't be part of - # * message - Specifies a customer error message (default is: "is reserved") - # * allow_nil - If set to true, skips this validation if the attribute is null (default is: false) - # * if - Specifies a method, proc or string to call to determine if the validation should - # occur (e.g. :if => :allow_validation, or :if => Proc.new { |user| user.signup_step > 2 }). The - # method, proc or string should return or evaluate to a true or false value. - def validates_exclusion_of(*attr_names) - configuration = { :message => ActiveRecord::Errors.default_error_messages[:exclusion], :on => :save } - configuration.update(attr_names.pop) if attr_names.last.is_a?(Hash) - - enum = configuration[:in] || configuration[:within] - - raise(ArgumentError, "An object with the method include? is required must be supplied as the :in option of the configuration hash") unless enum.respond_to?("include?") - - validates_each(attr_names, configuration) do |record, attr_name, value| - record.errors.add(attr_name, configuration[:message]) if enum.include?(value) - end - end - - # Validates whether the associated object or objects are all valid themselves. Works with any kind of association. - # - # class Book < ActiveRecord::Base - # has_many :pages - # belongs_to :library - # - # validates_associated :pages, :library - # end - # - # Warning: If, after the above definition, you then wrote: - # - # class Page < ActiveRecord::Base - # belongs_to :book - # - # validates_associated :book - # end - # - # ...this would specify a circular dependency and cause infinite recursion. - # - # NOTE: This validation will not fail if the association hasn't been assigned. If you want to ensure that the association - # is both present and guaranteed to be valid, you also need to use validates_presence_of. - # - # Configuration options: - # * on Specifies when this validation is active (default is :save, other options :create, :update) - # * if - Specifies a method, proc or string to call to determine if the validation should - # occur (e.g. :if => :allow_validation, or :if => Proc.new { |user| user.signup_step > 2 }). The - # method, proc or string should return or evaluate to a true or false value. - def validates_associated(*attr_names) - configuration = { :message => ActiveRecord::Errors.default_error_messages[:invalid], :on => :save } - configuration.update(attr_names.pop) if attr_names.last.is_a?(Hash) - - validates_each(attr_names, configuration) do |record, attr_name, value| - record.errors.add(attr_name, configuration[:message]) unless - (value.is_a?(Array) ? value : [value]).all? { |r| r.nil? or r.valid? } - end - end - - # Validates whether the value of the specified attribute is numeric by trying to convert it to - # a float with Kernel.Float (if integer is false) or applying it to the regular expression - # /^[\+\-]?\d+$/ (if integer is set to true). - # - # class Person < ActiveRecord::Base - # validates_numericality_of :value, :on => :create - # end - # - # Configuration options: - # * message - A custom error message (default is: "is not a number") - # * on Specifies when this validation is active (default is :save, other options :create, :update) - # * only_integer Specifies whether the value has to be an integer, e.g. an integral value (default is false) - # * allow_nil Skip validation if attribute is nil (default is false). Notice that for fixnum and float columns empty strings are converted to nil - # * if - Specifies a method, proc or string to call to determine if the validation should - # occur (e.g. :if => :allow_validation, or :if => Proc.new { |user| user.signup_step > 2 }). The - # method, proc or string should return or evaluate to a true or false value. - def validates_numericality_of(*attr_names) - configuration = { :message => ActiveRecord::Errors.default_error_messages[:not_a_number], :on => :save, - :only_integer => false, :allow_nil => false } - configuration.update(attr_names.pop) if attr_names.last.is_a?(Hash) - - if configuration[:only_integer] - validates_each(attr_names,configuration) do |record, attr_name,value| - record.errors.add(attr_name, configuration[:message]) unless record.send("#{attr_name}_before_type_cast").to_s =~ /^[+-]?\d+$/ - end - else - validates_each(attr_names,configuration) do |record, attr_name,value| - next if configuration[:allow_nil] and record.send("#{attr_name}_before_type_cast").nil? - begin - Kernel.Float(record.send("#{attr_name}_before_type_cast").to_s) - rescue ArgumentError, TypeError - record.errors.add(attr_name, configuration[:message]) - end - end - end - end - - - # Creates an object just like Base.create but calls save! instead of save - # so an exception is raised if the record is invalid. - def create!(attributes = nil) - if attributes.is_a?(Array) - attributes.collect { |attr| create!(attr) } - else - attributes.reverse_merge!(scope(:create)) if scoped?(:create) - - object = new(attributes) - object.save! - object - end - end - - - private - def write_inheritable_set(key, methods) - existing_methods = read_inheritable_attribute(key) || [] - write_inheritable_attribute(key, methods | existing_methods) - end - - def validation_method(on) - case on - when :save then :validate - when :create then :validate_on_create - when :update then :validate_on_update - end - end - end - - # The validation process on save can be skipped by passing false. The regular Base#save method is - # replaced with this when the validations module is mixed in, which it is by default. - def save_with_validation(perform_validation = true) - if perform_validation && valid? || !perform_validation - save_without_validation - true - else - false - end - end - - # Attempts to save the record just like Base#save but will raise a RecordInvalid exception instead of returning false - # if the record is not valid. - def save! - if valid? - save(false) - else - raise RecordInvalid.new(self) - end - end - - # Updates a single attribute and saves the record without going through the normal validation procedure. - # This is especially useful for boolean flags on existing records. The regular +update_attribute+ method - # in Base is replaced with this when the validations module is mixed in, which it is by default. - def update_attribute_with_validation_skipping(name, value) - send(name.to_s + '=', value) - save(false) - end - - # Runs validate and validate_on_create or validate_on_update and returns true if no errors were added otherwise false. - def valid? - errors.clear - - run_validations(:validate) - validate - - if new_record? - run_validations(:validate_on_create) - validate_on_create - else - run_validations(:validate_on_update) - validate_on_update - end - - errors.empty? - end - - # Returns the Errors object that holds all information about attribute error messages. - def errors - @errors ||= Errors.new(self) - end - - protected - # Overwrite this method for validation checks on all saves and use Errors.add(field, msg) for invalid attributes. - def validate #:doc: - end - - # Overwrite this method for validation checks used only on creation. - def validate_on_create #:doc: - end - - # Overwrite this method for validation checks used only on updates. - def validate_on_update # :doc: - end - - private - def run_validations(validation_method) - validations = self.class.read_inheritable_attribute(validation_method.to_sym) - if validations.nil? then return end - validations.each do |validation| - if validation.is_a?(Symbol) - self.send(validation) - elsif validation.is_a?(String) - eval(validation, binding) - elsif validation_block?(validation) - validation.call(self) - elsif validation_class?(validation, validation_method) - validation.send(validation_method, self) - else - raise( - ActiveRecordError, - "Validations need to be either a symbol, string (to be eval'ed), proc/method, or " + - "class implementing a static validation method" - ) - end - end - end - - def validation_block?(validation) - validation.respond_to?("call") && (validation.arity == 1 || validation.arity == -1) - end - - def validation_class?(validation, validation_method) - validation.respond_to?(validation_method) - end - end -end diff --git a/tracks/vendor/rails/activerecord/lib/active_record/vendor/db2.rb b/tracks/vendor/rails/activerecord/lib/active_record/vendor/db2.rb deleted file mode 100644 index 42171bed..00000000 --- a/tracks/vendor/rails/activerecord/lib/active_record/vendor/db2.rb +++ /dev/null @@ -1,357 +0,0 @@ -require 'db2/db2cli.rb' - -module DB2 - module DB2Util - include DB2CLI - - def free() SQLFreeHandle(@handle_type, @handle); end - def handle() @handle; end - - def check_rc(rc) - if ![SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_NO_DATA_FOUND].include?(rc) - rec = 1 - msg = '' - loop do - a = SQLGetDiagRec(@handle_type, @handle, rec, 500) - break if a[0] != SQL_SUCCESS - msg << a[3] if !a[3].nil? and a[3] != '' # Create message. - rec += 1 - end - raise "DB2 error: #{msg}" - end - end - end - - class Environment - include DB2Util - - def initialize - @handle_type = SQL_HANDLE_ENV - rc, @handle = SQLAllocHandle(@handle_type, SQL_NULL_HANDLE) - check_rc(rc) - end - - def data_sources(buffer_length = 1024) - retval = [] - max_buffer_length = buffer_length - - a = SQLDataSources(@handle, SQL_FETCH_FIRST, SQL_MAX_DSN_LENGTH + 1, buffer_length) - retval << [a[1], a[3]] - max_buffer_length = [max_buffer_length, a[4]].max - - loop do - a = SQLDataSources(@handle, SQL_FETCH_NEXT, SQL_MAX_DSN_LENGTH + 1, buffer_length) - break if a[0] == SQL_NO_DATA_FOUND - - retval << [a[1], a[3]] - max_buffer_length = [max_buffer_length, a[4]].max - end - - if max_buffer_length > buffer_length - get_data_sources(max_buffer_length) - else - retval - end - end - end - - class Connection - include DB2Util - - def initialize(environment) - @env = environment - @handle_type = SQL_HANDLE_DBC - rc, @handle = SQLAllocHandle(@handle_type, @env.handle) - check_rc(rc) - end - - def connect(server_name, user_name = '', auth = '') - check_rc(SQLConnect(@handle, server_name, user_name, auth)) - end - - def set_connect_attr(attr, value) - value += "\0" if value.class == String - check_rc(SQLSetConnectAttr(@handle, attr, value)) - end - - def set_auto_commit_on - set_connect_attr(SQL_ATTR_AUTOCOMMIT, SQL_AUTOCOMMIT_ON) - end - - def set_auto_commit_off - set_connect_attr(SQL_ATTR_AUTOCOMMIT, SQL_AUTOCOMMIT_OFF) - end - - def disconnect - check_rc(SQLDisconnect(@handle)) - end - - def rollback - check_rc(SQLEndTran(@handle_type, @handle, SQL_ROLLBACK)) - end - - def commit - check_rc(SQLEndTran(@handle_type, @handle, SQL_COMMIT)) - end - end - - class Statement - include DB2Util - - def initialize(connection) - @conn = connection - @handle_type = SQL_HANDLE_STMT - @parms = [] #yun - @sql = '' #yun - @numParms = 0 #yun - @prepared = false #yun - @parmArray = [] #yun. attributes of the parameter markers - rc, @handle = SQLAllocHandle(@handle_type, @conn.handle) - check_rc(rc) - end - - def columns(table_name) - check_rc(SQLColumns(@handle, "", "%", table_name, "%")) - fetch_all - end - - def tables - check_rc(SQLTables(@handle, "", "%", "%", "TABLE")) - fetch_all - end - - def prepare(sql) - @sql = sql - check_rc(SQLPrepare(@handle, sql)) - rc, @numParms = SQLNumParams(@handle) #number of question marks - check_rc(rc) - #-------------------------------------------------------------------------- - # parameter attributes are stored in instance variable @parmArray so that - # they are available when execute method is called. - #-------------------------------------------------------------------------- - if @numParms > 0 # get parameter marker attributes - 1.upto(@numParms) do |i| # parameter number starts from 1 - rc, type, size, decimalDigits = SQLDescribeParam(@handle, i) - check_rc(rc) - @parmArray << Parameter.new(type, size, decimalDigits) - end - end - @prepared = true - self - end - - def execute(*parms) - raise "The statement was not prepared" if @prepared == false - - if parms.size == 1 and parms[0].class == Array - parms = parms[0] - end - - if @numParms != parms.size - raise "Number of parameters supplied does not match with the SQL statement" - end - - if @numParms > 0 #need to bind parameters - #-------------------------------------------------------------------- - #calling bindParms may not be safe. Look comment below. - #-------------------------------------------------------------------- - #bindParms(parms) - - valueArray = [] - 1.upto(@numParms) do |i| # parameter number starts from 1 - type = @parmArray[i - 1].class - size = @parmArray[i - 1].size - decimalDigits = @parmArray[i - 1].decimalDigits - - if parms[i - 1].class == String - valueArray << parms[i - 1] - else - valueArray << parms[i - 1].to_s - end - - rc = SQLBindParameter(@handle, i, type, size, decimalDigits, valueArray[i - 1]) - check_rc(rc) - end - end - - check_rc(SQLExecute(@handle)) - - if @numParms != 0 - check_rc(SQLFreeStmt(@handle, SQL_RESET_PARAMS)) # Reset parameters - end - - self - end - - #------------------------------------------------------------------------------- - # The last argument(value) to SQLBindParameter is a deferred argument, that is, - # it should be available when SQLExecute is called. Even though "value" is - # local to bindParms method, it seems that it is available when SQLExecute - # is called. I am not sure whether it would still work if garbage collection - # is done between bindParms call and SQLExecute call inside the execute method - # above. - #------------------------------------------------------------------------------- - def bindParms(parms) # This is the real thing. It uses SQLBindParms - 1.upto(@numParms) do |i| # parameter number starts from 1 - rc, dataType, parmSize, decimalDigits = SQLDescribeParam(@handle, i) - check_rc(rc) - if parms[i - 1].class == String - value = parms[i - 1] - else - value = parms[i - 1].to_s - end - rc = SQLBindParameter(@handle, i, dataType, parmSize, decimalDigits, value) - check_rc(rc) - end - end - - #------------------------------------------------------------------------------ - # bind method does not use DB2's SQLBindParams, but replaces "?" in the - # SQL statement with the value before passing the SQL statement to DB2. - # It is not efficient and can handle only strings since it puts everything in - # quotes. - #------------------------------------------------------------------------------ - def bind(sql, args) #does not use SQLBindParams - arg_index = 0 - result = "" - tokens(sql).each do |part| - case part - when '?' - result << "'" + (args[arg_index]) + "'" #put it into quotes - arg_index += 1 - when '??' - result << "?" - else - result << part - end - end - if arg_index < args.size - raise "Too many SQL parameters" - elsif arg_index > args.size - raise "Not enough SQL parameters" - end - result - end - - ## Break the sql string into parts. - # - # This is NOT a full lexer for SQL. It just breaks up the SQL - # string enough so that question marks, double question marks and - # quoted strings are separated. This is used when binding - # arguments to "?" in the SQL string. Note: comments are not - # handled. - # - def tokens(sql) - toks = sql.scan(/('([^'\\]|''|\\.)*'|"([^"\\]|""|\\.)*"|\?\??|[^'"?]+)/) - toks.collect { |t| t[0] } - end - - def exec_direct(sql) - check_rc(SQLExecDirect(@handle, sql)) - self - end - - def set_cursor_name(name) - check_rc(SQLSetCursorName(@handle, name)) - self - end - - def get_cursor_name - rc, name = SQLGetCursorName(@handle) - check_rc(rc) - name - end - - def row_count - rc, rowcount = SQLRowCount(@handle) - check_rc(rc) - rowcount - end - - def num_result_cols - rc, cols = SQLNumResultCols(@handle) - check_rc(rc) - cols - end - - def fetch_all - if block_given? - while row = fetch do - yield row - end - else - res = [] - while row = fetch do - res << row - end - res - end - end - - def fetch - cols = get_col_desc - rc = SQLFetch(@handle) - if rc == SQL_NO_DATA_FOUND - SQLFreeStmt(@handle, SQL_CLOSE) # Close cursor - SQLFreeStmt(@handle, SQL_RESET_PARAMS) # Reset parameters - return nil - end - raise "ERROR" unless rc == SQL_SUCCESS - - retval = [] - cols.each_with_index do |c, i| - rc, content = SQLGetData(@handle, i + 1, c[1], c[2] + 1) #yun added 1 to c[2] - retval << adjust_content(content) - end - retval - end - - def fetch_as_hash - cols = get_col_desc - rc = SQLFetch(@handle) - if rc == SQL_NO_DATA_FOUND - SQLFreeStmt(@handle, SQL_CLOSE) # Close cursor - SQLFreeStmt(@handle, SQL_RESET_PARAMS) # Reset parameters - return nil - end - raise "ERROR" unless rc == SQL_SUCCESS - - retval = {} - cols.each_with_index do |c, i| - rc, content = SQLGetData(@handle, i + 1, c[1], c[2] + 1) #yun added 1 to c[2] - retval[c[0]] = adjust_content(content) - end - retval - end - - def get_col_desc - rc, nr_cols = SQLNumResultCols(@handle) - cols = (1..nr_cols).collect do |c| - rc, name, bl, type, col_sz = SQLDescribeCol(@handle, c, 1024) - [name.downcase, type, col_sz] - end - end - - def adjust_content(c) - case c.class.to_s - when 'DB2CLI::NullClass' - return nil - when 'DB2CLI::Time' - "%02d:%02d:%02d" % [c.hour, c.minute, c.second] - when 'DB2CLI::Date' - "%04d-%02d-%02d" % [c.year, c.month, c.day] - when 'DB2CLI::Timestamp' - "%04d-%02d-%02d %02d:%02d:%02d" % [c.year, c.month, c.day, c.hour, c.minute, c.second] - else - return c - end - end - end - - class Parameter - attr_reader :type, :size, :decimalDigits - def initialize(type, size, decimalDigits) - @type, @size, @decimalDigits = type, size, decimalDigits - end - end -end diff --git a/tracks/vendor/rails/activerecord/lib/active_record/vendor/mysql.rb b/tracks/vendor/rails/activerecord/lib/active_record/vendor/mysql.rb deleted file mode 100644 index 2599f433..00000000 --- a/tracks/vendor/rails/activerecord/lib/active_record/vendor/mysql.rb +++ /dev/null @@ -1,1195 +0,0 @@ -# $Id: mysql.rb,v 1.24 2005/02/12 11:37:15 tommy Exp $ -# -# Copyright (C) 2003-2005 TOMITA Masahiro -# tommy@tmtm.org -# - -class Mysql - - VERSION = "4.0-ruby-0.2.5" - - require "socket" - require "digest/sha1" - - MAX_PACKET_LENGTH = 256*256*256-1 - MAX_ALLOWED_PACKET = 1024*1024*1024 - - MYSQL_UNIX_ADDR = "/tmp/mysql.sock" - MYSQL_PORT = 3306 - PROTOCOL_VERSION = 10 - - # Command - COM_SLEEP = 0 - COM_QUIT = 1 - COM_INIT_DB = 2 - COM_QUERY = 3 - COM_FIELD_LIST = 4 - COM_CREATE_DB = 5 - COM_DROP_DB = 6 - COM_REFRESH = 7 - COM_SHUTDOWN = 8 - COM_STATISTICS = 9 - COM_PROCESS_INFO = 10 - COM_CONNECT = 11 - COM_PROCESS_KILL = 12 - COM_DEBUG = 13 - COM_PING = 14 - COM_TIME = 15 - COM_DELAYED_INSERT = 16 - COM_CHANGE_USER = 17 - COM_BINLOG_DUMP = 18 - COM_TABLE_DUMP = 19 - COM_CONNECT_OUT = 20 - COM_REGISTER_SLAVE = 21 - - # Client flag - CLIENT_LONG_PASSWORD = 1 - CLIENT_FOUND_ROWS = 1 << 1 - CLIENT_LONG_FLAG = 1 << 2 - CLIENT_CONNECT_WITH_DB= 1 << 3 - CLIENT_NO_SCHEMA = 1 << 4 - CLIENT_COMPRESS = 1 << 5 - CLIENT_ODBC = 1 << 6 - CLIENT_LOCAL_FILES = 1 << 7 - CLIENT_IGNORE_SPACE = 1 << 8 - CLIENT_PROTOCOL_41 = 1 << 9 - CLIENT_INTERACTIVE = 1 << 10 - CLIENT_SSL = 1 << 11 - CLIENT_IGNORE_SIGPIPE = 1 << 12 - CLIENT_TRANSACTIONS = 1 << 13 - CLIENT_RESERVED = 1 << 14 - CLIENT_SECURE_CONNECTION = 1 << 15 - CLIENT_CAPABILITIES = CLIENT_LONG_PASSWORD|CLIENT_LONG_FLAG|CLIENT_TRANSACTIONS - PROTO_AUTH41 = CLIENT_PROTOCOL_41 | CLIENT_SECURE_CONNECTION - - # Connection Option - OPT_CONNECT_TIMEOUT = 0 - OPT_COMPRESS = 1 - OPT_NAMED_PIPE = 2 - INIT_COMMAND = 3 - READ_DEFAULT_FILE = 4 - READ_DEFAULT_GROUP = 5 - SET_CHARSET_DIR = 6 - SET_CHARSET_NAME = 7 - OPT_LOCAL_INFILE = 8 - - # Server Status - SERVER_STATUS_IN_TRANS = 1 - SERVER_STATUS_AUTOCOMMIT = 2 - - # Refresh parameter - REFRESH_GRANT = 1 - REFRESH_LOG = 2 - REFRESH_TABLES = 4 - REFRESH_HOSTS = 8 - REFRESH_STATUS = 16 - REFRESH_THREADS = 32 - REFRESH_SLAVE = 64 - REFRESH_MASTER = 128 - - def initialize(*args) - @client_flag = 0 - @max_allowed_packet = MAX_ALLOWED_PACKET - @query_with_result = true - @status = :STATUS_READY - if args[0] != :INIT then - real_connect(*args) - end - end - - def real_connect(host=nil, user=nil, passwd=nil, db=nil, port=nil, socket=nil, flag=nil) - @server_status = SERVER_STATUS_AUTOCOMMIT - if (host == nil or host == "localhost") and defined? UNIXSocket then - unix_socket = socket || ENV["MYSQL_UNIX_PORT"] || MYSQL_UNIX_ADDR - sock = UNIXSocket::new(unix_socket) - @host_info = Error::err(Error::CR_LOCALHOST_CONNECTION) - @unix_socket = unix_socket - else - sock = TCPSocket::new(host, port||ENV["MYSQL_TCP_PORT"]||(Socket::getservbyname("mysql","tcp") rescue MYSQL_PORT)) - @host_info = sprintf Error::err(Error::CR_TCP_CONNECTION), host - end - @host = host ? host.dup : nil - sock.setsockopt Socket::SOL_SOCKET, Socket::SO_KEEPALIVE, true - @net = Net::new sock - - a = read - @protocol_version = a.slice!(0) - @server_version, a = a.split(/\0/,2) - @thread_id, @scramble_buff = a.slice!(0,13).unpack("La8") - if a.size >= 2 then - @server_capabilities, = a.slice!(0,2).unpack("v") - end - if a.size >= 16 then - @server_language, @server_status = a.slice!(0,3).unpack("cv") - end - - flag = 0 if flag == nil - flag |= @client_flag | CLIENT_CAPABILITIES - flag |= CLIENT_CONNECT_WITH_DB if db - - @pre_411 = (0 == @server_capabilities & PROTO_AUTH41) - if @pre_411 - data = Net::int2str(flag)+Net::int3str(@max_allowed_packet)+ - (user||"")+"\0"+ - scramble(passwd, @scramble_buff, @protocol_version==9) - else - dummy, @salt2 = a.unpack("a13a12") - @scramble_buff += @salt2 - flag |= PROTO_AUTH41 - data = Net::int4str(flag) + Net::int4str(@max_allowed_packet) + - ([8] + Array.new(23, 0)).pack("c24") + (user||"")+"\0"+ - scramble41(passwd, @scramble_buff) - end - - if db and @server_capabilities & CLIENT_CONNECT_WITH_DB != 0 - data << "\0" if @pre_411 - data << db - @db = db.dup - end - write data - read - ObjectSpace.define_finalizer(self, Mysql.finalizer(@net)) - self - end - alias :connect :real_connect - - def escape_string(str) - Mysql::escape_string str - end - alias :quote :escape_string - - def get_client_info() - VERSION - end - alias :client_info :get_client_info - - def options(option, arg=nil) - if option == OPT_LOCAL_INFILE then - if arg == false or arg == 0 then - @client_flag &= ~CLIENT_LOCAL_FILES - else - @client_flag |= CLIENT_LOCAL_FILES - end - else - raise "not implemented" - end - end - - def real_query(query) - command COM_QUERY, query, true - read_query_result - self - end - - def use_result() - if @status != :STATUS_GET_RESULT then - error Error::CR_COMMANDS_OUT_OF_SYNC - end - res = Result::new self, @fields, @field_count - @status = :STATUS_USE_RESULT - res - end - - def store_result() - if @status != :STATUS_GET_RESULT then - error Error::CR_COMMANDS_OUT_OF_SYNC - end - @status = :STATUS_READY - data = read_rows @field_count - res = Result::new self, @fields, @field_count, data - @fields = nil - @affected_rows = data.length - res - end - - def change_user(user="", passwd="", db="") - if @pre_411 - data = user+"\0"+scramble(passwd, @scramble_buff, @protocol_version==9)+"\0"+db - else - data = user+"\0"+scramble41(passwd, @scramble_buff)+db - end - command COM_CHANGE_USER, data - @user = user - @passwd = passwd - @db = db - end - - def character_set_name() - raise "not implemented" - end - - def close() - @status = :STATUS_READY - command COM_QUIT, nil, true - @net.close - self - end - - def create_db(db) - command COM_CREATE_DB, db - self - end - - def drop_db(db) - command COM_DROP_DB, db - self - end - - def dump_debug_info() - command COM_DEBUG - self - end - - def get_host_info() - @host_info - end - alias :host_info :get_host_info - - def get_proto_info() - @protocol_version - end - alias :proto_info :get_proto_info - - def get_server_info() - @server_version - end - alias :server_info :get_server_info - - def kill(id) - command COM_PROCESS_KILL, Net::int4str(id) - self - end - - def list_dbs(db=nil) - real_query "show databases #{db}" - @status = :STATUS_READY - read_rows(1).flatten - end - - def list_fields(table, field=nil) - command COM_FIELD_LIST, "#{table}\0#{field}", true - if @pre_411 - f = read_rows 6 - else - f = read_rows 7 - end - fields = unpack_fields(f, @server_capabilities & CLIENT_LONG_FLAG != 0) - res = Result::new self, fields, f.length - res.eof = true - res - end - - def list_processes() - data = command COM_PROCESS_INFO - @field_count = get_length data - if @pre_411 - fields = read_rows 5 - else - fields = read_rows 7 - end - @fields = unpack_fields(fields, @server_capabilities & CLIENT_LONG_FLAG != 0) - @status = :STATUS_GET_RESULT - store_result - end - - def list_tables(table=nil) - real_query "show tables #{table}" - @status = :STATUS_READY - read_rows(1).flatten - end - - def ping() - command COM_PING - self - end - - def query(query) - real_query query - if not @query_with_result then - return self - end - if @field_count == 0 then - return nil - end - store_result - end - - def refresh(r) - command COM_REFRESH, r.chr - self - end - - def reload() - refresh REFRESH_GRANT - self - end - - def select_db(db) - command COM_INIT_DB, db - @db = db - self - end - - def shutdown() - command COM_SHUTDOWN - self - end - - def stat() - command COM_STATISTICS - end - - attr_reader :info, :insert_id, :affected_rows, :field_count, :thread_id - attr_accessor :query_with_result, :status - - def read_one_row(field_count) - data = read - if data[0] == 254 and data.length == 1 ## EOF - return - elsif data[0] == 254 and data.length == 5 - return - end - rec = [] - field_count.times do - len = get_length data - if len == nil then - rec << len - else - rec << data.slice!(0,len) - end - end - rec - end - - def skip_result() - if @status == :STATUS_USE_RESULT then - loop do - data = read - break if data[0] == 254 and data.length == 1 - end - @status = :STATUS_READY - end - end - - def inspect() - "#<#{self.class}>" - end - - private - - def read_query_result() - data = read - @field_count = get_length(data) - if @field_count == nil then # LOAD DATA LOCAL INFILE - File::open(data) do |f| - write f.read - end - write "" # mark EOF - data = read - @field_count = get_length(data) - end - if @field_count == 0 then - @affected_rows = get_length(data, true) - @insert_id = get_length(data, true) - if @server_capabilities & CLIENT_TRANSACTIONS != 0 then - a = data.slice!(0,2) - @server_status = a[0]+a[1]*256 - end - if data.size > 0 and get_length(data) then - @info = data - end - else - @extra_info = get_length(data, true) - if @pre_411 - fields = read_rows(5) - else - fields = read_rows(7) - end - @fields = unpack_fields(fields, @server_capabilities & CLIENT_LONG_FLAG != 0) - @status = :STATUS_GET_RESULT - end - self - end - - def unpack_fields(data, long_flag_protocol) - ret = [] - data.each do |f| - if @pre_411 - table = org_table = f[0] - name = f[1] - length = f[2][0]+f[2][1]*256+f[2][2]*256*256 - type = f[3][0] - if long_flag_protocol then - flags = f[4][0]+f[4][1]*256 - decimals = f[4][2] - else - flags = f[4][0] - decimals = f[4][1] - end - def_value = f[5] - max_length = 0 - else - catalog = f[0] - db = f[1] - table = f[2] - org_table = f[3] - name = f[4] - org_name = f[5] - length = f[6][2]+f[6][3]*256+f[6][4]*256*256 - type = f[6][6] - flags = f[6][7]+f[6][8]*256 - decimals = f[6][9] - def_value = "" - max_length = 0 - end - ret << Field::new(table, org_table, name, length, type, flags, decimals, def_value, max_length) - end - ret - end - - def read_rows(field_count) - ret = [] - while rec = read_one_row(field_count) do - ret << rec - end - ret - end - - def get_length(data, longlong=nil) - return if data.length == 0 - c = data.slice!(0) - case c - when 251 - return nil - when 252 - a = data.slice!(0,2) - return a[0]+a[1]*256 - when 253 - a = data.slice!(0,3) - return a[0]+a[1]*256+a[2]*256**2 - when 254 - a = data.slice!(0,8) - if longlong then - return a[0]+a[1]*256+a[2]*256**2+a[3]*256**3+ - a[4]*256**4+a[5]*256**5+a[6]*256**6+a[7]*256**7 - else - return a[0]+a[1]*256+a[2]*256**2+a[3]*256**3 - end - else - c - end - end - - def command(cmd, arg=nil, skip_check=nil) - unless @net then - error Error::CR_SERVER_GONE_ERROR - end - if @status != :STATUS_READY then - error Error::CR_COMMANDS_OUT_OF_SYNC - end - @net.clear - write cmd.chr+(arg||"") - read unless skip_check - end - - def read() - unless @net then - error Error::CR_SERVER_GONE_ERROR - end - a = @net.read - if a[0] == 255 then - if a.length > 3 then - @errno = a[1]+a[2]*256 - @error = a[3 .. -1] - else - @errno = Error::CR_UNKNOWN_ERROR - @error = Error::err @errno - end - raise Error::new(@errno, @error) - end - a - end - - def write(arg) - unless @net then - error Error::CR_SERVER_GONE_ERROR - end - @net.write arg - end - - def hash_password(password) - nr = 1345345333 - add = 7 - nr2 = 0x12345671 - password.each_byte do |i| - next if i == 0x20 or i == 9 - nr ^= (((nr & 63) + add) * i) + (nr << 8) - nr2 += (nr2 << 8) ^ nr - add += i - end - [nr & ((1 << 31) - 1), nr2 & ((1 << 31) - 1)] - end - - def scramble(password, message, old_ver) - return "" if password == nil or password == "" - raise "old version password is not implemented" if old_ver - hash_pass = hash_password password - hash_message = hash_password message - rnd = Random::new hash_pass[0] ^ hash_message[0], hash_pass[1] ^ hash_message[1] - to = [] - 1.upto(message.length) do - to << ((rnd.rnd*31)+64).floor - end - extra = (rnd.rnd*31).floor - to.map! do |t| (t ^ extra).chr end - to.join - end - - def scramble41(password, message) - return 0x00.chr if password.nil? or password.empty? - buf = [0x14] - s1 = Digest::SHA1.new(password).digest - s2 = Digest::SHA1.new(s1).digest - x = Digest::SHA1.new(message + s2).digest - (0..s1.length - 1).each {|i| buf.push(s1[i] ^ x[i])} - buf.pack("C*") - end - - def error(errno) - @errno = errno - @error = Error::err errno - raise Error::new(@errno, @error) - end - - class Result - def initialize(mysql, fields, field_count, data=nil) - @handle = mysql - @fields = fields - @field_count = field_count - @data = data - @current_field = 0 - @current_row = 0 - @eof = false - @row_count = 0 - end - attr_accessor :eof - - def data_seek(n) - @current_row = n - end - - def fetch_field() - return if @current_field >= @field_count - f = @fields[@current_field] - @current_field += 1 - f - end - - def fetch_fields() - @fields - end - - def fetch_field_direct(n) - @fields[n] - end - - def fetch_lengths() - @data ? @data[@current_row].map{|i| i ? i.length : 0} : @lengths - end - - def fetch_row() - if @data then - if @current_row >= @data.length then - @handle.status = :STATUS_READY - return - end - ret = @data[@current_row] - @current_row += 1 - else - return if @eof - ret = @handle.read_one_row @field_count - if ret == nil then - @eof = true - return - end - @lengths = ret.map{|i| i ? i.length : 0} - @row_count += 1 - end - ret - end - - def fetch_hash(with_table=nil) - row = fetch_row - return if row == nil - hash = {} - @fields.each_index do |i| - f = with_table ? @fields[i].table+"."+@fields[i].name : @fields[i].name - hash[f] = row[i] - end - hash - end - - def field_seek(n) - @current_field = n - end - - def field_tell() - @current_field - end - - def free() - @handle.skip_result - @handle = @fields = @data = nil - end - - def num_fields() - @field_count - end - - def num_rows() - @data ? @data.length : @row_count - end - - def row_seek(n) - @current_row = n - end - - def row_tell() - @current_row - end - - def each() - while row = fetch_row do - yield row - end - end - - def each_hash(with_table=nil) - while hash = fetch_hash(with_table) do - yield hash - end - end - - def inspect() - "#<#{self.class}>" - end - - end - - class Field - # Field type - TYPE_DECIMAL = 0 - TYPE_TINY = 1 - TYPE_SHORT = 2 - TYPE_LONG = 3 - TYPE_FLOAT = 4 - TYPE_DOUBLE = 5 - TYPE_NULL = 6 - TYPE_TIMESTAMP = 7 - TYPE_LONGLONG = 8 - TYPE_INT24 = 9 - TYPE_DATE = 10 - TYPE_TIME = 11 - TYPE_DATETIME = 12 - TYPE_YEAR = 13 - TYPE_NEWDATE = 14 - TYPE_ENUM = 247 - TYPE_SET = 248 - TYPE_TINY_BLOB = 249 - TYPE_MEDIUM_BLOB = 250 - TYPE_LONG_BLOB = 251 - TYPE_BLOB = 252 - TYPE_VAR_STRING = 253 - TYPE_STRING = 254 - TYPE_GEOMETRY = 255 - TYPE_CHAR = TYPE_TINY - TYPE_INTERVAL = TYPE_ENUM - - # Flag - NOT_NULL_FLAG = 1 - PRI_KEY_FLAG = 2 - UNIQUE_KEY_FLAG = 4 - MULTIPLE_KEY_FLAG = 8 - BLOB_FLAG = 16 - UNSIGNED_FLAG = 32 - ZEROFILL_FLAG = 64 - BINARY_FLAG = 128 - ENUM_FLAG = 256 - AUTO_INCREMENT_FLAG = 512 - TIMESTAMP_FLAG = 1024 - SET_FLAG = 2048 - NUM_FLAG = 32768 - PART_KEY_FLAG = 16384 - GROUP_FLAG = 32768 - UNIQUE_FLAG = 65536 - - def initialize(table, org_table, name, length, type, flags, decimals, def_value, max_length) - @table = table - @org_table = org_table - @name = name - @length = length - @type = type - @flags = flags - @decimals = decimals - @def = def_value - @max_length = max_length - if (type <= TYPE_INT24 and (type != TYPE_TIMESTAMP or length == 14 or length == 8)) or type == TYPE_YEAR then - @flags |= NUM_FLAG - end - end - attr_reader :table, :org_table, :name, :length, :type, :flags, :decimals, :def, :max_length - - def inspect() - "#<#{self.class}:#{@name}>" - end - end - - class Error < StandardError - # Server Error - ER_HASHCHK = 1000 - ER_NISAMCHK = 1001 - ER_NO = 1002 - ER_YES = 1003 - ER_CANT_CREATE_FILE = 1004 - ER_CANT_CREATE_TABLE = 1005 - ER_CANT_CREATE_DB = 1006 - ER_DB_CREATE_EXISTS = 1007 - ER_DB_DROP_EXISTS = 1008 - ER_DB_DROP_DELETE = 1009 - ER_DB_DROP_RMDIR = 1010 - ER_CANT_DELETE_FILE = 1011 - ER_CANT_FIND_SYSTEM_REC = 1012 - ER_CANT_GET_STAT = 1013 - ER_CANT_GET_WD = 1014 - ER_CANT_LOCK = 1015 - ER_CANT_OPEN_FILE = 1016 - ER_FILE_NOT_FOUND = 1017 - ER_CANT_READ_DIR = 1018 - ER_CANT_SET_WD = 1019 - ER_CHECKREAD = 1020 - ER_DISK_FULL = 1021 - ER_DUP_KEY = 1022 - ER_ERROR_ON_CLOSE = 1023 - ER_ERROR_ON_READ = 1024 - ER_ERROR_ON_RENAME = 1025 - ER_ERROR_ON_WRITE = 1026 - ER_FILE_USED = 1027 - ER_FILSORT_ABORT = 1028 - ER_FORM_NOT_FOUND = 1029 - ER_GET_ERRNO = 1030 - ER_ILLEGAL_HA = 1031 - ER_KEY_NOT_FOUND = 1032 - ER_NOT_FORM_FILE = 1033 - ER_NOT_KEYFILE = 1034 - ER_OLD_KEYFILE = 1035 - ER_OPEN_AS_READONLY = 1036 - ER_OUTOFMEMORY = 1037 - ER_OUT_OF_SORTMEMORY = 1038 - ER_UNEXPECTED_EOF = 1039 - ER_CON_COUNT_ERROR = 1040 - ER_OUT_OF_RESOURCES = 1041 - ER_BAD_HOST_ERROR = 1042 - ER_HANDSHAKE_ERROR = 1043 - ER_DBACCESS_DENIED_ERROR = 1044 - ER_ACCESS_DENIED_ERROR = 1045 - ER_NO_DB_ERROR = 1046 - ER_UNKNOWN_COM_ERROR = 1047 - ER_BAD_NULL_ERROR = 1048 - ER_BAD_DB_ERROR = 1049 - ER_TABLE_EXISTS_ERROR = 1050 - ER_BAD_TABLE_ERROR = 1051 - ER_NON_UNIQ_ERROR = 1052 - ER_SERVER_SHUTDOWN = 1053 - ER_BAD_FIELD_ERROR = 1054 - ER_WRONG_FIELD_WITH_GROUP = 1055 - ER_WRONG_GROUP_FIELD = 1056 - ER_WRONG_SUM_SELECT = 1057 - ER_WRONG_VALUE_COUNT = 1058 - ER_TOO_LONG_IDENT = 1059 - ER_DUP_FIELDNAME = 1060 - ER_DUP_KEYNAME = 1061 - ER_DUP_ENTRY = 1062 - ER_WRONG_FIELD_SPEC = 1063 - ER_PARSE_ERROR = 1064 - ER_EMPTY_QUERY = 1065 - ER_NONUNIQ_TABLE = 1066 - ER_INVALID_DEFAULT = 1067 - ER_MULTIPLE_PRI_KEY = 1068 - ER_TOO_MANY_KEYS = 1069 - ER_TOO_MANY_KEY_PARTS = 1070 - ER_TOO_LONG_KEY = 1071 - ER_KEY_COLUMN_DOES_NOT_EXITS = 1072 - ER_BLOB_USED_AS_KEY = 1073 - ER_TOO_BIG_FIELDLENGTH = 1074 - ER_WRONG_AUTO_KEY = 1075 - ER_READY = 1076 - ER_NORMAL_SHUTDOWN = 1077 - ER_GOT_SIGNAL = 1078 - ER_SHUTDOWN_COMPLETE = 1079 - ER_FORCING_CLOSE = 1080 - ER_IPSOCK_ERROR = 1081 - ER_NO_SUCH_INDEX = 1082 - ER_WRONG_FIELD_TERMINATORS = 1083 - ER_BLOBS_AND_NO_TERMINATED = 1084 - ER_TEXTFILE_NOT_READABLE = 1085 - ER_FILE_EXISTS_ERROR = 1086 - ER_LOAD_INFO = 1087 - ER_ALTER_INFO = 1088 - ER_WRONG_SUB_KEY = 1089 - ER_CANT_REMOVE_ALL_FIELDS = 1090 - ER_CANT_DROP_FIELD_OR_KEY = 1091 - ER_INSERT_INFO = 1092 - ER_INSERT_TABLE_USED = 1093 - ER_NO_SUCH_THREAD = 1094 - ER_KILL_DENIED_ERROR = 1095 - ER_NO_TABLES_USED = 1096 - ER_TOO_BIG_SET = 1097 - ER_NO_UNIQUE_LOGFILE = 1098 - ER_TABLE_NOT_LOCKED_FOR_WRITE = 1099 - ER_TABLE_NOT_LOCKED = 1100 - ER_BLOB_CANT_HAVE_DEFAULT = 1101 - ER_WRONG_DB_NAME = 1102 - ER_WRONG_TABLE_NAME = 1103 - ER_TOO_BIG_SELECT = 1104 - ER_UNKNOWN_ERROR = 1105 - ER_UNKNOWN_PROCEDURE = 1106 - ER_WRONG_PARAMCOUNT_TO_PROCEDURE = 1107 - ER_WRONG_PARAMETERS_TO_PROCEDURE = 1108 - ER_UNKNOWN_TABLE = 1109 - ER_FIELD_SPECIFIED_TWICE = 1110 - ER_INVALID_GROUP_FUNC_USE = 1111 - ER_UNSUPPORTED_EXTENSION = 1112 - ER_TABLE_MUST_HAVE_COLUMNS = 1113 - ER_RECORD_FILE_FULL = 1114 - ER_UNKNOWN_CHARACTER_SET = 1115 - ER_TOO_MANY_TABLES = 1116 - ER_TOO_MANY_FIELDS = 1117 - ER_TOO_BIG_ROWSIZE = 1118 - ER_STACK_OVERRUN = 1119 - ER_WRONG_OUTER_JOIN = 1120 - ER_NULL_COLUMN_IN_INDEX = 1121 - ER_CANT_FIND_UDF = 1122 - ER_CANT_INITIALIZE_UDF = 1123 - ER_UDF_NO_PATHS = 1124 - ER_UDF_EXISTS = 1125 - ER_CANT_OPEN_LIBRARY = 1126 - ER_CANT_FIND_DL_ENTRY = 1127 - ER_FUNCTION_NOT_DEFINED = 1128 - ER_HOST_IS_BLOCKED = 1129 - ER_HOST_NOT_PRIVILEGED = 1130 - ER_PASSWORD_ANONYMOUS_USER = 1131 - ER_PASSWORD_NOT_ALLOWED = 1132 - ER_PASSWORD_NO_MATCH = 1133 - ER_UPDATE_INFO = 1134 - ER_CANT_CREATE_THREAD = 1135 - ER_WRONG_VALUE_COUNT_ON_ROW = 1136 - ER_CANT_REOPEN_TABLE = 1137 - ER_INVALID_USE_OF_NULL = 1138 - ER_REGEXP_ERROR = 1139 - ER_MIX_OF_GROUP_FUNC_AND_FIELDS = 1140 - ER_NONEXISTING_GRANT = 1141 - ER_TABLEACCESS_DENIED_ERROR = 1142 - ER_COLUMNACCESS_DENIED_ERROR = 1143 - ER_ILLEGAL_GRANT_FOR_TABLE = 1144 - ER_GRANT_WRONG_HOST_OR_USER = 1145 - ER_NO_SUCH_TABLE = 1146 - ER_NONEXISTING_TABLE_GRANT = 1147 - ER_NOT_ALLOWED_COMMAND = 1148 - ER_SYNTAX_ERROR = 1149 - ER_DELAYED_CANT_CHANGE_LOCK = 1150 - ER_TOO_MANY_DELAYED_THREADS = 1151 - ER_ABORTING_CONNECTION = 1152 - ER_NET_PACKET_TOO_LARGE = 1153 - ER_NET_READ_ERROR_FROM_PIPE = 1154 - ER_NET_FCNTL_ERROR = 1155 - ER_NET_PACKETS_OUT_OF_ORDER = 1156 - ER_NET_UNCOMPRESS_ERROR = 1157 - ER_NET_READ_ERROR = 1158 - ER_NET_READ_INTERRUPTED = 1159 - ER_NET_ERROR_ON_WRITE = 1160 - ER_NET_WRITE_INTERRUPTED = 1161 - ER_TOO_LONG_STRING = 1162 - ER_TABLE_CANT_HANDLE_BLOB = 1163 - ER_TABLE_CANT_HANDLE_AUTO_INCREMENT = 1164 - ER_DELAYED_INSERT_TABLE_LOCKED = 1165 - ER_WRONG_COLUMN_NAME = 1166 - ER_WRONG_KEY_COLUMN = 1167 - ER_WRONG_MRG_TABLE = 1168 - ER_DUP_UNIQUE = 1169 - ER_BLOB_KEY_WITHOUT_LENGTH = 1170 - ER_PRIMARY_CANT_HAVE_NULL = 1171 - ER_TOO_MANY_ROWS = 1172 - ER_REQUIRES_PRIMARY_KEY = 1173 - ER_NO_RAID_COMPILED = 1174 - ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE = 1175 - ER_KEY_DOES_NOT_EXITS = 1176 - ER_CHECK_NO_SUCH_TABLE = 1177 - ER_CHECK_NOT_IMPLEMENTED = 1178 - ER_CANT_DO_THIS_DURING_AN_TRANSACTION = 1179 - ER_ERROR_DURING_COMMIT = 1180 - ER_ERROR_DURING_ROLLBACK = 1181 - ER_ERROR_DURING_FLUSH_LOGS = 1182 - ER_ERROR_DURING_CHECKPOINT = 1183 - ER_NEW_ABORTING_CONNECTION = 1184 - ER_DUMP_NOT_IMPLEMENTED = 1185 - ER_FLUSH_MASTER_BINLOG_CLOSED = 1186 - ER_INDEX_REBUILD = 1187 - ER_MASTER = 1188 - ER_MASTER_NET_READ = 1189 - ER_MASTER_NET_WRITE = 1190 - ER_FT_MATCHING_KEY_NOT_FOUND = 1191 - ER_LOCK_OR_ACTIVE_TRANSACTION = 1192 - ER_UNKNOWN_SYSTEM_VARIABLE = 1193 - ER_CRASHED_ON_USAGE = 1194 - ER_CRASHED_ON_REPAIR = 1195 - ER_WARNING_NOT_COMPLETE_ROLLBACK = 1196 - ER_TRANS_CACHE_FULL = 1197 - ER_SLAVE_MUST_STOP = 1198 - ER_SLAVE_NOT_RUNNING = 1199 - ER_BAD_SLAVE = 1200 - ER_MASTER_INFO = 1201 - ER_SLAVE_THREAD = 1202 - ER_TOO_MANY_USER_CONNECTIONS = 1203 - ER_SET_CONSTANTS_ONLY = 1204 - ER_LOCK_WAIT_TIMEOUT = 1205 - ER_LOCK_TABLE_FULL = 1206 - ER_READ_ONLY_TRANSACTION = 1207 - ER_DROP_DB_WITH_READ_LOCK = 1208 - ER_CREATE_DB_WITH_READ_LOCK = 1209 - ER_WRONG_ARGUMENTS = 1210 - ER_NO_PERMISSION_TO_CREATE_USER = 1211 - ER_UNION_TABLES_IN_DIFFERENT_DIR = 1212 - ER_LOCK_DEADLOCK = 1213 - ER_TABLE_CANT_HANDLE_FULLTEXT = 1214 - ER_CANNOT_ADD_FOREIGN = 1215 - ER_NO_REFERENCED_ROW = 1216 - ER_ROW_IS_REFERENCED = 1217 - ER_CONNECT_TO_MASTER = 1218 - ER_QUERY_ON_MASTER = 1219 - ER_ERROR_WHEN_EXECUTING_COMMAND = 1220 - ER_WRONG_USAGE = 1221 - ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT = 1222 - ER_CANT_UPDATE_WITH_READLOCK = 1223 - ER_MIXING_NOT_ALLOWED = 1224 - ER_DUP_ARGUMENT = 1225 - ER_USER_LIMIT_REACHED = 1226 - ER_SPECIFIC_ACCESS_DENIED_ERROR = 1227 - ER_LOCAL_VARIABLE = 1228 - ER_GLOBAL_VARIABLE = 1229 - ER_NO_DEFAULT = 1230 - ER_WRONG_VALUE_FOR_VAR = 1231 - ER_WRONG_TYPE_FOR_VAR = 1232 - ER_VAR_CANT_BE_READ = 1233 - ER_CANT_USE_OPTION_HERE = 1234 - ER_NOT_SUPPORTED_YET = 1235 - ER_MASTER_FATAL_ERROR_READING_BINLOG = 1236 - ER_SLAVE_IGNORED_TABLE = 1237 - ER_ERROR_MESSAGES = 238 - - # Client Error - CR_MIN_ERROR = 2000 - CR_MAX_ERROR = 2999 - CR_UNKNOWN_ERROR = 2000 - CR_SOCKET_CREATE_ERROR = 2001 - CR_CONNECTION_ERROR = 2002 - CR_CONN_HOST_ERROR = 2003 - CR_IPSOCK_ERROR = 2004 - CR_UNKNOWN_HOST = 2005 - CR_SERVER_GONE_ERROR = 2006 - CR_VERSION_ERROR = 2007 - CR_OUT_OF_MEMORY = 2008 - CR_WRONG_HOST_INFO = 2009 - CR_LOCALHOST_CONNECTION = 2010 - CR_TCP_CONNECTION = 2011 - CR_SERVER_HANDSHAKE_ERR = 2012 - CR_SERVER_LOST = 2013 - CR_COMMANDS_OUT_OF_SYNC = 2014 - CR_NAMEDPIPE_CONNECTION = 2015 - CR_NAMEDPIPEWAIT_ERROR = 2016 - CR_NAMEDPIPEOPEN_ERROR = 2017 - CR_NAMEDPIPESETSTATE_ERROR = 2018 - CR_CANT_READ_CHARSET = 2019 - CR_NET_PACKET_TOO_LARGE = 2020 - CR_EMBEDDED_CONNECTION = 2021 - CR_PROBE_SLAVE_STATUS = 2022 - CR_PROBE_SLAVE_HOSTS = 2023 - CR_PROBE_SLAVE_CONNECT = 2024 - CR_PROBE_MASTER_CONNECT = 2025 - CR_SSL_CONNECTION_ERROR = 2026 - CR_MALFORMED_PACKET = 2027 - - CLIENT_ERRORS = [ - "Unknown MySQL error", - "Can't create UNIX socket (%d)", - "Can't connect to local MySQL server through socket '%-.64s' (%d)", - "Can't connect to MySQL server on '%-.64s' (%d)", - "Can't create TCP/IP socket (%d)", - "Unknown MySQL Server Host '%-.64s' (%d)", - "MySQL server has gone away", - "Protocol mismatch. Server Version = %d Client Version = %d", - "MySQL client run out of memory", - "Wrong host info", - "Localhost via UNIX socket", - "%-.64s via TCP/IP", - "Error in server handshake", - "Lost connection to MySQL server during query", - "Commands out of sync; You can't run this command now", - "%-.64s via named pipe", - "Can't wait for named pipe to host: %-.64s pipe: %-.32s (%lu)", - "Can't open named pipe to host: %-.64s pipe: %-.32s (%lu)", - "Can't set state of named pipe to host: %-.64s pipe: %-.32s (%lu)", - "Can't initialize character set %-.64s (path: %-.64s)", - "Got packet bigger than 'max_allowed_packet'", - "Embedded server", - "Error on SHOW SLAVE STATUS:", - "Error on SHOW SLAVE HOSTS:", - "Error connecting to slave:", - "Error connecting to master:", - "SSL connection error", - "Malformed packet" - ] - - def initialize(errno, error) - @errno = errno - @error = error - super error - end - attr_reader :errno, :error - - def Error::err(errno) - CLIENT_ERRORS[errno - Error::CR_MIN_ERROR] - end - end - - class Net - def initialize(sock) - @sock = sock - @pkt_nr = 0 - end - - def clear() - @pkt_nr = 0 - end - - def read() - buf = [] - len = nil - @sock.sync = false - while len == nil or len == MAX_PACKET_LENGTH do - a = @sock.read(4) - len = a[0]+a[1]*256+a[2]*256*256 - pkt_nr = a[3] - if @pkt_nr != pkt_nr then - raise "Packets out of order: #{@pkt_nr}<>#{pkt_nr}" - end - @pkt_nr = @pkt_nr + 1 & 0xff - buf << @sock.read(len) - end - @sock.sync = true - buf.join - rescue - errno = Error::CR_SERVER_LOST - raise Error::new(errno, Error::err(errno)) - end - - def write(data) - if data.is_a? Array then - data = data.join - end - @sock.sync = false - ptr = 0 - while data.length >= MAX_PACKET_LENGTH do - @sock.write Net::int3str(MAX_PACKET_LENGTH)+@pkt_nr.chr+data[ptr, MAX_PACKET_LENGTH] - @pkt_nr = @pkt_nr + 1 & 0xff - ptr += MAX_PACKET_LENGTH - end - @sock.write Net::int3str(data.length-ptr)+@pkt_nr.chr+data[ptr .. -1] - @pkt_nr = @pkt_nr + 1 & 0xff - @sock.sync = true - @sock.flush - rescue - errno = Error::CR_SERVER_LOST - raise Error::new(errno, Error::err(errno)) - end - - def close() - @sock.close - end - - def Net::int2str(n) - [n].pack("v") - end - - def Net::int3str(n) - [n%256, n>>8].pack("cv") - end - - def Net::int4str(n) - [n].pack("V") - end - - end - - class Random - def initialize(seed1, seed2) - @max_value = 0x3FFFFFFF - @seed1 = seed1 % @max_value - @seed2 = seed2 % @max_value - end - - def rnd() - @seed1 = (@seed1*3+@seed2) % @max_value - @seed2 = (@seed1+@seed2+33) % @max_value - @seed1.to_f / @max_value - end - end - -end - -class << Mysql - def init() - Mysql::new :INIT - end - - def real_connect(*args) - Mysql::new(*args) - end - alias :connect :real_connect - - def finalizer(net) - proc { - net.clear - net.write Mysql::COM_QUIT.chr - } - end - - def escape_string(str) - str.gsub(/([\0\n\r\032\'\"\\])/) do - case $1 - when "\0" then "\\0" - when "\n" then "\\n" - when "\r" then "\\r" - when "\032" then "\\Z" - else "\\"+$1 - end - end - end - alias :quote :escape_string - - def get_client_info() - Mysql::VERSION - end - alias :client_info :get_client_info - - def debug(str) - raise "not implemented" - end -end - -# -# for compatibility -# - -MysqlRes = Mysql::Result -MysqlField = Mysql::Field -MysqlError = Mysql::Error diff --git a/tracks/vendor/rails/activerecord/lib/active_record/vendor/simple.rb b/tracks/vendor/rails/activerecord/lib/active_record/vendor/simple.rb deleted file mode 100644 index 1bd332c8..00000000 --- a/tracks/vendor/rails/activerecord/lib/active_record/vendor/simple.rb +++ /dev/null @@ -1,702 +0,0 @@ -# :title: Transaction::Simple -# -# == Licence -# -# 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. -#-- -# Transaction::Simple -# Simple object transaction support for Ruby -# Version 1.11 -# -# Copyright (c) 2003 Austin Ziegler -# -# $Id: simple.rb,v 1.2 2004/08/20 13:56:37 webster132 Exp $ -# -# ========================================================================== -# Revision History :: -# YYYY.MM.DD Change ID Developer -# Description -# -------------------------------------------------------------------------- -# 2003.07.29 Austin Ziegler -# Added debugging capabilities and VERSION string. -# 2003.08.21 Austin Ziegler -# Added named transactions. -# -# ========================================================================== -#++ -require 'thread' - - # The "Transaction" namespace can be used for additional transactional - # support objects and modules. -module Transaction - - # A standard exception for transactional errors. - class TransactionError < StandardError; end - # A standard exception for transactional errors involving the acquisition - # of locks for Transaction::Simple::ThreadSafe. - class TransactionThreadError < StandardError; end - - # = Transaction::Simple for Ruby - # Simple object transaction support for Ruby - # - # == Introduction - # - # Transaction::Simple provides a generic way to add active transactional - # support to objects. The transaction methods added by this module will - # work with most objects, excluding those that cannot be Marshaled - # (bindings, procedure objects, IO instances, or singleton objects). - # - # The transactions supported by Transaction::Simple are not backed - # transactions; that is, they have nothing to do with any sort of data - # store. They are "live" transactions occurring in memory and in the - # object itself. This is to allow "test" changes to be made to an object - # before making the changes permanent. - # - # Transaction::Simple can handle an "infinite" number of transactional - # levels (limited only by memory). If I open two transactions, commit the - # first, but abort the second, the object will revert to the original - # version. - # - # Transaction::Simple supports "named" transactions, so that multiple - # levels of transactions can be committed, aborted, or rewound by - # referring to the appropriate name of the transaction. Names may be any - # object *except* +nil+. - # - # Copyright:: Copyright © 2003 by Austin Ziegler - # Version:: 1.1 - # Licence:: MIT-Style - # - # Thanks to David Black for help with the initial concept that led to this - # library. - # - # == Usage - # include 'transaction/simple' - # - # v = "Hello, you." # => "Hello, you." - # v.extend(Transaction::Simple) # => "Hello, you." - # - # v.start_transaction # => ... (a Marshal string) - # v.transaction_open? # => true - # v.gsub!(/you/, "world") # => "Hello, world." - # - # v.rewind_transaction # => "Hello, you." - # v.transaction_open? # => true - # - # v.gsub!(/you/, "HAL") # => "Hello, HAL." - # v.abort_transaction # => "Hello, you." - # v.transaction_open? # => false - # - # v.start_transaction # => ... (a Marshal string) - # v.start_transaction # => ... (a Marshal string) - # - # v.transaction_open? # => true - # v.gsub!(/you/, "HAL") # => "Hello, HAL." - # - # v.commit_transaction # => "Hello, HAL." - # v.transaction_open? # => true - # v.abort_transaction # => "Hello, you." - # v.transaction_open? # => false - # - # == Named Transaction Usage - # v = "Hello, you." # => "Hello, you." - # v.extend(Transaction::Simple) # => "Hello, you." - # - # v.start_transaction(:first) # => ... (a Marshal string) - # v.transaction_open? # => true - # v.transaction_open?(:first) # => true - # v.transaction_open?(:second) # => false - # v.gsub!(/you/, "world") # => "Hello, world." - # - # v.start_transaction(:second) # => ... (a Marshal string) - # v.gsub!(/world/, "HAL") # => "Hello, HAL." - # v.rewind_transaction(:first) # => "Hello, you." - # v.transaction_open? # => true - # v.transaction_open?(:first) # => true - # v.transaction_open?(:second) # => false - # - # v.gsub!(/you/, "world") # => "Hello, world." - # v.start_transaction(:second) # => ... (a Marshal string) - # v.gsub!(/world/, "HAL") # => "Hello, HAL." - # v.transaction_name # => :second - # v.abort_transaction(:first) # => "Hello, you." - # v.transaction_open? # => false - # - # v.start_transaction(:first) # => ... (a Marshal string) - # v.gsub!(/you/, "world") # => "Hello, world." - # v.start_transaction(:second) # => ... (a Marshal string) - # v.gsub!(/world/, "HAL") # => "Hello, HAL." - # - # v.commit_transaction(:first) # => "Hello, HAL." - # v.transaction_open? # => false - # - # == Contraindications - # - # While Transaction::Simple is very useful, it has some severe limitations - # that must be understood. Transaction::Simple: - # - # * uses Marshal. Thus, any object which cannot be Marshaled cannot - # use Transaction::Simple. - # * does not manage resources. Resources external to the object and its - # instance variables are not managed at all. However, all instance - # variables and objects "belonging" to those instance variables are - # managed. If there are object reference counts to be handled, - # Transaction::Simple will probably cause problems. - # * is not inherently thread-safe. In the ACID ("atomic, consistent, - # isolated, durable") test, Transaction::Simple provides CD, but it is - # up to the user of Transaction::Simple to provide isolation and - # atomicity. Transactions should be considered "critical sections" in - # multi-threaded applications. If thread safety and atomicity is - # absolutely required, use Transaction::Simple::ThreadSafe, which uses a - # Mutex object to synchronize the accesses on the object during the - # transactional operations. - # * does not necessarily maintain Object#__id__ values on rewind or abort. - # This may change for future versions that will be Ruby 1.8 or better - # *only*. Certain objects that support #replace will maintain - # Object#__id__. - # * Can be a memory hog if you use many levels of transactions on many - # objects. - # - module Simple - VERSION = '1.1.1.0'; - - # Sets the Transaction::Simple debug object. It must respond to #<<. - # Sets the transaction debug object. Debugging will be performed - # automatically if there's a debug object. The generic transaction error - # class. - def self.debug_io=(io) - raise TransactionError, "Transaction Error: the transaction debug object must respond to #<<" unless io.respond_to?(:<<) - @tdi = io - end - - # Returns the Transaction::Simple debug object. It must respond to #<<. - def self.debug_io - @tdi - end - - # If +name+ is +nil+ (default), then returns +true+ if there is - # currently a transaction open. - # - # If +name+ is specified, then returns +true+ if there is currently a - # transaction that responds to +name+ open. - def transaction_open?(name = nil) - if name.nil? - Transaction::Simple.debug_io << "Transaction [#{(@__transaction_checkpoint__.nil?) ? 'closed' : 'open'}]\n" unless Transaction::Simple.debug_io.nil? - return (not @__transaction_checkpoint__.nil?) - else - Transaction::Simple.debug_io << "Transaction(#{name.inspect}) [#{(@__transaction_checkpoint__.nil?) ? 'closed' : 'open'}]\n" unless Transaction::Simple.debug_io.nil? - return ((not @__transaction_checkpoint__.nil?) and @__transaction_names__.include?(name)) - end - end - - # Returns the current name of the transaction. Transactions not - # explicitly named are named +nil+. - def transaction_name - raise TransactionError, "Transaction Error: No transaction open." if @__transaction_checkpoint__.nil? - Transaction::Simple.debug_io << "#{'|' * @__transaction_level__} Transaction Name: #{@__transaction_names__[-1].inspect}\n" unless Transaction::Simple.debug_io.nil? - @__transaction_names__[-1] - end - - # Starts a transaction. Stores the current object state. If a - # transaction name is specified, the transaction will be named. - # Transaction names must be unique. Transaction names of +nil+ will be - # treated as unnamed transactions. - def start_transaction(name = nil) - @__transaction_level__ ||= 0 - @__transaction_names__ ||= [] - - if name.nil? - @__transaction_names__ << nil - s = "" - else - raise TransactionError, "Transaction Error: Named transactions must be unique." if @__transaction_names__.include?(name) - @__transaction_names__ << name - s = "(#{name.inspect})" - end - - @__transaction_level__ += 1 - - Transaction::Simple.debug_io << "#{'>' * @__transaction_level__} Start Transaction#{s}\n" unless Transaction::Simple.debug_io.nil? - - @__transaction_checkpoint__ = Marshal.dump(self) - end - - # Rewinds the transaction. If +name+ is specified, then the intervening - # transactions will be aborted and the named transaction will be - # rewound. Otherwise, only the current transaction is rewound. - def rewind_transaction(name = nil) - raise TransactionError, "Transaction Error: Cannot rewind. There is no current transaction." if @__transaction_checkpoint__.nil? - if name.nil? - __rewind_this_transaction - s = "" - else - raise TransactionError, "Transaction Error: Cannot rewind to transaction #{name.inspect} because it does not exist." unless @__transaction_names__.include?(name) - s = "(#{name})" - - while @__transaction_names__[-1] != name - @__transaction_checkpoint__ = __rewind_this_transaction - Transaction::Simple.debug_io << "#{'|' * @__transaction_level__} Rewind Transaction#{s}\n" unless Transaction::Simple.debug_io.nil? - @__transaction_level__ -= 1 - @__transaction_names__.pop - end - __rewind_this_transaction - end - Transaction::Simple.debug_io << "#{'|' * @__transaction_level__} Rewind Transaction#{s}\n" unless Transaction::Simple.debug_io.nil? - self - end - - # Aborts the transaction. Resets the object state to what it was before - # the transaction was started and closes the transaction. If +name+ is - # specified, then the intervening transactions and the named transaction - # will be aborted. Otherwise, only the current transaction is aborted. - def abort_transaction(name = nil) - raise TransactionError, "Transaction Error: Cannot abort. There is no current transaction." if @__transaction_checkpoint__.nil? - if name.nil? - __abort_transaction(name) - else - raise TransactionError, "Transaction Error: Cannot abort nonexistant transaction #{name.inspect}." unless @__transaction_names__.include?(name) - - __abort_transaction(name) while @__transaction_names__.include?(name) - end - self - end - - # If +name+ is +nil+ (default), the current transaction level is closed - # out and the changes are committed. - # - # If +name+ is specified and +name+ is in the list of named - # transactions, then all transactions are closed and committed until the - # named transaction is reached. - def commit_transaction(name = nil) - raise TransactionError, "Transaction Error: Cannot commit. There is no current transaction." if @__transaction_checkpoint__.nil? - - if name.nil? - s = "" - __commit_transaction - Transaction::Simple.debug_io << "#{'<' * @__transaction_level__} Commit Transaction#{s}\n" unless Transaction::Simple.debug_io.nil? - else - raise TransactionError, "Transaction Error: Cannot commit nonexistant transaction #{name.inspect}." unless @__transaction_names__.include?(name) - s = "(#{name})" - - while @__transaction_names__[-1] != name - Transaction::Simple.debug_io << "#{'<' * @__transaction_level__} Commit Transaction#{s}\n" unless Transaction::Simple.debug_io.nil? - __commit_transaction - end - Transaction::Simple.debug_io << "#{'<' * @__transaction_level__} Commit Transaction#{s}\n" unless Transaction::Simple.debug_io.nil? - __commit_transaction - end - self - end - - # Alternative method for calling the transaction methods. An optional - # name can be specified for named transaction support. - # - # #transaction(:start):: #start_transaction - # #transaction(:rewind):: #rewind_transaction - # #transaction(:abort):: #abort_transaction - # #transaction(:commit):: #commit_transaction - # #transaction(:name):: #transaction_name - # #transaction:: #transaction_open? - def transaction(action = nil, name = nil) - case action - when :start - start_transaction(name) - when :rewind - rewind_transaction(name) - when :abort - abort_transaction(name) - when :commit - commit_transaction(name) - when :name - transaction_name - when nil - transaction_open?(name) - end - end - - def __abort_transaction(name = nil) #:nodoc: - @__transaction_checkpoint__ = __rewind_this_transaction - - if name.nil? - s = "" - else - s = "(#{name.inspect})" - end - - Transaction::Simple.debug_io << "#{'<' * @__transaction_level__} Abort Transaction#{s}\n" unless Transaction::Simple.debug_io.nil? - @__transaction_level__ -= 1 - @__transaction_names__.pop - if @__transaction_level__ < 1 - @__transaction_level__ = 0 - @__transaction_names__ = [] - end - end - - TRANSACTION_CHECKPOINT = "@__transaction_checkpoint__" #:nodoc: - SKIP_TRANSACTION_VARS = [TRANSACTION_CHECKPOINT, "@__transaction_level__"] #:nodoc: - - def __rewind_this_transaction #:nodoc: - r = Marshal.restore(@__transaction_checkpoint__) - - begin - self.replace(r) if respond_to?(:replace) - rescue - nil - end - - r.instance_variables.each do |i| - next if SKIP_TRANSACTION_VARS.include?(i) - if respond_to?(:instance_variable_get) - instance_variable_set(i, r.instance_variable_get(i)) - else - instance_eval(%q|#{i} = r.instance_eval("#{i}")|) - end - end - - if respond_to?(:instance_variable_get) - return r.instance_variable_get(TRANSACTION_CHECKPOINT) - else - return r.instance_eval(TRANSACTION_CHECKPOINT) - end - end - - def __commit_transaction #:nodoc: - if respond_to?(:instance_variable_get) - @__transaction_checkpoint__ = Marshal.restore(@__transaction_checkpoint__).instance_variable_get(TRANSACTION_CHECKPOINT) - else - @__transaction_checkpoint__ = Marshal.restore(@__transaction_checkpoint__).instance_eval(TRANSACTION_CHECKPOINT) - end - - @__transaction_level__ -= 1 - @__transaction_names__.pop - if @__transaction_level__ < 1 - @__transaction_level__ = 0 - @__transaction_names__ = [] - end - end - - private :__abort_transaction, :__rewind_this_transaction, :__commit_transaction - - # = Transaction::Simple::ThreadSafe - # Thread-safe simple object transaction support for Ruby. - # Transaction::Simple::ThreadSafe is used in the same way as - # Transaction::Simple. Transaction::Simple::ThreadSafe uses a Mutex - # object to ensure atomicity at the cost of performance in threaded - # applications. - # - # Transaction::Simple::ThreadSafe will not wait to obtain a lock; if the - # lock cannot be obtained immediately, a - # Transaction::TransactionThreadError will be raised. - # - # Thanks to Mauricio Fernández for help with getting this part working. - module ThreadSafe - VERSION = '1.1.1.0'; - - include Transaction::Simple - - SKIP_TRANSACTION_VARS = Transaction::Simple::SKIP_TRANSACTION_VARS.dup #:nodoc: - SKIP_TRANSACTION_VARS << "@__transaction_mutex__" - - Transaction::Simple.instance_methods(false) do |meth| - next if meth == "transaction" - arg = "(name = nil)" unless meth == "transaction_name" - module_eval <<-EOS - def #{meth}#{arg} - if (@__transaction_mutex__ ||= Mutex.new).try_lock - result = super - @__transaction_mutex__.unlock - return result - else - raise TransactionThreadError, "Transaction Error: Cannot obtain lock for ##{meth}" - end - ensure - @__transaction_mutex__.unlock - end - EOS - end - end - end -end - -if $0 == __FILE__ - require 'test/unit' - - class Test__Transaction_Simple < Test::Unit::TestCase #:nodoc: - VALUE = "Now is the time for all good men to come to the aid of their country." - - def setup - @value = VALUE.dup - @value.extend(Transaction::Simple) - end - - def test_extended - assert_respond_to(@value, :start_transaction) - end - - def test_started - assert_equal(false, @value.transaction_open?) - assert_nothing_raised { @value.start_transaction } - assert_equal(true, @value.transaction_open?) - end - - def test_rewind - assert_equal(false, @value.transaction_open?) - assert_raises(Transaction::TransactionError) { @value.rewind_transaction } - assert_nothing_raised { @value.start_transaction } - assert_equal(true, @value.transaction_open?) - assert_nothing_raised { @value.gsub!(/men/, 'women') } - assert_not_equal(VALUE, @value) - assert_nothing_raised { @value.rewind_transaction } - assert_equal(true, @value.transaction_open?) - assert_equal(VALUE, @value) - end - - def test_abort - assert_equal(false, @value.transaction_open?) - assert_raises(Transaction::TransactionError) { @value.abort_transaction } - assert_nothing_raised { @value.start_transaction } - assert_equal(true, @value.transaction_open?) - assert_nothing_raised { @value.gsub!(/men/, 'women') } - assert_not_equal(VALUE, @value) - assert_nothing_raised { @value.abort_transaction } - assert_equal(false, @value.transaction_open?) - assert_equal(VALUE, @value) - end - - def test_commit - assert_equal(false, @value.transaction_open?) - assert_raises(Transaction::TransactionError) { @value.commit_transaction } - assert_nothing_raised { @value.start_transaction } - assert_equal(true, @value.transaction_open?) - assert_nothing_raised { @value.gsub!(/men/, 'women') } - assert_not_equal(VALUE, @value) - assert_equal(true, @value.transaction_open?) - assert_nothing_raised { @value.commit_transaction } - assert_equal(false, @value.transaction_open?) - assert_not_equal(VALUE, @value) - end - - def test_multilevel - assert_equal(false, @value.transaction_open?) - assert_nothing_raised { @value.start_transaction } - assert_equal(true, @value.transaction_open?) - assert_nothing_raised { @value.gsub!(/men/, 'women') } - assert_equal(VALUE.gsub(/men/, 'women'), @value) - assert_equal(true, @value.transaction_open?) - assert_nothing_raised { @value.start_transaction } - assert_nothing_raised { @value.gsub!(/country/, 'nation-state') } - assert_nothing_raised { @value.commit_transaction } - assert_equal(VALUE.gsub(/men/, 'women').gsub(/country/, 'nation-state'), @value) - assert_equal(true, @value.transaction_open?) - assert_nothing_raised { @value.abort_transaction } - assert_equal(VALUE, @value) - end - - def test_multilevel_named - assert_equal(false, @value.transaction_open?) - assert_raises(Transaction::TransactionError) { @value.transaction_name } - assert_nothing_raised { @value.start_transaction(:first) } # 1 - assert_raises(Transaction::TransactionError) { @value.start_transaction(:first) } - assert_equal(true, @value.transaction_open?) - assert_equal(true, @value.transaction_open?(:first)) - assert_equal(:first, @value.transaction_name) - assert_nothing_raised { @value.start_transaction } # 2 - assert_not_equal(:first, @value.transaction_name) - assert_equal(nil, @value.transaction_name) - assert_raises(Transaction::TransactionError) { @value.abort_transaction(:second) } - assert_nothing_raised { @value.abort_transaction(:first) } - assert_equal(false, @value.transaction_open?) - assert_nothing_raised do - @value.start_transaction(:first) - @value.gsub!(/men/, 'women') - @value.start_transaction(:second) - @value.gsub!(/women/, 'people') - @value.start_transaction - @value.gsub!(/people/, 'sentients') - end - assert_nothing_raised { @value.abort_transaction(:second) } - assert_equal(true, @value.transaction_open?(:first)) - assert_equal(VALUE.gsub(/men/, 'women'), @value) - assert_nothing_raised do - @value.start_transaction(:second) - @value.gsub!(/women/, 'people') - @value.start_transaction - @value.gsub!(/people/, 'sentients') - end - assert_raises(Transaction::TransactionError) { @value.rewind_transaction(:foo) } - assert_nothing_raised { @value.rewind_transaction(:second) } - assert_equal(VALUE.gsub(/men/, 'women'), @value) - assert_nothing_raised do - @value.gsub!(/women/, 'people') - @value.start_transaction - @value.gsub!(/people/, 'sentients') - end - assert_raises(Transaction::TransactionError) { @value.commit_transaction(:foo) } - assert_nothing_raised { @value.commit_transaction(:first) } - assert_equal(VALUE.gsub(/men/, 'sentients'), @value) - assert_equal(false, @value.transaction_open?) - end - - def test_array - assert_nothing_raised do - @orig = ["first", "second", "third"] - @value = ["first", "second", "third"] - @value.extend(Transaction::Simple) - end - assert_equal(@orig, @value) - assert_nothing_raised { @value.start_transaction } - assert_equal(true, @value.transaction_open?) - assert_nothing_raised { @value[1].gsub!(/second/, "fourth") } - assert_not_equal(@orig, @value) - assert_nothing_raised { @value.abort_transaction } - assert_equal(@orig, @value) - end - end - - class Test__Transaction_Simple_ThreadSafe < Test::Unit::TestCase #:nodoc: - VALUE = "Now is the time for all good men to come to the aid of their country." - - def setup - @value = VALUE.dup - @value.extend(Transaction::Simple::ThreadSafe) - end - - def test_extended - assert_respond_to(@value, :start_transaction) - end - - def test_started - assert_equal(false, @value.transaction_open?) - assert_nothing_raised { @value.start_transaction } - assert_equal(true, @value.transaction_open?) - end - - def test_rewind - assert_equal(false, @value.transaction_open?) - assert_raises(Transaction::TransactionError) { @value.rewind_transaction } - assert_nothing_raised { @value.start_transaction } - assert_equal(true, @value.transaction_open?) - assert_nothing_raised { @value.gsub!(/men/, 'women') } - assert_not_equal(VALUE, @value) - assert_nothing_raised { @value.rewind_transaction } - assert_equal(true, @value.transaction_open?) - assert_equal(VALUE, @value) - end - - def test_abort - assert_equal(false, @value.transaction_open?) - assert_raises(Transaction::TransactionError) { @value.abort_transaction } - assert_nothing_raised { @value.start_transaction } - assert_equal(true, @value.transaction_open?) - assert_nothing_raised { @value.gsub!(/men/, 'women') } - assert_not_equal(VALUE, @value) - assert_nothing_raised { @value.abort_transaction } - assert_equal(false, @value.transaction_open?) - assert_equal(VALUE, @value) - end - - def test_commit - assert_equal(false, @value.transaction_open?) - assert_raises(Transaction::TransactionError) { @value.commit_transaction } - assert_nothing_raised { @value.start_transaction } - assert_equal(true, @value.transaction_open?) - assert_nothing_raised { @value.gsub!(/men/, 'women') } - assert_not_equal(VALUE, @value) - assert_equal(true, @value.transaction_open?) - assert_nothing_raised { @value.commit_transaction } - assert_equal(false, @value.transaction_open?) - assert_not_equal(VALUE, @value) - end - - def test_multilevel - assert_equal(false, @value.transaction_open?) - assert_nothing_raised { @value.start_transaction } - assert_equal(true, @value.transaction_open?) - assert_nothing_raised { @value.gsub!(/men/, 'women') } - assert_equal(VALUE.gsub(/men/, 'women'), @value) - assert_equal(true, @value.transaction_open?) - assert_nothing_raised { @value.start_transaction } - assert_nothing_raised { @value.gsub!(/country/, 'nation-state') } - assert_nothing_raised { @value.commit_transaction } - assert_equal(VALUE.gsub(/men/, 'women').gsub(/country/, 'nation-state'), @value) - assert_equal(true, @value.transaction_open?) - assert_nothing_raised { @value.abort_transaction } - assert_equal(VALUE, @value) - end - - def test_multilevel_named - assert_equal(false, @value.transaction_open?) - assert_raises(Transaction::TransactionError) { @value.transaction_name } - assert_nothing_raised { @value.start_transaction(:first) } # 1 - assert_raises(Transaction::TransactionError) { @value.start_transaction(:first) } - assert_equal(true, @value.transaction_open?) - assert_equal(true, @value.transaction_open?(:first)) - assert_equal(:first, @value.transaction_name) - assert_nothing_raised { @value.start_transaction } # 2 - assert_not_equal(:first, @value.transaction_name) - assert_equal(nil, @value.transaction_name) - assert_raises(Transaction::TransactionError) { @value.abort_transaction(:second) } - assert_nothing_raised { @value.abort_transaction(:first) } - assert_equal(false, @value.transaction_open?) - assert_nothing_raised do - @value.start_transaction(:first) - @value.gsub!(/men/, 'women') - @value.start_transaction(:second) - @value.gsub!(/women/, 'people') - @value.start_transaction - @value.gsub!(/people/, 'sentients') - end - assert_nothing_raised { @value.abort_transaction(:second) } - assert_equal(true, @value.transaction_open?(:first)) - assert_equal(VALUE.gsub(/men/, 'women'), @value) - assert_nothing_raised do - @value.start_transaction(:second) - @value.gsub!(/women/, 'people') - @value.start_transaction - @value.gsub!(/people/, 'sentients') - end - assert_raises(Transaction::TransactionError) { @value.rewind_transaction(:foo) } - assert_nothing_raised { @value.rewind_transaction(:second) } - assert_equal(VALUE.gsub(/men/, 'women'), @value) - assert_nothing_raised do - @value.gsub!(/women/, 'people') - @value.start_transaction - @value.gsub!(/people/, 'sentients') - end - assert_raises(Transaction::TransactionError) { @value.commit_transaction(:foo) } - assert_nothing_raised { @value.commit_transaction(:first) } - assert_equal(VALUE.gsub(/men/, 'sentients'), @value) - assert_equal(false, @value.transaction_open?) - end - - def test_array - assert_nothing_raised do - @orig = ["first", "second", "third"] - @value = ["first", "second", "third"] - @value.extend(Transaction::Simple::ThreadSafe) - end - assert_equal(@orig, @value) - assert_nothing_raised { @value.start_transaction } - assert_equal(true, @value.transaction_open?) - assert_nothing_raised { @value[1].gsub!(/second/, "fourth") } - assert_not_equal(@orig, @value) - assert_nothing_raised { @value.abort_transaction } - assert_equal(@orig, @value) - end - end -end diff --git a/tracks/vendor/rails/activerecord/lib/active_record/version.rb b/tracks/vendor/rails/activerecord/lib/active_record/version.rb deleted file mode 100644 index 6abddb37..00000000 --- a/tracks/vendor/rails/activerecord/lib/active_record/version.rb +++ /dev/null @@ -1,9 +0,0 @@ -module ActiveRecord - module VERSION #:nodoc: - MAJOR = 1 - MINOR = 13 - TINY = 2 - - STRING = [MAJOR, MINOR, TINY].join('.') - end -end diff --git a/tracks/vendor/rails/activerecord/lib/active_record/wrappers/yaml_wrapper.rb b/tracks/vendor/rails/activerecord/lib/active_record/wrappers/yaml_wrapper.rb deleted file mode 100644 index 74f40a50..00000000 --- a/tracks/vendor/rails/activerecord/lib/active_record/wrappers/yaml_wrapper.rb +++ /dev/null @@ -1,15 +0,0 @@ -require 'yaml' - -module ActiveRecord - module Wrappings #:nodoc: - class YamlWrapper < AbstractWrapper #:nodoc: - def wrap(attribute) attribute.to_yaml end - def unwrap(attribute) YAML::load(attribute) end - end - - module ClassMethods #:nodoc: - # Wraps the attribute in Yaml encoding - def wrap_in_yaml(*attributes) wrap_with(YamlWrapper, attributes) end - end - end -end \ No newline at end of file diff --git a/tracks/vendor/rails/activerecord/lib/active_record/wrappings.rb b/tracks/vendor/rails/activerecord/lib/active_record/wrappings.rb deleted file mode 100644 index 01976417..00000000 --- a/tracks/vendor/rails/activerecord/lib/active_record/wrappings.rb +++ /dev/null @@ -1,59 +0,0 @@ -module ActiveRecord - # A plugin framework for wrapping attribute values before they go in and unwrapping them after they go out of the database. - # This was intended primarily for YAML wrapping of arrays and hashes, but this behavior is now native in the Base class. - # So for now this framework is laying dormant until a need pops up. - module Wrappings #:nodoc: - module ClassMethods #:nodoc: - def wrap_with(wrapper, *attributes) - [ attributes ].flat.each { |attribute| wrapper.wrap(attribute) } - end - end - - def self.append_features(base) - super - base.extend(ClassMethods) - end - - class AbstractWrapper #:nodoc: - def self.wrap(attribute, record_binding) #:nodoc: - %w( before_save after_save after_initialize ).each do |callback| - eval "#{callback} #{name}.new('#{attribute}')", record_binding - end - end - - def initialize(attribute) #:nodoc: - @attribute = attribute - end - - def save_wrapped_attribute(record) #:nodoc: - if record.attribute_present?(@attribute) - record.send( - "write_attribute", - @attribute, - wrap(record.send("read_attribute", @attribute)) - ) - end - end - - def load_wrapped_attribute(record) #:nodoc: - if record.attribute_present?(@attribute) - record.send( - "write_attribute", - @attribute, - unwrap(record.send("read_attribute", @attribute)) - ) - end - end - - alias_method :before_save, :save_wrapped_attribute #:nodoc: - alias_method :after_save, :load_wrapped_attribute #:nodoc: - alias_method :after_initialize, :after_save #:nodoc: - - # Overwrite to implement the logic that'll take the regular attribute and wrap it. - def wrap(attribute) end - - # Overwrite to implement the logic that'll take the wrapped attribute and unwrap it. - def unwrap(attribute) end - end - end -end diff --git a/tracks/vendor/rails/activerecord/rakefile b/tracks/vendor/rails/activerecord/rakefile deleted file mode 100644 index 5d146cec..00000000 --- a/tracks/vendor/rails/activerecord/rakefile +++ /dev/null @@ -1,285 +0,0 @@ -require 'rubygems' -require 'rake' -require 'rake/testtask' -require 'rake/rdoctask' -require 'rake/packagetask' -require 'rake/gempackagetask' -require 'rake/contrib/rubyforgepublisher' -require File.join(File.dirname(__FILE__), 'lib', 'active_record', 'version') - -PKG_BUILD = ENV['PKG_BUILD'] ? '.' + ENV['PKG_BUILD'] : '' -PKG_NAME = 'activerecord' -PKG_VERSION = ActiveRecord::VERSION::STRING + PKG_BUILD -PKG_FILE_NAME = "#{PKG_NAME}-#{PKG_VERSION}" - -RELEASE_NAME = "REL #{PKG_VERSION}" - -RUBY_FORGE_PROJECT = "activerecord" -RUBY_FORGE_USER = "webster132" - -PKG_FILES = FileList[ - "lib/**/*", "test/**/*", "examples/**/*", "doc/**/*", "[A-Z]*", "install.rb", "rakefile" -].exclude(/\bCVS\b|~$/) - - -desc "Default Task" -task :default => [ :test_mysql, :test_sqlite, :test_postgresql ] - -# Run the unit tests - -for adapter in %w( mysql postgresql sqlite sqlite3 firebird sqlserver sqlserver_odbc db2 oci ) - Rake::TestTask.new("test_#{adapter}") { |t| - t.libs << "test" << "test/connections/native_#{adapter}" - t.pattern = "test/*_test{,_#{adapter}}.rb" - t.verbose = true - } -end - -SCHEMA_PATH = File.join(File.dirname(__FILE__), *%w(test fixtures db_definitions)) - -desc 'Build the MySQL test databases' -task :build_mysql_databases do - %x( mysqladmin create activerecord_unittest ) - %x( mysqladmin create activerecord_unittest2 ) - %x( mysql activerecord_unittest < #{File.join(SCHEMA_PATH, 'mysql.sql')} ) - %x( mysql activerecord_unittest < #{File.join(SCHEMA_PATH, 'mysql2.sql')} ) -end - -desc 'Drop the MySQL test databases' -task :drop_mysql_databases do - %x( mysqladmin -f drop activerecord_unittest ) - %x( mysqladmin -f drop activerecord_unittest2 ) -end - -desc 'Rebuild the MySQL test databases' -task :rebuild_mysql_databases => [:drop_mysql_databases, :build_mysql_databases] - -desc 'Build the PostgreSQL test databases' -task :build_postgresql_databases do - %x( createdb activerecord_unittest ) - %x( createdb activerecord_unittest2 ) - %x( psql activerecord_unittest -f #{File.join(SCHEMA_PATH, 'postgresql.sql')} ) - %x( psql activerecord_unittest -f #{File.join(SCHEMA_PATH, 'postgresql2.sql')} ) -end - -desc 'Drop the PostgreSQL test databases' -task :drop_postgresql_databases do - %x( dropdb activerecord_unittest ) - %x( dropdb activerecord_unittest2 ) -end - -desc 'Rebuild the PostgreSQL test databases' -task :rebuild_postgresql_databases => [:drop_postgresql_databases, :build_postgresql_databases] - -# Generate the RDoc documentation - -Rake::RDocTask.new { |rdoc| - rdoc.rdoc_dir = 'doc' - rdoc.title = "Active Record -- Object-relation mapping put on rails" - rdoc.options << '--line-numbers --inline-source --accessor cattr_accessor=object' - rdoc.template = "#{ENV['template']}.rb" if ENV['template'] - rdoc.rdoc_files.include('README', 'RUNNING_UNIT_TESTS', 'CHANGELOG') - rdoc.rdoc_files.include('lib/**/*.rb') - rdoc.rdoc_files.exclude('lib/active_record/vendor/*') - rdoc.rdoc_files.include('dev-utils/*.rb') -} - -# Enhance rdoc task to copy referenced images also -task :rdoc do - FileUtils.mkdir_p "doc/files/examples/" - FileUtils.copy "examples/associations.png", "doc/files/examples/associations.png" -end - - -# Create compressed packages - -dist_dirs = [ "lib", "test", "examples", "dev-utils" ] - -spec = Gem::Specification.new do |s| - s.name = PKG_NAME - s.version = PKG_VERSION - s.summary = "Implements the ActiveRecord pattern for ORM." - s.description = %q{Implements the ActiveRecord pattern (Fowler, PoEAA) for ORM. It ties database tables and classes together for business objects, like Customer or Subscription, that can find, save, and destroy themselves without resorting to manual SQL.} - - s.files = [ "rakefile", "install.rb", "README", "RUNNING_UNIT_TESTS", "CHANGELOG" ] - dist_dirs.each do |dir| - s.files = s.files + Dir.glob( "#{dir}/**/*" ).delete_if { |item| item.include?( "\.svn" ) } - end - - s.add_dependency('activesupport', '= 1.2.5' + PKG_BUILD) - - s.files.delete "test/fixtures/fixture_database.sqlite" - s.files.delete "test/fixtures/fixture_database_2.sqlite" - s.files.delete "test/fixtures/fixture_database.sqlite3" - s.files.delete "test/fixtures/fixture_database_2.sqlite3" - s.require_path = 'lib' - s.autorequire = 'active_record' - - s.has_rdoc = true - s.extra_rdoc_files = %w( README ) - s.rdoc_options.concat ['--main', 'README'] - - s.author = "David Heinemeier Hansson" - s.email = "david@loudthinking.com" - s.homepage = "http://www.rubyonrails.org" - s.rubyforge_project = "activerecord" -end - -Rake::GemPackageTask.new(spec) do |p| - p.gem_spec = spec - p.need_tar = true - p.need_zip = true -end - -task :lines do - lines, codelines, total_lines, total_codelines = 0, 0, 0, 0 - - for file_name in FileList["lib/active_record/**/*.rb"] - next if file_name =~ /vendor/ - f = File.open(file_name) - - while line = f.gets - lines += 1 - next if line =~ /^\s*$/ - next if line =~ /^\s*#/ - codelines += 1 - end - puts "L: #{sprintf("%4d", lines)}, LOC #{sprintf("%4d", codelines)} | #{file_name}" - - total_lines += lines - total_codelines += codelines - - lines, codelines = 0, 0 - end - - puts "Total: Lines #{total_lines}, LOC #{total_codelines}" -end - - -# Publishing ------------------------------------------------------ - -desc "Publish the beta gem" -task :pgem => [:package] do - Rake::SshFilePublisher.new("davidhh@wrath.rubyonrails.org", "public_html/gems/gems", "pkg", "#{PKG_FILE_NAME}.gem").upload - `ssh davidhh@wrath.rubyonrails.org './gemupdate.sh'` -end - -desc "Publish the API documentation" -task :pdoc => [:rdoc] do - Rake::SshDirPublisher.new("davidhh@wrath.rubyonrails.org", "public_html/ar", "doc").upload -end - -desc "Publish the release files to RubyForge." -task :release => [:package] do - files = ["gem", "tgz", "zip"].map { |ext| "pkg/#{PKG_FILE_NAME}.#{ext}" } - - if RUBY_FORGE_PROJECT then - require 'net/http' - require 'open-uri' - - project_uri = "http://rubyforge.org/projects/#{RUBY_FORGE_PROJECT}/" - project_data = open(project_uri) { |data| data.read } - group_id = project_data[/[?&]group_id=(\d+)/, 1] - raise "Couldn't get group id" unless group_id - - # This echos password to shell which is a bit sucky - if ENV["RUBY_FORGE_PASSWORD"] - password = ENV["RUBY_FORGE_PASSWORD"] - else - print "#{RUBY_FORGE_USER}@rubyforge.org's password: " - password = STDIN.gets.chomp - end - - login_response = Net::HTTP.start("rubyforge.org", 80) do |http| - data = [ - "login=1", - "form_loginname=#{RUBY_FORGE_USER}", - "form_pw=#{password}" - ].join("&") - http.post("/account/login.php", data) - end - - cookie = login_response["set-cookie"] - raise "Login failed" unless cookie - headers = { "Cookie" => cookie } - - release_uri = "http://rubyforge.org/frs/admin/?group_id=#{group_id}" - release_data = open(release_uri, headers) { |data| data.read } - package_id = release_data[/[?&]package_id=(\d+)/, 1] - raise "Couldn't get package id" unless package_id - - first_file = true - release_id = "" - - files.each do |filename| - basename = File.basename(filename) - file_ext = File.extname(filename) - file_data = File.open(filename, "rb") { |file| file.read } - - puts "Releasing #{basename}..." - - release_response = Net::HTTP.start("rubyforge.org", 80) do |http| - release_date = Time.now.strftime("%Y-%m-%d %H:%M") - type_map = { - ".zip" => "3000", - ".tgz" => "3110", - ".gz" => "3110", - ".gem" => "1400" - }; type_map.default = "9999" - type = type_map[file_ext] - boundary = "rubyqMY6QN9bp6e4kS21H4y0zxcvoor" - - query_hash = if first_file then - { - "group_id" => group_id, - "package_id" => package_id, - "release_name" => RELEASE_NAME, - "release_date" => release_date, - "type_id" => type, - "processor_id" => "8000", # Any - "release_notes" => "", - "release_changes" => "", - "preformatted" => "1", - "submit" => "1" - } - else - { - "group_id" => group_id, - "release_id" => release_id, - "package_id" => package_id, - "step2" => "1", - "type_id" => type, - "processor_id" => "8000", # Any - "submit" => "Add This File" - } - end - - query = "?" + query_hash.map do |(name, value)| - [name, URI.encode(value)].join("=") - end.join("&") - - data = [ - "--" + boundary, - "Content-Disposition: form-data; name=\"userfile\"; filename=\"#{basename}\"", - "Content-Type: application/octet-stream", - "Content-Transfer-Encoding: binary", - "", file_data, "" - ].join("\x0D\x0A") - - release_headers = headers.merge( - "Content-Type" => "multipart/form-data; boundary=#{boundary}" - ) - - target = first_file ? "/frs/admin/qrs.php" : "/frs/admin/editrelease.php" - http.post(target + query, data, release_headers) - end - - if first_file then - release_id = release_response.body[/release_id=(\d+)/, 1] - raise("Couldn't get release id") unless release_id - end - - first_file = false - end - end -end diff --git a/tracks/vendor/rails/activerecord/test/aaa_create_tables_test.rb b/tracks/vendor/rails/activerecord/test/aaa_create_tables_test.rb deleted file mode 100644 index d49e6256..00000000 --- a/tracks/vendor/rails/activerecord/test/aaa_create_tables_test.rb +++ /dev/null @@ -1,36 +0,0 @@ -# The filename begins with "aaa" to ensure this is the first test. -require 'abstract_unit' - -class CreateTablesTest < Test::Unit::TestCase - def setup - @base_path = "#{File.dirname(__FILE__)}/fixtures/db_definitions" - end - - def test_drop_and_create_main_tables - recreate ActiveRecord::Base - assert true - end - - def test_drop_and_create_courses_table - recreate Course, '2' - assert true - end - - private - def recreate(base, suffix = nil) - connection = base.connection - adapter_name = connection.adapter_name.downcase + suffix.to_s - execute_sql_file "#{@base_path}/#{adapter_name}.drop.sql", connection - execute_sql_file "#{@base_path}/#{adapter_name}.sql", connection - end - - def execute_sql_file(path, connection) - File.read(path).split(';').each_with_index do |sql, i| - begin - connection.execute("\n\n-- statement ##{i}\n#{sql}\n") unless sql.blank? - rescue ActiveRecord::StatementInvalid - #$stderr.puts "warning: #{$!}" - end - end - end -end diff --git a/tracks/vendor/rails/activerecord/test/abstract_unit.rb b/tracks/vendor/rails/activerecord/test/abstract_unit.rb deleted file mode 100644 index d9c60ab6..00000000 --- a/tracks/vendor/rails/activerecord/test/abstract_unit.rb +++ /dev/null @@ -1,29 +0,0 @@ -$:.unshift(File.dirname(__FILE__) + '/../lib') -$:.unshift(File.dirname(__FILE__) + '/../../activesupport/lib') - -require 'test/unit' -require 'active_record' -require 'active_record/fixtures' -require 'active_support/binding_of_caller' -require 'active_support/breakpoint' -require 'connection' - -QUOTED_TYPE = ActiveRecord::Base.connection.quote_column_name('type') unless Object.const_defined?(:QUOTED_TYPE) - -class Test::Unit::TestCase #:nodoc: - self.fixture_path = File.dirname(__FILE__) + "/fixtures/" - self.use_instantiated_fixtures = false - self.use_transactional_fixtures = (ENV['AR_NO_TX_FIXTURES'] != "yes") - - def create_fixtures(*table_names, &block) - Fixtures.create_fixtures(File.dirname(__FILE__) + "/fixtures/", table_names, &block) - end -end - -def current_adapter?(type) - ActiveRecord::ConnectionAdapters.const_defined?(type) && - ActiveRecord::Base.connection.instance_of?(ActiveRecord::ConnectionAdapters.const_get(type)) -end - -#ActiveRecord::Base.logger = Logger.new(STDOUT) -#ActiveRecord::Base.colorize_logging = false diff --git a/tracks/vendor/rails/activerecord/test/active_schema_mysql.rb b/tracks/vendor/rails/activerecord/test/active_schema_mysql.rb deleted file mode 100644 index d3ee5bfb..00000000 --- a/tracks/vendor/rails/activerecord/test/active_schema_mysql.rb +++ /dev/null @@ -1,31 +0,0 @@ -require 'abstract_unit' - -class ActiveSchemaTest < Test::Unit::TestCase - def setup - ActiveRecord::ConnectionAdapters::MysqlAdapter.class_eval do - alias_method :real_execute, :execute - def execute(sql, name = nil) return sql end - end - end - - def teardown - ActiveRecord::ConnectionAdapters::MysqlAdapter.send(:alias_method, :execute, :real_execute) - end - - def test_drop_table - assert_equal "DROP TABLE people", drop_table(:people) - end - - def test_add_column - assert_equal "ALTER TABLE people ADD last_name varchar(255)", add_column(:people, :last_name, :string) - end - - def test_add_column_with_limit - assert_equal "ALTER TABLE people ADD key varchar(32)", add_column(:people, :key, :string, :limit => 32) - end - - private - def method_missing(method_symbol, *arguments) - ActiveRecord::Base.connection.send(method_symbol, *arguments) - end -end \ No newline at end of file diff --git a/tracks/vendor/rails/activerecord/test/adapter_test.rb b/tracks/vendor/rails/activerecord/test/adapter_test.rb deleted file mode 100644 index 7d427cda..00000000 --- a/tracks/vendor/rails/activerecord/test/adapter_test.rb +++ /dev/null @@ -1,58 +0,0 @@ -require 'abstract_unit' - -class AdapterTest < Test::Unit::TestCase - def setup - @connection = ActiveRecord::Base.connection - end - - def test_tables - if @connection.respond_to?(:tables) - tables = @connection.tables - assert tables.include?("accounts") - assert tables.include?("authors") - assert tables.include?("tasks") - assert tables.include?("topics") - else - warn "#{@connection.class} does not respond to #tables" - end - end - - def test_indexes - if @connection.respond_to?(:indexes) - indexes = @connection.indexes("accounts") - assert indexes.empty? - - @connection.add_index :accounts, :firm_id - indexes = @connection.indexes("accounts") - assert_equal "accounts", indexes.first.table - assert_equal "accounts_firm_id_index", indexes.first.name - assert !indexes.first.unique - assert_equal ["firm_id"], indexes.first.columns - else - warn "#{@connection.class} does not respond to #indexes" - end - - ensure - @connection.remove_index :accounts, :firm_id rescue nil - end - - # test resetting sequences in odd tables in postgreSQL - if ActiveRecord::Base.connection.respond_to?(:reset_pk_sequence!) - require 'fixtures/movie' - require 'fixtures/subscriber' - def test_reset_empty_table_with_custom_pk - Movie.delete_all - Movie.connection.reset_pk_sequence! 'movies' - assert_equal 1, Movie.create(:name => 'fight club').id - end - - def test_reset_table_with_non_integer_pk - Subscriber.delete_all - Subscriber.connection.reset_pk_sequence! 'subscribers' - - sub = Subscriber.new(:name => 'robert drake') - sub.id = 'bob drake' - assert sub.save! - end - end -end diff --git a/tracks/vendor/rails/activerecord/test/aggregations_test.rb b/tracks/vendor/rails/activerecord/test/aggregations_test.rb deleted file mode 100644 index 39adedae..00000000 --- a/tracks/vendor/rails/activerecord/test/aggregations_test.rb +++ /dev/null @@ -1,66 +0,0 @@ -require 'abstract_unit' -require 'fixtures/customer' - -class AggregationsTest < Test::Unit::TestCase - fixtures :customers - - def test_find_single_value_object - assert_equal 50, customers(:david).balance.amount - assert_kind_of Money, customers(:david).balance - assert_equal 300, customers(:david).balance.exchange_to("DKK").amount - end - - def test_find_multiple_value_object - assert_equal customers(:david).address_street, customers(:david).address.street - assert( - customers(:david).address.close_to?(Address.new("Different Street", customers(:david).address_city, customers(:david).address_country)) - ) - end - - def test_change_single_value_object - customers(:david).balance = Money.new(100) - customers(:david).save - assert_equal 100, Customer.find(1).balance.amount - end - - def test_immutable_value_objects - customers(:david).balance = Money.new(100) - assert_raises(TypeError) { customers(:david).balance.instance_eval { @amount = 20 } } - end - - def test_inferred_mapping - assert_equal "35.544623640962634", customers(:david).gps_location.latitude - assert_equal "-105.9309951055148", customers(:david).gps_location.longitude - - customers(:david).gps_location = GpsLocation.new("39x-110") - - assert_equal "39", customers(:david).gps_location.latitude - assert_equal "-110", customers(:david).gps_location.longitude - - customers(:david).save - - customers(:david).reload - - assert_equal "39", customers(:david).gps_location.latitude - assert_equal "-110", customers(:david).gps_location.longitude - end - - def test_reloaded_instance_refreshes_aggregations - assert_equal "35.544623640962634", customers(:david).gps_location.latitude - assert_equal "-105.9309951055148", customers(:david).gps_location.longitude - - Customer.update_all("gps_location = '24x113'") - customers(:david).reload - assert_equal '24x113', customers(:david)['gps_location'] - - assert_equal GpsLocation.new('24x113'), customers(:david).gps_location - end - - def test_gps_equality - assert GpsLocation.new('39x110') == GpsLocation.new('39x110') - end - - def test_gps_inequality - assert GpsLocation.new('39x110') != GpsLocation.new('39x111') - end -end diff --git a/tracks/vendor/rails/activerecord/test/all.sh b/tracks/vendor/rails/activerecord/test/all.sh deleted file mode 100644 index a6712cc4..00000000 --- a/tracks/vendor/rails/activerecord/test/all.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/sh - -if [ -z "$1" ]; then - echo "Usage: $0 connections/" 1>&2 - exit 1 -fi - -ruby -I $1 -e 'Dir.foreach(".") { |file| require file if file =~ /_test.rb$/ }' diff --git a/tracks/vendor/rails/activerecord/test/ar_schema_test.rb b/tracks/vendor/rails/activerecord/test/ar_schema_test.rb deleted file mode 100644 index c700b85e..00000000 --- a/tracks/vendor/rails/activerecord/test/ar_schema_test.rb +++ /dev/null @@ -1,33 +0,0 @@ -require 'abstract_unit' -require "#{File.dirname(__FILE__)}/../lib/active_record/schema" - -if ActiveRecord::Base.connection.supports_migrations? - - class ActiveRecordSchemaTest < Test::Unit::TestCase - self.use_transactional_fixtures = false - - def setup - @connection = ActiveRecord::Base.connection - end - - def teardown - @connection.drop_table :fruits rescue nil - end - - def test_schema_define - ActiveRecord::Schema.define(:version => 7) do - create_table :fruits do |t| - t.column :color, :string - t.column :fruit_size, :string # NOTE: "size" is reserved in Oracle - t.column :texture, :string - t.column :flavor, :string - end - end - - assert_nothing_raised { @connection.select_all "SELECT * FROM fruits" } - assert_nothing_raised { @connection.select_all "SELECT * FROM schema_info" } - assert_equal 7, @connection.select_one("SELECT version FROM schema_info")['version'].to_i - end - end - -end diff --git a/tracks/vendor/rails/activerecord/test/association_callbacks_test.rb b/tracks/vendor/rails/activerecord/test/association_callbacks_test.rb deleted file mode 100644 index 1426fb71..00000000 --- a/tracks/vendor/rails/activerecord/test/association_callbacks_test.rb +++ /dev/null @@ -1,124 +0,0 @@ -require 'abstract_unit' -require 'fixtures/post' -require 'fixtures/comment' -require 'fixtures/author' -require 'fixtures/category' -require 'fixtures/project' -require 'fixtures/developer' - -class AssociationCallbacksTest < Test::Unit::TestCase - fixtures :posts, :authors, :projects, :developers - - def setup - @david = authors(:david) - @thinking = posts(:thinking) - @authorless = posts(:authorless) - assert @david.post_log.empty? - end - - def test_adding_macro_callbacks - @david.posts_with_callbacks << @thinking - assert_equal ["before_adding#{@thinking.id}", "after_adding#{@thinking.id}"], @david.post_log - @david.posts_with_callbacks << @thinking - assert_equal ["before_adding#{@thinking.id}", "after_adding#{@thinking.id}", "before_adding#{@thinking.id}", - "after_adding#{@thinking.id}"], @david.post_log - end - - def test_adding_with_proc_callbacks - @david.posts_with_proc_callbacks << @thinking - assert_equal ["before_adding#{@thinking.id}", "after_adding#{@thinking.id}"], @david.post_log - @david.posts_with_proc_callbacks << @thinking - assert_equal ["before_adding#{@thinking.id}", "after_adding#{@thinking.id}", "before_adding#{@thinking.id}", - "after_adding#{@thinking.id}"], @david.post_log - end - - def test_removing_with_macro_callbacks - first_post, second_post = @david.posts_with_callbacks[0, 2] - @david.posts_with_callbacks.delete(first_post) - assert_equal ["before_removing#{first_post.id}", "after_removing#{first_post.id}"], @david.post_log - @david.posts_with_callbacks.delete(second_post) - assert_equal ["before_removing#{first_post.id}", "after_removing#{first_post.id}", "before_removing#{second_post.id}", - "after_removing#{second_post.id}"], @david.post_log - end - - def test_removing_with_proc_callbacks - first_post, second_post = @david.posts_with_callbacks[0, 2] - @david.posts_with_proc_callbacks.delete(first_post) - assert_equal ["before_removing#{first_post.id}", "after_removing#{first_post.id}"], @david.post_log - @david.posts_with_proc_callbacks.delete(second_post) - assert_equal ["before_removing#{first_post.id}", "after_removing#{first_post.id}", "before_removing#{second_post.id}", - "after_removing#{second_post.id}"], @david.post_log - end - - def test_multiple_callbacks - @david.posts_with_multiple_callbacks << @thinking - assert_equal ["before_adding#{@thinking.id}", "before_adding_proc#{@thinking.id}", "after_adding#{@thinking.id}", - "after_adding_proc#{@thinking.id}"], @david.post_log - @david.posts_with_multiple_callbacks << @thinking - assert_equal ["before_adding#{@thinking.id}", "before_adding_proc#{@thinking.id}", "after_adding#{@thinking.id}", - "after_adding_proc#{@thinking.id}", "before_adding#{@thinking.id}", "before_adding_proc#{@thinking.id}", - "after_adding#{@thinking.id}", "after_adding_proc#{@thinking.id}"], @david.post_log - end - - def test_has_and_belongs_to_many_add_callback - david = developers(:david) - ar = projects(:active_record) - assert ar.developers_log.empty? - ar.developers_with_callbacks << david - assert_equal ["before_adding#{david.id}", "after_adding#{david.id}"], ar.developers_log - ar.developers_with_callbacks << david - assert_equal ["before_adding#{david.id}", "after_adding#{david.id}", "before_adding#{david.id}", - "after_adding#{david.id}"], ar.developers_log - end - - def test_has_and_belongs_to_many_remove_callback - david = developers(:david) - jamis = developers(:jamis) - activerecord = projects(:active_record) - assert activerecord.developers_log.empty? - activerecord.developers_with_callbacks.delete(david) - assert_equal ["before_removing#{david.id}", "after_removing#{david.id}"], activerecord.developers_log - - activerecord.developers_with_callbacks.delete(jamis) - assert_equal ["before_removing#{david.id}", "after_removing#{david.id}", "before_removing#{jamis.id}", - "after_removing#{jamis.id}"], activerecord.developers_log - end - - def test_has_and_belongs_to_many_remove_callback_on_clear - activerecord = projects(:active_record) - assert activerecord.developers_log.empty? - if activerecord.developers_with_callbacks.size == 0 - activerecord.developers << developers(:david) - activerecord.developers << developers(:jamis) - activerecord.reload - assert activerecord.developers_with_callbacks.size == 2 - end - log_array = activerecord.developers_with_callbacks.collect {|d| ["before_removing#{d.id}","after_removing#{d.id}"]}.flatten.sort - assert activerecord.developers_with_callbacks.clear - assert_equal log_array, activerecord.developers_log.sort - end - - def test_dont_add_if_before_callback_raises_exception - assert !@david.unchangable_posts.include?(@authorless) - begin - @david.unchangable_posts << @authorless - rescue Exception => e - end - assert @david.post_log.empty? - assert !@david.unchangable_posts.include?(@authorless) - @david.reload - assert !@david.unchangable_posts.include?(@authorless) - end - - def test_push_with_attributes - david = developers(:david) - activerecord = projects(:active_record) - assert activerecord.developers_log.empty? - activerecord.developers_with_callbacks.push_with_attributes(david, {}) - assert_equal ["before_adding#{david.id}", "after_adding#{david.id}"], activerecord.developers_log - activerecord.developers_with_callbacks.push_with_attributes(david, {}) - assert_equal ["before_adding#{david.id}", "after_adding#{david.id}", "before_adding#{david.id}", - "after_adding#{david.id}"], activerecord.developers_log - end -end - diff --git a/tracks/vendor/rails/activerecord/test/association_inheritance_reload.rb b/tracks/vendor/rails/activerecord/test/association_inheritance_reload.rb deleted file mode 100644 index a3d57228..00000000 --- a/tracks/vendor/rails/activerecord/test/association_inheritance_reload.rb +++ /dev/null @@ -1,14 +0,0 @@ -require 'abstract_unit' -require 'fixtures/company' - -class AssociationInheritanceReloadTest < Test::Unit::TestCase - fixtures :companies - - def test_set_attributes - assert_equal ["errors.add_on_empty('name', \"can't be empty\")"], Firm.read_inheritable_attribute("validate"), "Second run" - # ActiveRecord::Base.reset_column_information_and_inheritable_attributes_for_all_subclasses - remove_subclass_of(ActiveRecord::Base) - load 'fixtures/company.rb' - assert_equal ["errors.add_on_empty('name', \"can't be empty\")"], Firm.read_inheritable_attribute("validate"), "Second run" - end -end \ No newline at end of file diff --git a/tracks/vendor/rails/activerecord/test/associations_extensions_test.rb b/tracks/vendor/rails/activerecord/test/associations_extensions_test.rb deleted file mode 100644 index 915056c5..00000000 --- a/tracks/vendor/rails/activerecord/test/associations_extensions_test.rb +++ /dev/null @@ -1,37 +0,0 @@ -require 'abstract_unit' -require 'fixtures/post' -require 'fixtures/comment' -require 'fixtures/project' -require 'fixtures/developer' - -class AssociationsExtensionsTest < Test::Unit::TestCase - fixtures :projects, :developers, :developers_projects, :comments, :posts - - def test_extension_on_has_many - assert_equal comments(:more_greetings), posts(:welcome).comments.find_most_recent - end - - def test_extension_on_habtm - assert_equal projects(:action_controller), developers(:david).projects.find_most_recent - end - - def test_named_extension_on_habtm - assert_equal projects(:action_controller), developers(:david).projects_extended_by_name.find_most_recent - end - - def test_marshalling_extensions - david = developers(:david) - assert_equal projects(:action_controller), david.projects.find_most_recent - - david = Marshal.load(Marshal.dump(david)) - assert_equal projects(:action_controller), david.projects.find_most_recent - end - - def test_marshalling_named_extensions - david = developers(:david) - assert_equal projects(:action_controller), david.projects_extended_by_name.find_most_recent - - david = Marshal.load(Marshal.dump(david)) - assert_equal projects(:action_controller), david.projects_extended_by_name.find_most_recent - end -end \ No newline at end of file diff --git a/tracks/vendor/rails/activerecord/test/associations_go_eager_test.rb b/tracks/vendor/rails/activerecord/test/associations_go_eager_test.rb deleted file mode 100644 index f345656c..00000000 --- a/tracks/vendor/rails/activerecord/test/associations_go_eager_test.rb +++ /dev/null @@ -1,244 +0,0 @@ -require 'abstract_unit' -require 'fixtures/post' -require 'fixtures/comment' -require 'fixtures/author' -require 'fixtures/category' -require 'fixtures/company' - -class EagerAssociationTest < Test::Unit::TestCase - fixtures :posts, :comments, :authors, :categories, :categories_posts, - :companies, :accounts - - def test_loading_with_one_association - posts = Post.find(:all, :include => :comments) - post = posts.find { |p| p.id == 1 } - assert_equal 2, post.comments.size - assert post.comments.include?(comments(:greetings)) - - post = Post.find(:first, :include => :comments, :conditions => "posts.title = 'Welcome to the weblog'") - assert_equal 2, post.comments.size - assert post.comments.include?(comments(:greetings)) - end - - def test_loading_conditions_with_or - posts = authors(:david).posts.find(:all, :include => :comments, :conditions => "comments.body like 'Normal%' OR comments.#{QUOTED_TYPE} = 'SpecialComment'") - assert_nil posts.detect { |p| p.author_id != authors(:david).id }, - "expected to find only david's posts" - end - - def test_with_ordering - list = Post.find(:all, :include => :comments, :order => "posts.id DESC") - [:eager_other, :sti_habtm, :sti_post_and_comments, :sti_comments, - :authorless, :thinking, :welcome - ].each_with_index do |post, index| - assert_equal posts(post), list[index] - end - end - - def test_loading_with_multiple_associations - posts = Post.find(:all, :include => [ :comments, :author, :categories ], :order => "posts.id") - assert_equal 2, posts.first.comments.size - assert_equal 2, posts.first.categories.size - assert posts.first.comments.include?(comments(:greetings)) - end - - def test_loading_from_an_association - posts = authors(:david).posts.find(:all, :include => :comments, :order => "posts.id") - assert_equal 2, posts.first.comments.size - end - - def test_loading_with_no_associations - assert_nil Post.find(posts(:authorless).id, :include => :author).author - end - - def test_eager_association_loading_with_belongs_to - comments = Comment.find(:all, :include => :post) - assert_equal 10, comments.length - titles = comments.map { |c| c.post.title } - assert titles.include?(posts(:welcome).title) - assert titles.include?(posts(:sti_post_and_comments).title) - end - - def test_eager_association_loading_with_belongs_to_and_limit - comments = Comment.find(:all, :include => :post, :limit => 5, :order => 'comments.id') - assert_equal 5, comments.length - assert_equal [1,2,3,5,6], comments.collect { |c| c.id } - end - - def test_eager_association_loading_with_belongs_to_and_limit_and_conditions - comments = Comment.find(:all, :include => :post, :conditions => 'post_id = 4', :limit => 3, :order => 'comments.id') - assert_equal 3, comments.length - assert_equal [5,6,7], comments.collect { |c| c.id } - end - - def test_eager_association_loading_with_belongs_to_and_limit_and_offset - comments = Comment.find(:all, :include => :post, :limit => 3, :offset => 2, :order => 'comments.id') - assert_equal 3, comments.length - assert_equal [3,5,6], comments.collect { |c| c.id } - end - - def test_eager_association_loading_with_belongs_to_and_limit_and_offset_and_conditions - comments = Comment.find(:all, :include => :post, :conditions => 'post_id = 4', :limit => 3, :offset => 1, :order => 'comments.id') - assert_equal 3, comments.length - assert_equal [6,7,8], comments.collect { |c| c.id } - end - - def test_eager_association_loading_with_belongs_to_and_limit_and_offset_and_conditions_array - comments = Comment.find(:all, :include => :post, :conditions => ['post_id = ?',4], :limit => 3, :offset => 1, :order => 'comments.id') - assert_equal 3, comments.length - assert_equal [6,7,8], comments.collect { |c| c.id } - end - - def test_eager_association_loading_with_belongs_to_and_limit_and_multiple_associations - posts = Post.find(:all, :include => [:author, :very_special_comment], :limit => 1) - assert_equal 1, posts.length - assert_equal [4], posts.collect { |p| p.id } - end - - def test_eager_association_loading_with_belongs_to_and_limit_and_offset_and_multiple_associations - posts = Post.find(:all, :include => [:author, :very_special_comment], :limit => 1, :offset => 1) - assert_equal 0, posts.length - assert_equal [], posts - end - - def test_eager_with_has_many_and_limit - posts = Post.find(:all, :order => 'posts.id asc', :include => [ :author, :comments ], :limit => 2) - assert_equal 2, posts.size - assert_equal 3, posts.inject(0) { |sum, post| sum += post.comments.size } - end - - def test_eager_with_has_many_and_limit_and_conditions - posts = Post.find(:all, :include => [ :author, :comments ], :limit => 2, :conditions => "posts.body = 'hello'", :order => "posts.id") - assert_equal 2, posts.size - assert_equal [4,5], posts.collect { |p| p.id } - end - - def test_eager_with_has_many_and_limit_and_conditions_array - posts = Post.find(:all, :include => [ :author, :comments ], :limit => 2, :conditions => [ "posts.body = ?", 'hello' ], :order => "posts.id") - assert_equal 2, posts.size - assert_equal [4,5], posts.collect { |p| p.id } - end - - def test_eager_with_has_many_and_limit_and_conditions_array_on_the_eagers - assert_raises(ArgumentError) do - posts = Post.find(:all, :include => [ :author, :comments ], :limit => 2, :conditions => [ "authors.name = ?", 'David' ]) - end - end - - def test_eager_with_has_many_and_limit_with_no_results - posts = Post.find(:all, :include => [ :author, :comments ], :limit => 2, :conditions => "posts.title = 'magic forest'") - assert_equal 0, posts.size - end - - def test_eager_with_has_and_belongs_to_many_and_limit - posts = Post.find(:all, :include => :categories, :order => "posts.id", :limit => 3) - assert_equal 3, posts.size - assert_equal 2, posts[0].categories.size - assert_equal 1, posts[1].categories.size - assert_equal 0, posts[2].categories.size - assert posts[0].categories.include?(categories(:technology)) - assert posts[1].categories.include?(categories(:general)) - end - - def test_eager_with_has_many_and_limit_and_conditions_on_the_eagers - assert_raises(ArgumentError) do - posts = authors(:david).posts.find(:all, - :include => :comments, - :conditions => "comments.body like 'Normal%' OR comments.#{QUOTED_TYPE}= 'SpecialComment'", - :limit => 2 - ) - end - end - - def test_eager_association_loading_with_habtm - posts = Post.find(:all, :include => :categories, :order => "posts.id") - assert_equal 2, posts[0].categories.size - assert_equal 1, posts[1].categories.size - assert_equal 0, posts[2].categories.size - assert posts[0].categories.include?(categories(:technology)) - assert posts[1].categories.include?(categories(:general)) - end - - def test_eager_with_inheritance - posts = SpecialPost.find(:all, :include => [ :comments ]) - end - - def test_eager_has_one_with_association_inheritance - post = Post.find(4, :include => [ :very_special_comment ]) - assert_equal "VerySpecialComment", post.very_special_comment.class.to_s - end - - def test_eager_has_many_with_association_inheritance - post = Post.find(4, :include => [ :special_comments ]) - post.special_comments.each do |special_comment| - assert_equal "SpecialComment", special_comment.class.to_s - end - end - - def test_eager_habtm_with_association_inheritance - post = Post.find(6, :include => [ :special_categories ]) - assert_equal 1, post.special_categories.size - post.special_categories.each do |special_category| - assert_equal "SpecialCategory", special_category.class.to_s - end - end - - def test_eager_with_has_one_dependent_does_not_destroy_dependent - assert_not_nil companies(:first_firm).account - f = Firm.find(:first, :include => :account, - :conditions => ["companies.name = ?", "37signals"]) - assert_not_nil f.account - assert_equal companies(:first_firm, :reload).account, f.account - end - - def test_eager_with_invalid_association_reference - assert_raises(ActiveRecord::ConfigurationError, "Association was not found; perhaps you misspelled it? You specified :include => :monkeys") { - post = Post.find(6, :include=> :monkeys ) - } - assert_raises(ActiveRecord::ConfigurationError, "Association was not found; perhaps you misspelled it? You specified :include => :monkeys") { - post = Post.find(6, :include=>[ :monkeys ]) - } - assert_raises(ActiveRecord::ConfigurationError, "Association was not found; perhaps you misspelled it? You specified :include => :monkeys") { - post = Post.find(6, :include=>[ 'monkeys' ]) - } - assert_raises(ActiveRecord::ConfigurationError, "Association was not found; perhaps you misspelled it? You specified :include => :monkeys, :elephants") { - post = Post.find(6, :include=>[ :monkeys, :elephants ]) - } - end - - def test_eager_with_valid_association_as_string_not_symbol - assert_nothing_raised { Post.find(:all, :include => 'comments') } - end - - def test_preconfigured_includes_with_belongs_to - author = posts(:welcome).author_with_posts - assert_equal 5, author.posts.size - end - - def test_preconfigured_includes_with_has_one - comment = posts(:sti_comments).very_special_comment_with_post - assert_equal posts(:sti_comments), comment.post - end - - def test_preconfigured_includes_with_has_many - posts = authors(:david).posts_with_comments - one = posts.detect { |p| p.id == 1 } - assert_equal 5, posts.size - assert_equal 2, one.comments.size - end - - def test_preconfigured_includes_with_habtm - posts = authors(:david).posts_with_categories - one = posts.detect { |p| p.id == 1 } - assert_equal 5, posts.size - assert_equal 2, one.categories.size - end - - def test_preconfigured_includes_with_has_many_and_habtm - posts = authors(:david).posts_with_comments_and_categories - one = posts.detect { |p| p.id == 1 } - assert_equal 5, posts.size - assert_equal 2, one.comments.size - assert_equal 2, one.categories.size - end -end diff --git a/tracks/vendor/rails/activerecord/test/associations_test.rb b/tracks/vendor/rails/activerecord/test/associations_test.rb deleted file mode 100644 index 610a6954..00000000 --- a/tracks/vendor/rails/activerecord/test/associations_test.rb +++ /dev/null @@ -1,1397 +0,0 @@ -require 'abstract_unit' -require 'fixtures/developer' -require 'fixtures/project' -require 'fixtures/company' -require 'fixtures/topic' -require 'fixtures/reply' -require 'fixtures/computer' -require 'fixtures/customer' -require 'fixtures/order' -require 'fixtures/post' -require 'fixtures/author' - -# Can't declare new classes in test case methods, so tests before that -bad_collection_keys = false -begin - class Car < ActiveRecord::Base; has_many :wheels, :name => "wheels"; end -rescue ArgumentError - bad_collection_keys = true -end -raise "ActiveRecord should have barked on bad collection keys" unless bad_collection_keys - - -class AssociationsTest < Test::Unit::TestCase - fixtures :accounts, :companies, :developers, :projects, :developers_projects, - :computers - - def test_force_reload - firm = Firm.new("name" => "A New Firm, Inc") - firm.save - firm.clients.each {|c|} # forcing to load all clients - assert firm.clients.empty?, "New firm shouldn't have client objects" - assert !firm.has_clients?, "New firm shouldn't have clients" - assert_equal 0, firm.clients.size, "New firm should have 0 clients" - - client = Client.new("name" => "TheClient.com", "firm_id" => firm.id) - client.save - - assert firm.clients.empty?, "New firm should have cached no client objects" - assert !firm.has_clients?, "New firm should have cached a no-clients response" - assert_equal 0, firm.clients.size, "New firm should have cached 0 clients count" - - assert !firm.clients(true).empty?, "New firm should have reloaded client objects" - assert_equal 1, firm.clients(true).size, "New firm should have reloaded clients count" - end - - def test_storing_in_pstore - require "tmpdir" - store_filename = File.join(Dir.tmpdir, "ar-pstore-association-test") - File.delete(store_filename) if File.exists?(store_filename) - require "pstore" - apple = Firm.create("name" => "Apple") - natural = Client.new("name" => "Natural Company") - apple.clients << natural - - db = PStore.new(store_filename) - db.transaction do - db["apple"] = apple - end - - db = PStore.new(store_filename) - db.transaction do - assert_equal "Natural Company", db["apple"].clients.first.name - end - end -end - -class HasOneAssociationsTest < Test::Unit::TestCase - fixtures :accounts, :companies, :developers, :projects, :developers_projects - - def test_has_one - assert_equal companies(:first_firm).account, Account.find(1) - assert_equal Account.find(1).credit_limit, companies(:first_firm).account.credit_limit - end - - def test_proxy_assignment - company = companies(:first_firm) - assert_nothing_raised { company.account = company.account } - end - - def test_triple_equality - assert Account === companies(:first_firm).account - end - - def test_type_mismatch - assert_raises(ActiveRecord::AssociationTypeMismatch) { companies(:first_firm).account = 1 } - assert_raises(ActiveRecord::AssociationTypeMismatch) { companies(:first_firm).account = Project.find(1) } - end - - def test_natural_assignment - apple = Firm.create("name" => "Apple") - citibank = Account.create("credit_limit" => 10) - apple.account = citibank - assert_equal apple.id, citibank.firm_id - end - - def test_natural_assignment_to_nil - old_account_id = companies(:first_firm).account.id - companies(:first_firm).account = nil - companies(:first_firm).save - assert_nil companies(:first_firm).account - # account is dependent, therefore is destroyed when reference to owner is lost - assert_raises(ActiveRecord::RecordNotFound) { Account.find(old_account_id) } - end - - def test_assignment_without_replacement - apple = Firm.create("name" => "Apple") - citibank = Account.create("credit_limit" => 10) - apple.account = citibank - assert_equal apple.id, citibank.firm_id - - hsbc = apple.build_account({ :credit_limit => 20}, false) - assert_equal apple.id, hsbc.firm_id - hsbc.save - assert_equal apple.id, citibank.firm_id - - nykredit = apple.create_account({ :credit_limit => 30}, false) - assert_equal apple.id, nykredit.firm_id - assert_equal apple.id, citibank.firm_id - assert_equal apple.id, hsbc.firm_id - end - - def test_assignment_without_replacement_on_create - apple = Firm.create("name" => "Apple") - citibank = Account.create("credit_limit" => 10) - apple.account = citibank - assert_equal apple.id, citibank.firm_id - - hsbc = apple.create_account({:credit_limit => 10}, false) - assert_equal apple.id, hsbc.firm_id - hsbc.save - assert_equal apple.id, citibank.firm_id - end - - def test_dependence - num_accounts = Account.count - firm = Firm.find(1) - assert !firm.account.nil? - firm.destroy - assert_equal num_accounts - 1, Account.count - end - - def test_succesful_build_association - firm = Firm.new("name" => "GlobalMegaCorp") - firm.save - - account = firm.build_account("credit_limit" => 1000) - assert account.save - assert_equal account, firm.account - end - - def test_failing_build_association - firm = Firm.new("name" => "GlobalMegaCorp") - firm.save - - account = firm.build_account - assert !account.save - assert_equal "can't be empty", account.errors.on("credit_limit") - end - - def test_create_association - firm = Firm.new("name" => "GlobalMegaCorp") - firm.save - assert_equal firm.create_account("credit_limit" => 1000), firm.account - end - - def test_build - firm = Firm.new("name" => "GlobalMegaCorp") - firm.save - - firm.account = account = Account.new("credit_limit" => 1000) - assert_equal account, firm.account - assert account.save - assert_equal account, firm.account - end - - def test_build_before_child_saved - firm = Firm.find(1) - - account = firm.account.build("credit_limit" => 1000) - assert_equal account, firm.account - assert account.new_record? - assert firm.save - assert_equal account, firm.account - assert !account.new_record? - end - - def test_build_before_either_saved - firm = Firm.new("name" => "GlobalMegaCorp") - - firm.account = account = Account.new("credit_limit" => 1000) - assert_equal account, firm.account - assert account.new_record? - assert firm.save - assert_equal account, firm.account - assert !account.new_record? - end - - def test_failing_build_association - firm = Firm.new("name" => "GlobalMegaCorp") - firm.save - - firm.account = account = Account.new - assert_equal account, firm.account - assert !account.save - assert_equal account, firm.account - assert_equal "can't be empty", account.errors.on("credit_limit") - end - - def test_create - firm = Firm.new("name" => "GlobalMegaCorp") - firm.save - firm.account = account = Account.create("credit_limit" => 1000) - assert_equal account, firm.account - end - - def test_create_before_save - firm = Firm.new("name" => "GlobalMegaCorp") - firm.account = account = Account.create("credit_limit" => 1000) - assert_equal account, firm.account - end - - def test_dependence_with_missing_association - Account.destroy_all - firm = Firm.find(1) - assert firm.account.nil? - firm.destroy - end - - def test_assignment_before_parent_saved - firm = Firm.new("name" => "GlobalMegaCorp") - firm.account = a = Account.find(1) - assert firm.new_record? - assert_equal a, firm.account - assert firm.save - assert_equal a, firm.account - assert_equal a, firm.account(true) - end - - def test_assignment_before_child_saved - firm = Firm.find(1) - firm.account = a = Account.new("credit_limit" => 1000) - assert !a.new_record? - assert_equal a, firm.account - assert_equal a, firm.account - assert_equal a, firm.account(true) - end - - def test_assignment_before_either_saved - firm = Firm.new("name" => "GlobalMegaCorp") - firm.account = a = Account.new("credit_limit" => 1000) - assert firm.new_record? - assert a.new_record? - assert_equal a, firm.account - assert firm.save - assert !firm.new_record? - assert !a.new_record? - assert_equal a, firm.account - assert_equal a, firm.account(true) - end -end - - -class HasManyAssociationsTest < Test::Unit::TestCase - fixtures :accounts, :companies, :developers, :projects, - :developers_projects, :topics - - def setup - Client.destroyed_client_ids.clear - end - - def force_signal37_to_load_all_clients_of_firm - companies(:first_firm).clients_of_firm.each {|f| } - end - - def test_counting - assert_equal 2, Firm.find(:first).clients.count - end - - def test_finding - assert_equal 2, Firm.find(:first).clients.length - end - - def test_finding_default_orders - assert_equal "Summit", Firm.find(:first).clients.first.name - end - - def test_finding_with_different_class_name_and_order - assert_equal "Microsoft", Firm.find(:first).clients_sorted_desc.first.name - end - - def test_finding_with_foreign_key - assert_equal "Microsoft", Firm.find(:first).clients_of_firm.first.name - end - - def test_finding_with_condition - assert_equal "Microsoft", Firm.find(:first).clients_like_ms.first.name - end - - def test_finding_using_sql - firm = Firm.find(:first) - first_client = firm.clients_using_sql.first - assert_not_nil first_client - assert_equal "Microsoft", first_client.name - assert_equal 1, firm.clients_using_sql.size - assert_equal 1, Firm.find(:first).clients_using_sql.size - end - - def test_counting_using_sql - assert_equal 1, Firm.find(:first).clients_using_counter_sql.size - assert_equal 0, Firm.find(:first).clients_using_zero_counter_sql.size - end - - def test_counting_non_existant_items_using_sql - assert_equal 0, Firm.find(:first).no_clients_using_counter_sql.size - end - - def test_belongs_to_sanity - c = Client.new - assert_nil c.firm - - if c.firm - assert false, "belongs_to failed if check" - end - - unless c.firm - else - assert false, "belongs_to failed unless check" - end - end - - def test_find_ids - firm = Firm.find(:first) - - assert_raises(ActiveRecord::RecordNotFound) { firm.clients.find } - - client = firm.clients.find(2) - assert_kind_of Client, client - - client_ary = firm.clients.find([2]) - assert_kind_of Array, client_ary - assert_equal client, client_ary.first - - client_ary = firm.clients.find(2, 3) - assert_kind_of Array, client_ary - assert_equal 2, client_ary.size - assert_equal client, client_ary.first - - assert_raises(ActiveRecord::RecordNotFound) { firm.clients.find(2, 99) } - end - - def test_find_all - firm = Firm.find_first - assert_equal firm.clients, firm.clients.find_all - assert_equal 2, firm.clients.find(:all, :conditions => "#{QUOTED_TYPE} = 'Client'").length - assert_equal 1, firm.clients.find(:all, :conditions => "name = 'Summit'").length - end - - def test_find_all_sanitized - firm = Firm.find_first - assert_equal firm.clients.find_all("name = 'Summit'"), firm.clients.find_all(["name = '%s'", "Summit"]) - summit = firm.clients.find(:all, :conditions => "name = 'Summit'") - assert_equal summit, firm.clients.find(:all, :conditions => ["name = ?", "Summit"]) - assert_equal summit, firm.clients.find(:all, :conditions => ["name = :name", { :name => "Summit" }]) - end - - def test_find_first - firm = Firm.find_first - client2 = Client.find(2) - assert_equal firm.clients.first, firm.clients.find_first - assert_equal client2, firm.clients.find_first("#{QUOTED_TYPE} = 'Client'") - assert_equal client2, firm.clients.find(:first, :conditions => "#{QUOTED_TYPE} = 'Client'") - end - - def test_find_first_sanitized - firm = Firm.find_first - client2 = Client.find(2) - assert_equal client2, firm.clients.find_first(["#{QUOTED_TYPE} = ?", "Client"]) - assert_equal client2, firm.clients.find(:first, :conditions => ["#{QUOTED_TYPE} = ?", 'Client']) - assert_equal client2, firm.clients.find(:first, :conditions => ["#{QUOTED_TYPE} = :type", { :type => 'Client' }]) - end - - def test_find_in_collection - assert_equal Client.find(2).name, companies(:first_firm).clients.find(2).name - assert_raises(ActiveRecord::RecordNotFound) { companies(:first_firm).clients.find(6) } - end - - def test_find_grouped - all_clients_of_firm1 = Client.find(:all, :conditions => "firm_id = 1") - grouped_clients_of_firm1 = Client.find(:all, :conditions => "firm_id = 1", :group => "firm_id", :select => 'firm_id, count(id) as clients_count') - assert_equal 2, all_clients_of_firm1.size - assert_equal 1, grouped_clients_of_firm1.size - end - - def test_adding - force_signal37_to_load_all_clients_of_firm - natural = Client.new("name" => "Natural Company") - companies(:first_firm).clients_of_firm << natural - assert_equal 2, companies(:first_firm).clients_of_firm.size # checking via the collection - assert_equal 2, companies(:first_firm).clients_of_firm(true).size # checking using the db - assert_equal natural, companies(:first_firm).clients_of_firm.last - end - - def test_adding_a_mismatch_class - assert_raises(ActiveRecord::AssociationTypeMismatch) { companies(:first_firm).clients_of_firm << nil } - assert_raises(ActiveRecord::AssociationTypeMismatch) { companies(:first_firm).clients_of_firm << 1 } - assert_raises(ActiveRecord::AssociationTypeMismatch) { companies(:first_firm).clients_of_firm << Topic.find(1) } - end - - def test_adding_a_collection - force_signal37_to_load_all_clients_of_firm - companies(:first_firm).clients_of_firm.concat([Client.new("name" => "Natural Company"), Client.new("name" => "Apple")]) - assert_equal 3, companies(:first_firm).clients_of_firm.size - assert_equal 3, companies(:first_firm).clients_of_firm(true).size - end - - def test_adding_before_save - no_of_firms = Firm.count - no_of_clients = Client.count - new_firm = Firm.new("name" => "A New Firm, Inc") - new_firm.clients_of_firm.push Client.new("name" => "Natural Company") - new_firm.clients_of_firm << (c = Client.new("name" => "Apple")) - assert new_firm.new_record? - assert c.new_record? - assert_equal 2, new_firm.clients_of_firm.size - assert_equal no_of_firms, Firm.count # Firm was not saved to database. - assert_equal no_of_clients, Client.count # Clients were not saved to database. - assert new_firm.save - assert !new_firm.new_record? - assert !c.new_record? - assert_equal new_firm, c.firm - assert_equal no_of_firms+1, Firm.count # Firm was saved to database. - assert_equal no_of_clients+2, Client.count # Clients were saved to database. - assert_equal 2, new_firm.clients_of_firm.size - assert_equal 2, new_firm.clients_of_firm(true).size - end - - def test_invalid_adding - firm = Firm.find(1) - assert !(firm.clients_of_firm << c = Client.new) - assert c.new_record? - assert !firm.valid? - assert !firm.save - assert c.new_record? - end - - def test_invalid_adding_before_save - no_of_firms = Firm.count - no_of_clients = Client.count - new_firm = Firm.new("name" => "A New Firm, Inc") - new_firm.clients_of_firm.concat([c = Client.new, Client.new("name" => "Apple")]) - assert c.new_record? - assert !c.valid? - assert !new_firm.valid? - assert !new_firm.save - assert c.new_record? - assert new_firm.new_record? - end - - def test_build - new_client = companies(:first_firm).clients_of_firm.build("name" => "Another Client") - assert_equal "Another Client", new_client.name - assert new_client.new_record? - assert_equal new_client, companies(:first_firm).clients_of_firm.last - assert companies(:first_firm).save - assert !new_client.new_record? - assert_equal 2, companies(:first_firm).clients_of_firm(true).size - end - - def test_build_many - new_clients = companies(:first_firm).clients_of_firm.build([{"name" => "Another Client"}, {"name" => "Another Client II"}]) - assert_equal 2, new_clients.size - - assert companies(:first_firm).save - assert_equal 3, companies(:first_firm).clients_of_firm(true).size - end - - def test_invalid_build - new_client = companies(:first_firm).clients_of_firm.build - assert new_client.new_record? - assert !new_client.valid? - assert_equal new_client, companies(:first_firm).clients_of_firm.last - assert !companies(:first_firm).save - assert new_client.new_record? - assert_equal 1, companies(:first_firm).clients_of_firm(true).size - end - - def test_create - force_signal37_to_load_all_clients_of_firm - new_client = companies(:first_firm).clients_of_firm.create("name" => "Another Client") - assert !new_client.new_record? - assert_equal new_client, companies(:first_firm).clients_of_firm.last - assert_equal new_client, companies(:first_firm).clients_of_firm(true).last - end - - def test_create_many - companies(:first_firm).clients_of_firm.create([{"name" => "Another Client"}, {"name" => "Another Client II"}]) - assert_equal 3, companies(:first_firm).clients_of_firm(true).size - end - - def test_find_or_create - number_of_clients = companies(:first_firm).clients.size - the_client = companies(:first_firm).clients.find_or_create_by_name("Yet another client") - assert_equal number_of_clients + 1, companies(:first_firm, :refresh).clients.size - assert_equal the_client, companies(:first_firm).clients.find_or_create_by_name("Yet another client") - assert_equal number_of_clients + 1, companies(:first_firm, :refresh).clients.size - end - - def test_deleting - force_signal37_to_load_all_clients_of_firm - companies(:first_firm).clients_of_firm.delete(companies(:first_firm).clients_of_firm.first) - assert_equal 0, companies(:first_firm).clients_of_firm.size - assert_equal 0, companies(:first_firm).clients_of_firm(true).size - end - - def test_deleting_before_save - new_firm = Firm.new("name" => "A New Firm, Inc.") - new_client = new_firm.clients_of_firm.build("name" => "Another Client") - assert_equal 1, new_firm.clients_of_firm.size - new_firm.clients_of_firm.delete(new_client) - assert_equal 0, new_firm.clients_of_firm.size - end - - def test_deleting_a_collection - force_signal37_to_load_all_clients_of_firm - companies(:first_firm).clients_of_firm.create("name" => "Another Client") - assert_equal 2, companies(:first_firm).clients_of_firm.size - companies(:first_firm).clients_of_firm.delete([companies(:first_firm).clients_of_firm[0], companies(:first_firm).clients_of_firm[1]]) - assert_equal 0, companies(:first_firm).clients_of_firm.size - assert_equal 0, companies(:first_firm).clients_of_firm(true).size - end - - def test_clearing_an_association_collection - firm = companies(:first_firm) - client_id = firm.clients_of_firm.first.id - assert_equal 1, firm.clients_of_firm.size - - firm.clients_of_firm.clear - - assert_equal 0, firm.clients_of_firm.size - assert_equal 0, firm.clients_of_firm(true).size - assert_equal [], Client.destroyed_client_ids[firm.id] - - # Should not be destroyed since the association is not dependent. - assert_nothing_raised do - assert Client.find(client_id).firm.nil? - end - end - - def test_clearing_a_dependent_association_collection - firm = companies(:first_firm) - client_id = firm.dependent_clients_of_firm.first.id - assert_equal 1, firm.dependent_clients_of_firm.size - - # :dependent means destroy is called on each client - firm.dependent_clients_of_firm.clear - - assert_equal 0, firm.dependent_clients_of_firm.size - assert_equal 0, firm.dependent_clients_of_firm(true).size - assert_equal [client_id], Client.destroyed_client_ids[firm.id] - - # Should be destroyed since the association is dependent. - assert Client.find_by_id(client_id).nil? - end - - def test_clearing_an_exclusively_dependent_association_collection - firm = companies(:first_firm) - client_id = firm.exclusively_dependent_clients_of_firm.first.id - assert_equal 1, firm.exclusively_dependent_clients_of_firm.size - - assert_equal [], Client.destroyed_client_ids[firm.id] - - # :exclusively_dependent means each client is deleted directly from - # the database without looping through them calling destroy. - firm.exclusively_dependent_clients_of_firm.clear - - assert_equal 0, firm.exclusively_dependent_clients_of_firm.size - assert_equal 0, firm.exclusively_dependent_clients_of_firm(true).size - assert_equal [3], Client.destroyed_client_ids[firm.id] - - # Should be destroyed since the association is exclusively dependent. - assert Client.find_by_id(client_id).nil? - end - - def test_clearing_without_initial_access - firm = companies(:first_firm) - - firm.clients_of_firm.clear - - assert_equal 0, firm.clients_of_firm.size - assert_equal 0, firm.clients_of_firm(true).size - end - - def test_deleting_a_item_which_is_not_in_the_collection - force_signal37_to_load_all_clients_of_firm - summit = Client.find_first("name = 'Summit'") - companies(:first_firm).clients_of_firm.delete(summit) - assert_equal 1, companies(:first_firm).clients_of_firm.size - assert_equal 1, companies(:first_firm).clients_of_firm(true).size - assert_equal 2, summit.client_of - end - - def test_deleting_type_mismatch - david = Developer.find(1) - david.projects.reload - assert_raises(ActiveRecord::AssociationTypeMismatch) { david.projects.delete(1) } - end - - def test_deleting_self_type_mismatch - david = Developer.find(1) - david.projects.reload - assert_raises(ActiveRecord::AssociationTypeMismatch) { david.projects.delete(Project.find(1).developers) } - end - - def test_destroy_all - force_signal37_to_load_all_clients_of_firm - assert !companies(:first_firm).clients_of_firm.empty?, "37signals has clients after load" - companies(:first_firm).clients_of_firm.destroy_all - assert companies(:first_firm).clients_of_firm.empty?, "37signals has no clients after destroy all" - assert companies(:first_firm).clients_of_firm(true).empty?, "37signals has no clients after destroy all and refresh" - end - - def test_dependence - firm = companies(:first_firm) - assert_equal 2, firm.clients.size - firm.destroy - assert Client.find(:all, :conditions => "firm_id=#{firm.id}").empty? - end - - def test_destroy_dependent_when_deleted_from_association - firm = Firm.find(:first) - assert_equal 2, firm.clients.size - - client = firm.clients.first - firm.clients.delete(client) - - assert_raise(ActiveRecord::RecordNotFound) { Client.find(client.id) } - assert_raise(ActiveRecord::RecordNotFound) { firm.clients.find(client.id) } - assert_equal 1, firm.clients.size - end - - def test_three_levels_of_dependence - topic = Topic.create "title" => "neat and simple" - reply = topic.replies.create "title" => "neat and simple", "content" => "still digging it" - silly_reply = reply.silly_replies.create "title" => "neat and simple", "content" => "ain't complaining" - - assert_nothing_raised { topic.destroy } - end - - uses_transaction :test_dependence_with_transaction_support_on_failure - def test_dependence_with_transaction_support_on_failure - firm = companies(:first_firm) - clients = firm.clients - assert_equal 2, clients.length - clients.last.instance_eval { def before_destroy() raise "Trigger rollback" end } - - firm.destroy rescue "do nothing" - - assert_equal 2, Client.find(:all, :conditions => "firm_id=#{firm.id}").size - end - - def test_dependence_on_account - num_accounts = Account.count - companies(:first_firm).destroy - assert_equal num_accounts - 1, Account.count - end - - - def test_depends_and_nullify - num_accounts = Account.count - num_companies = Company.count - - core = companies(:rails_core) - assert_equal accounts(:rails_core_account), core.account - assert_equal [companies(:leetsoft), companies(:jadedpixel)], core.companies - core.destroy - assert_nil accounts(:rails_core_account).reload.firm_id - assert_nil companies(:leetsoft).reload.client_of - assert_nil companies(:jadedpixel).reload.client_of - - - assert_equal num_accounts, Account.count - end - - def test_included_in_collection - assert companies(:first_firm).clients.include?(Client.find(2)) - end - - def test_adding_array_and_collection - assert_nothing_raised { Firm.find(:first).clients + Firm.find(:all).last.clients } - end - - def test_find_all_without_conditions - firm = companies(:first_firm) - assert_equal 2, firm.clients.find(:all).length - end - - def test_replace_with_less - firm = Firm.find(:first) - firm.clients = [companies(:first_client)] - assert firm.save, "Could not save firm" - firm.reload - assert_equal 1, firm.clients.length - end - - - def test_replace_with_new - firm = Firm.find(:first) - new_client = Client.new("name" => "New Client") - firm.clients = [companies(:second_client),new_client] - firm.save - firm.reload - assert_equal 2, firm.clients.length - assert !firm.clients.include?(:first_client) - end - - def test_replace_on_new_object - firm = Firm.new("name" => "New Firm") - firm.clients = [companies(:second_client), Client.new("name" => "New Client")] - assert firm.save - firm.reload - assert_equal 2, firm.clients.length - assert firm.clients.include?(Client.find_by_name("New Client")) - end - - def test_assign_ids - firm = Firm.new("name" => "Apple") - firm.client_ids = [companies(:first_client).id, companies(:second_client).id] - firm.save - firm.reload - assert_equal 2, firm.clients.length - assert firm.clients.include?(companies(:second_client)) - end -end - -class BelongsToAssociationsTest < Test::Unit::TestCase - fixtures :accounts, :companies, :developers, :projects, :topics, - :developers_projects, :computers, :authors, :posts - - def test_belongs_to - Client.find(3).firm.name - assert_equal companies(:first_firm).name, Client.find(3).firm.name - assert !Client.find(3).firm.nil?, "Microsoft should have a firm" - end - - def test_proxy_assignment - account = Account.find(1) - assert_nothing_raised { account.firm = account.firm } - end - - def test_type_mismatch - assert_raise(ActiveRecord::AssociationTypeMismatch) { Account.find(1).firm = 1 } - assert_raise(ActiveRecord::AssociationTypeMismatch) { Account.find(1).firm = Project.find(1) } - end - - def test_natural_assignment - apple = Firm.create("name" => "Apple") - citibank = Account.create("credit_limit" => 10) - citibank.firm = apple - assert_equal apple.id, citibank.firm_id - end - - def test_creating_the_belonging_object - citibank = Account.create("credit_limit" => 10) - apple = citibank.create_firm("name" => "Apple") - assert_equal apple, citibank.firm - citibank.save - citibank.reload - assert_equal apple, citibank.firm - end - - def test_building_the_belonging_object - citibank = Account.create("credit_limit" => 10) - apple = citibank.build_firm("name" => "Apple") - citibank.save - assert_equal apple.id, citibank.firm_id - end - - def test_natural_assignment_to_nil - client = Client.find(3) - client.firm = nil - client.save - assert_nil client.firm(true) - assert_nil client.client_of - end - - def test_with_different_class_name - assert_equal Company.find(1).name, Company.find(3).firm_with_other_name.name - assert_not_nil Company.find(3).firm_with_other_name, "Microsoft should have a firm" - end - - def test_with_condition - assert_equal Company.find(1).name, Company.find(3).firm_with_condition.name - assert_not_nil Company.find(3).firm_with_condition, "Microsoft should have a firm" - end - - def test_belongs_to_counter - debate = Topic.create("title" => "debate") - assert_equal 0, debate.send(:read_attribute, "replies_count"), "No replies yet" - - trash = debate.replies.create("title" => "blah!", "content" => "world around!") - assert_equal 1, Topic.find(debate.id).send(:read_attribute, "replies_count"), "First reply created" - - trash.destroy - assert_equal 0, Topic.find(debate.id).send(:read_attribute, "replies_count"), "First reply deleted" - end - - def test_assignment_before_parent_saved - client = Client.find(:first) - apple = Firm.new("name" => "Apple") - client.firm = apple - assert_equal apple, client.firm - assert apple.new_record? - assert client.save - assert apple.save - assert !apple.new_record? - assert_equal apple, client.firm - assert_equal apple, client.firm(true) - end - - def test_assignment_before_child_saved - final_cut = Client.new("name" => "Final Cut") - firm = Firm.find(1) - final_cut.firm = firm - assert final_cut.new_record? - assert final_cut.save - assert !final_cut.new_record? - assert !firm.new_record? - assert_equal firm, final_cut.firm - assert_equal firm, final_cut.firm(true) - end - - def test_assignment_before_either_saved - final_cut = Client.new("name" => "Final Cut") - apple = Firm.new("name" => "Apple") - final_cut.firm = apple - assert final_cut.new_record? - assert apple.new_record? - assert final_cut.save - assert !final_cut.new_record? - assert !apple.new_record? - assert_equal apple, final_cut.firm - assert_equal apple, final_cut.firm(true) - end - - def test_new_record_with_foreign_key_but_no_object - c = Client.new("firm_id" => 1) - assert_equal Firm.find(:first), c.firm_with_basic_id - end - - def test_forgetting_the_load_when_foreign_key_enters_late - c = Client.new - assert_nil c.firm_with_basic_id - - c.firm_id = 1 - assert_equal Firm.find(:first), c.firm_with_basic_id - end - - def test_field_name_same_as_foreign_key - computer = Computer.find(1) - assert_not_nil computer.developer, ":foreign key == attribute didn't lock up" # ' - end - - def xtest_counter_cache - apple = Firm.create("name" => "Apple") - final_cut = apple.clients.create("name" => "Final Cut") - - apple.clients.to_s - assert_equal 1, apple.clients.size, "Created one client" - - apple.companies_count = 2 - apple.save - - apple = Firm.find(:first, :conditions => "name = 'Apple'") - assert_equal 2, apple.clients.size, "Should use the new cached number" - - apple.clients.to_s - assert_equal 1, apple.clients.size, "Should not use the cached number, but go to the database" - end - - def test_store_two_association_with_one_save - num_orders = Order.count - num_customers = Customer.count - order = Order.new - - customer1 = order.billing = Customer.new - customer2 = order.shipping = Customer.new - assert order.save - assert_equal customer1, order.billing - assert_equal customer2, order.shipping - - order.reload - - assert_equal customer1, order.billing - assert_equal customer2, order.shipping - - assert_equal num_orders +1, Order.count - assert_equal num_customers +2, Customer.count - end - - - def test_store_association_in_two_relations_with_one_save - num_orders = Order.count - num_customers = Customer.count - order = Order.new - - customer = order.billing = order.shipping = Customer.new - assert order.save - assert_equal customer, order.billing - assert_equal customer, order.shipping - - order.reload - - assert_equal customer, order.billing - assert_equal customer, order.shipping - - assert_equal num_orders +1, Order.count - assert_equal num_customers +1, Customer.count - end - - def test_store_association_in_two_relations_with_one_save_in_existing_object - num_orders = Order.count - num_customers = Customer.count - order = Order.create - - customer = order.billing = order.shipping = Customer.new - assert order.save - assert_equal customer, order.billing - assert_equal customer, order.shipping - - order.reload - - assert_equal customer, order.billing - assert_equal customer, order.shipping - - assert_equal num_orders +1, Order.count - assert_equal num_customers +1, Customer.count - end - - def test_store_association_in_two_relations_with_one_save_in_existing_object_with_values - num_orders = Order.count - num_customers = Customer.count - order = Order.create - - customer = order.billing = order.shipping = Customer.new - assert order.save - assert_equal customer, order.billing - assert_equal customer, order.shipping - - order.reload - - customer = order.billing = order.shipping = Customer.new - - assert order.save - order.reload - - assert_equal customer, order.billing - assert_equal customer, order.shipping - - assert_equal num_orders +1, Order.count - assert_equal num_customers +2, Customer.count - end - - - def test_association_assignment_sticks - post = Post.find(:first) - - author1, author2 = Author.find(:all, :limit => 2) - assert_not_nil author1 - assert_not_nil author2 - - # make sure the association is loaded - post.author - - # set the association by id, directly - post.author_id = author2.id - - # save and reload - post.save! - post.reload - - # the author id of the post should be the id we set - assert_equal post.author_id, author2.id - end - -end - - -class ProjectWithAfterCreateHook < ActiveRecord::Base - set_table_name 'projects' - has_and_belongs_to_many :developers, - :class_name => "DeveloperForProjectWithAfterCreateHook", - :join_table => "developers_projects", - :foreign_key => "project_id", - :association_foreign_key => "developer_id" - - after_create :add_david - - def add_david - david = DeveloperForProjectWithAfterCreateHook.find_by_name('David') - david.projects << self - end -end - -class DeveloperForProjectWithAfterCreateHook < ActiveRecord::Base - set_table_name 'developers' - has_and_belongs_to_many :projects, - :class_name => "ProjectWithAfterCreateHook", - :join_table => "developers_projects", - :association_foreign_key => "project_id", - :foreign_key => "developer_id" -end - - -class HasAndBelongsToManyAssociationsTest < Test::Unit::TestCase - fixtures :accounts, :companies, :developers, :projects, :developers_projects - - def test_has_and_belongs_to_many - david = Developer.find(1) - - assert !david.projects.empty? - assert_equal 2, david.projects.size - - active_record = Project.find(1) - assert !active_record.developers.empty? - assert_equal 2, active_record.developers.size - assert active_record.developers.include?(david) - end - - def test_adding_single - jamis = Developer.find(2) - jamis.projects.reload # causing the collection to load - action_controller = Project.find(2) - assert_equal 1, jamis.projects.size - assert_equal 1, action_controller.developers.size - - jamis.projects << action_controller - - assert_equal 2, jamis.projects.size - assert_equal 2, jamis.projects(true).size - assert_equal 2, action_controller.developers(true).size - end - - def test_adding_type_mismatch - jamis = Developer.find(2) - assert_raise(ActiveRecord::AssociationTypeMismatch) { jamis.projects << nil } - assert_raise(ActiveRecord::AssociationTypeMismatch) { jamis.projects << 1 } - end - - def test_adding_from_the_project - jamis = Developer.find(2) - action_controller = Project.find(2) - action_controller.developers.reload - assert_equal 1, jamis.projects.size - assert_equal 1, action_controller.developers.size - - action_controller.developers << jamis - - assert_equal 2, jamis.projects(true).size - assert_equal 2, action_controller.developers.size - assert_equal 2, action_controller.developers(true).size - end - - def test_adding_from_the_project_fixed_timestamp - jamis = Developer.find(2) - action_controller = Project.find(2) - action_controller.developers.reload - assert_equal 1, jamis.projects.size - assert_equal 1, action_controller.developers.size - updated_at = jamis.updated_at - - action_controller.developers << jamis - - assert_equal updated_at, jamis.updated_at - assert_equal 2, jamis.projects(true).size - assert_equal 2, action_controller.developers.size - assert_equal 2, action_controller.developers(true).size - end - - def test_adding_multiple - aredridel = Developer.new("name" => "Aredridel") - aredridel.save - aredridel.projects.reload - aredridel.projects.push(Project.find(1), Project.find(2)) - assert_equal 2, aredridel.projects.size - assert_equal 2, aredridel.projects(true).size - end - - def test_adding_a_collection - aredridel = Developer.new("name" => "Aredridel") - aredridel.save - aredridel.projects.reload - aredridel.projects.concat([Project.find(1), Project.find(2)]) - assert_equal 2, aredridel.projects.size - assert_equal 2, aredridel.projects(true).size - end - - def test_adding_uses_default_values_on_join_table - ac = projects(:action_controller) - assert !developers(:jamis).projects.include?(ac) - developers(:jamis).projects << ac - - assert developers(:jamis, :reload).projects.include?(ac) - project = developers(:jamis).projects.detect { |p| p == ac } - assert_equal 1, project.access_level.to_i - end - - def test_adding_uses_explicit_values_on_join_table - ac = projects(:action_controller) - assert !developers(:jamis).projects.include?(ac) - developers(:jamis).projects.push_with_attributes(ac, :access_level => 3) - - assert developers(:jamis, :reload).projects.include?(ac) - project = developers(:jamis).projects.detect { |p| p == ac } - assert_equal 3, project.access_level.to_i - end - - def test_hatbm_attribute_access_and_respond_to - project = developers(:jamis).projects[0] - assert project.has_attribute?("name") - assert project.has_attribute?("joined_on") - assert project.has_attribute?("access_level") - assert project.respond_to?("name") - assert project.respond_to?("name=") - assert project.respond_to?("name?") - assert project.respond_to?("joined_on") - assert project.respond_to?("joined_on=") - assert project.respond_to?("joined_on?") - assert project.respond_to?("access_level") - assert project.respond_to?("access_level=") - assert project.respond_to?("access_level?") - end - - def test_habtm_adding_before_save - no_of_devels = Developer.count - no_of_projects = Project.count - aredridel = Developer.new("name" => "Aredridel") - aredridel.projects.concat([Project.find(1), p = Project.new("name" => "Projekt")]) - assert aredridel.new_record? - assert p.new_record? - assert aredridel.save - assert !aredridel.new_record? - assert_equal no_of_devels+1, Developer.count - assert_equal no_of_projects+1, Project.count - assert_equal 2, aredridel.projects.size - assert_equal 2, aredridel.projects(true).size - end - - def test_habtm_adding_before_save_with_join_attributes - no_of_devels = Developer.count - no_of_projects = Project.count - now = Date.today - sqlnow = Time.now.strftime("%Y/%m/%d 00:00:00") - ken = Developer.new("name" => "Ken") - ken.projects.push_with_attributes( Project.find(1), :joined_on => now ) - p = Project.new("name" => "Foomatic") - ken.projects.push_with_attributes( p, :joined_on => now ) - assert ken.new_record? - assert p.new_record? - assert ken.save - assert !ken.new_record? - assert_equal no_of_devels+1, Developer.count - assert_equal no_of_projects+1, Project.count - assert_equal 2, ken.projects.size - assert_equal 2, ken.projects(true).size - - kenReloaded = Developer.find_by_name 'Ken' - # SQL Server doesn't have a separate column type just for dates, - # so the time is in the string and incorrectly formatted - if current_adapter?(:SQLServerAdapter) - kenReloaded.projects.each { |prj| assert_equal(sqlnow, prj.joined_on.strftime("%Y/%m/%d 00:00:00")) } - else - kenReloaded.projects.each { |prj| assert_equal(now.to_s, prj.joined_on.to_s) } - end - end - - def test_build - devel = Developer.find(1) - proj = devel.projects.build("name" => "Projekt") - assert_equal devel.projects.last, proj - assert proj.new_record? - devel.save - assert !proj.new_record? - assert_equal devel.projects.last, proj - end - - def test_create - devel = Developer.find(1) - proj = devel.projects.create("name" => "Projekt") - assert_equal devel.projects.last, proj - assert !proj.new_record? - end - - def test_uniq_after_the_fact - developers(:jamis).projects << projects(:active_record) - developers(:jamis).projects << projects(:active_record) - assert_equal 3, developers(:jamis).projects.size - assert_equal 1, developers(:jamis).projects.uniq.size - end - - def test_uniq_before_the_fact - projects(:active_record).developers << developers(:jamis) - projects(:active_record).developers << developers(:david) - assert_equal 2, projects(:active_record, :reload).developers.size - end - - def test_deleting - david = Developer.find(1) - active_record = Project.find(1) - david.projects.reload - assert_equal 2, david.projects.size - assert_equal 2, active_record.developers.size - - david.projects.delete(active_record) - - assert_equal 1, david.projects.size - assert_equal 1, david.projects(true).size - assert_equal 1, active_record.developers(true).size - end - - def test_deleting_array - david = Developer.find(1) - david.projects.reload - david.projects.delete(Project.find(:all)) - assert_equal 0, david.projects.size - assert_equal 0, david.projects(true).size - end - - def test_deleting_with_sql - david = Developer.find(1) - active_record = Project.find(1) - active_record.developers.reload - assert_equal 2, active_record.developers_by_sql.size - - active_record.developers_by_sql.delete(david) - assert_equal 1, active_record.developers_by_sql(true).size - end - - def test_deleting_array_with_sql - active_record = Project.find(1) - active_record.developers.reload - assert_equal 2, active_record.developers_by_sql.size - - active_record.developers_by_sql.delete(Developer.find(:all)) - assert_equal 0, active_record.developers_by_sql(true).size - end - - def test_deleting_all - david = Developer.find(1) - david.projects.reload - david.projects.clear - assert_equal 0, david.projects.size - assert_equal 0, david.projects(true).size - end - - def test_removing_associations_on_destroy - david = DeveloperWithBeforeDestroyRaise.find(1) - assert !david.projects.empty? - assert_nothing_raised { david.destroy } - assert david.projects.empty? - assert DeveloperWithBeforeDestroyRaise.connection.select_all("SELECT * FROM developers_projects WHERE developer_id = 1").empty? - end - - def test_additional_columns_from_join_table - # SQL Server doesn't have a separate column type just for dates, - # so the time is in the string and incorrectly formatted - if current_adapter?(:SQLServerAdapter) - assert_equal Time.mktime(2004, 10, 10).strftime("%Y/%m/%d 00:00:00"), Developer.find(1).projects.first.joined_on.strftime("%Y/%m/%d 00:00:00") - else - assert_equal Date.new(2004, 10, 10).to_s, Developer.find(1).projects.first.joined_on.to_s - end - end - - def test_destroy_all - david = Developer.find(1) - david.projects.reload - assert !david.projects.empty? - david.projects.destroy_all - assert david.projects.empty? - assert david.projects(true).empty? - end - - def test_rich_association - jamis = developers(:jamis) - jamis.projects.push_with_attributes(projects(:action_controller), :joined_on => Date.today) - # SQL Server doesn't have a separate column type just for dates, - # so the time is in the string and incorrectly formatted - if current_adapter?(:SQLServerAdapter) - assert_equal Time.now.strftime("%Y/%m/%d 00:00:00"), jamis.projects.select { |p| p.name == projects(:action_controller).name }.first.joined_on.strftime("%Y/%m/%d 00:00:00") - assert_equal Time.now.strftime("%Y/%m/%d 00:00:00"), developers(:jamis).projects.select { |p| p.name == projects(:action_controller).name }.first.joined_on.strftime("%Y/%m/%d 00:00:00") - else - assert_equal Date.today.to_s, jamis.projects.select { |p| p.name == projects(:action_controller).name }.first.joined_on.to_s - assert_equal Date.today.to_s, developers(:jamis).projects.select { |p| p.name == projects(:action_controller).name }.first.joined_on.to_s - end - end - - def test_associations_with_conditions - assert_equal 2, projects(:active_record).developers.size - assert_equal 1, projects(:active_record).developers_named_david.size - - assert_equal developers(:david), projects(:active_record).developers_named_david.find(developers(:david).id) - assert_equal developers(:david), projects(:active_record).salaried_developers.find(developers(:david).id) - - projects(:active_record).developers_named_david.clear - assert_equal 1, projects(:active_record, :reload).developers.size - end - - def test_find_in_association - # Using sql - assert_equal developers(:david), projects(:active_record).developers.find(developers(:david).id), "SQL find" - - # Using ruby - active_record = projects(:active_record) - active_record.developers.reload - assert_equal developers(:david), active_record.developers.find(developers(:david).id), "Ruby find" - end - - def test_find_in_association_with_custom_finder_sql - assert_equal developers(:david), projects(:active_record).developers_with_finder_sql.find(developers(:david).id), "SQL find" - - active_record = projects(:active_record) - active_record.developers_with_finder_sql.reload - assert_equal developers(:david), active_record.developers_with_finder_sql.find(developers(:david).id), "Ruby find" - end - - def test_find_in_association_with_custom_finder_sql_and_string_id - assert_equal developers(:david), projects(:active_record).developers_with_finder_sql.find(developers(:david).id.to_s), "SQL find" - end - - - def test_new_with_values_in_collection - jamis = DeveloperForProjectWithAfterCreateHook.find_by_name('Jamis') - david = DeveloperForProjectWithAfterCreateHook.find_by_name('David') - project = ProjectWithAfterCreateHook.new(:name => "Cooking with Bertie") - project.developers << jamis - project.save! - project.reload - - assert project.developers.include?(jamis) - assert project.developers.include?(david) - end - - def xtest_find_in_association_with_options - developers = projects(:active_record).developers.find(:all) - assert_equal 2, developers.size - - assert_equal developers(:david), projects(:active_record).developers.find(:first, :conditions => "salary < 10000") - assert_equal developers(:jamis), projects(:active_record).developers.find(:first, :order => "salary DESC") - end - - def test_replace_with_less - david = developers(:david) - david.projects = [projects(:action_controller)] - assert david.save - assert_equal 1, david.projects.length - end - - def test_replace_with_new - david = developers(:david) - david.projects = [projects(:action_controller), Project.new("name" => "ActionWebSearch")] - david.save - assert_equal 2, david.projects.length - assert !david.projects.include?(projects(:active_record)) - end - - def test_replace_on_new_object - new_developer = Developer.new("name" => "Matz") - new_developer.projects = [projects(:action_controller), Project.new("name" => "ActionWebSearch")] - new_developer.save - assert_equal 2, new_developer.projects.length - end - - def test_consider_type - developer = Developer.find(:first) - special_project = SpecialProject.create("name" => "Special Project") - - other_project = developer.projects.first - developer.special_projects << special_project - developer.reload - - assert developer.projects.include?(special_project) - assert developer.special_projects.include?(special_project) - assert !developer.special_projects.include?(other_project) - end - - def test_update_attributes_after_push_without_duplicate_join_table_rows - developer = Developer.new("name" => "Kano") - project = SpecialProject.create("name" => "Special Project") - assert developer.save - developer.projects << project - developer.update_attribute("name", "Bruza") - assert_equal 1, Developer.connection.select_value(<<-end_sql).to_i - SELECT count(*) FROM developers_projects - WHERE project_id = #{project.id} - AND developer_id = #{developer.id} - end_sql - end -end diff --git a/tracks/vendor/rails/activerecord/test/base_test.rb b/tracks/vendor/rails/activerecord/test/base_test.rb deleted file mode 100644 index a7b1521d..00000000 --- a/tracks/vendor/rails/activerecord/test/base_test.rb +++ /dev/null @@ -1,1135 +0,0 @@ -require 'abstract_unit' -require 'fixtures/topic' -require 'fixtures/reply' -require 'fixtures/company' -require 'fixtures/developer' -require 'fixtures/project' -require 'fixtures/default' -require 'fixtures/auto_id' -require 'fixtures/column_name' -require 'fixtures/subscriber' -require 'fixtures/keyboard' - -class Category < ActiveRecord::Base; end -class Smarts < ActiveRecord::Base; end -class CreditCard < ActiveRecord::Base; end -class MasterCreditCard < ActiveRecord::Base; end -class Post < ActiveRecord::Base; end -class Computer < ActiveRecord::Base; end -class NonExistentTable < ActiveRecord::Base; end -class TestOCIDefault < ActiveRecord::Base; end - -class LoosePerson < ActiveRecord::Base - attr_protected :credit_rating, :administrator -end - -class LooseDescendant < LoosePerson - attr_protected :phone_number -end - -class TightPerson < ActiveRecord::Base - attr_accessible :name, :address -end - -class TightDescendant < TightPerson - attr_accessible :phone_number -end - -class Booleantest < ActiveRecord::Base; end - -class Task < ActiveRecord::Base - attr_protected :starting -end - -class BasicsTest < Test::Unit::TestCase - fixtures :topics, :companies, :developers, :projects, :computers - - def test_table_exists - assert !NonExistentTable.table_exists? - assert Topic.table_exists? - end - - def test_set_attributes - topic = Topic.find(1) - topic.attributes = { "title" => "Budget", "author_name" => "Jason" } - topic.save - assert_equal("Budget", topic.title) - assert_equal("Jason", topic.author_name) - assert_equal(topics(:first).author_email_address, Topic.find(1).author_email_address) - end - - def test_integers_as_nil - test = AutoId.create('value' => '') - assert_nil AutoId.find(test.id).value - end - - def test_set_attributes_with_block - topic = Topic.new do |t| - t.title = "Budget" - t.author_name = "Jason" - end - - assert_equal("Budget", topic.title) - assert_equal("Jason", topic.author_name) - end - - def test_respond_to? - topic = Topic.find(1) - assert topic.respond_to?("title") - assert topic.respond_to?("title?") - assert topic.respond_to?("title=") - assert topic.respond_to?(:title) - assert topic.respond_to?(:title?) - assert topic.respond_to?(:title=) - assert topic.respond_to?("author_name") - assert topic.respond_to?("attribute_names") - assert !topic.respond_to?("nothingness") - assert !topic.respond_to?(:nothingness) - end - - def test_array_content - topic = Topic.new - topic.content = %w( one two three ) - topic.save - - assert_equal(%w( one two three ), Topic.find(topic.id).content) - end - - def test_hash_content - topic = Topic.new - topic.content = { "one" => 1, "two" => 2 } - topic.save - - assert_equal 2, Topic.find(topic.id).content["two"] - - topic.content["three"] = 3 - topic.save - - assert_equal 3, Topic.find(topic.id).content["three"] - end - - def test_update_array_content - topic = Topic.new - topic.content = %w( one two three ) - - topic.content.push "four" - assert_equal(%w( one two three four ), topic.content) - - topic.save - - topic = Topic.find(topic.id) - topic.content << "five" - assert_equal(%w( one two three four five ), topic.content) - end - - def test_case_sensitive_attributes_hash - # DB2 is not case-sensitive - return true if current_adapter?(:DB2Adapter) - - assert_equal @loaded_fixtures['computers']['workstation'].to_hash, Computer.find(:first).attributes - end - - def test_create - topic = Topic.new - topic.title = "New Topic" - topic.save - topicReloaded = Topic.find(topic.id) - assert_equal("New Topic", topicReloaded.title) - end - - def test_create_many - topics = Topic.create([ { "title" => "first" }, { "title" => "second" }]) - assert_equal 2, topics.size - assert_equal "first", topics.first.title - end - - def test_create_columns_not_equal_attributes - topic = Topic.new - topic.title = 'Another New Topic' - topic.send :write_attribute, 'does_not_exist', 'test' - assert_nothing_raised { topic.save } - end - - def test_create_through_factory - topic = Topic.create("title" => "New Topic") - topicReloaded = Topic.find(topic.id) - assert_equal(topic, topicReloaded) - end - - def test_update - topic = Topic.new - topic.title = "Another New Topic" - topic.written_on = "2003-12-12 23:23:00" - topic.save - topicReloaded = Topic.find(topic.id) - assert_equal("Another New Topic", topicReloaded.title) - - topicReloaded.title = "Updated topic" - topicReloaded.save - - topicReloadedAgain = Topic.find(topic.id) - - assert_equal("Updated topic", topicReloadedAgain.title) - end - - def test_update_columns_not_equal_attributes - topic = Topic.new - topic.title = "Still another topic" - topic.save - - topicReloaded = Topic.find(topic.id) - topicReloaded.title = "A New Topic" - topicReloaded.send :write_attribute, 'does_not_exist', 'test' - assert_nothing_raised { topicReloaded.save } - end - - def test_write_attribute - topic = Topic.new - topic.send(:write_attribute, :title, "Still another topic") - assert_equal "Still another topic", topic.title - - topic.send(:write_attribute, "title", "Still another topic: part 2") - assert_equal "Still another topic: part 2", topic.title - end - - def test_read_attribute - topic = Topic.new - topic.title = "Don't change the topic" - assert_equal "Don't change the topic", topic.send(:read_attribute, "title") - assert_equal "Don't change the topic", topic["title"] - - assert_equal "Don't change the topic", topic.send(:read_attribute, :title) - assert_equal "Don't change the topic", topic[:title] - end - - def test_read_attribute_when_false - topic = topics(:first) - topic.approved = false - assert !topic.approved?, "approved should be false" - topic.approved = "false" - assert !topic.approved?, "approved should be false" - end - - def test_read_attribute_when_true - topic = topics(:first) - topic.approved = true - assert topic.approved?, "approved should be true" - topic.approved = "true" - assert topic.approved?, "approved should be true" - end - - def test_read_write_boolean_attribute - topic = Topic.new - # puts "" - # puts "New Topic" - # puts topic.inspect - topic.approved = "false" - # puts "Expecting false" - # puts topic.inspect - assert !topic.approved?, "approved should be false" - topic.approved = "false" - # puts "Expecting false" - # puts topic.inspect - assert !topic.approved?, "approved should be false" - topic.approved = "true" - # puts "Expecting true" - # puts topic.inspect - assert topic.approved?, "approved should be true" - topic.approved = "true" - # puts "Expecting true" - # puts topic.inspect - assert topic.approved?, "approved should be true" - # puts "" - end - - def test_reader_generation - Topic.find(:first).title - Firm.find(:first).name - Client.find(:first).name - if ActiveRecord::Base.generate_read_methods - assert_readers(Topic, %w(type replies_count)) - assert_readers(Firm, %w(type)) - assert_readers(Client, %w(type)) - else - [Topic, Firm, Client].each {|klass| assert_equal klass.read_methods, {}} - end - end - - def test_reader_for_invalid_column_names - # column names which aren't legal ruby ids - topic = Topic.find(:first) - topic.send(:define_read_method, "mumub-jumbo".to_sym, "mumub-jumbo", nil) - assert !Topic.read_methods.include?("mumub-jumbo") - end - - def test_non_attribute_access_and_assignment - topic = Topic.new - assert !topic.respond_to?("mumbo") - assert_raises(NoMethodError) { topic.mumbo } - assert_raises(NoMethodError) { topic.mumbo = 5 } - end - - def test_preserving_date_objects - # SQL Server doesn't have a separate column type just for dates, so all are returned as time - return true if current_adapter?(:SQLServerAdapter) - - assert_kind_of( - Date, Topic.find(1).last_read, - "The last_read attribute should be of the Date class" - ) - end - - def test_preserving_time_objects - assert_kind_of( - Time, Topic.find(1).bonus_time, - "The bonus_time attribute should be of the Time class" - ) - - assert_kind_of( - Time, Topic.find(1).written_on, - "The written_on attribute should be of the Time class" - ) - end - - def test_destroy - topic = Topic.new - topic.title = "Yet Another New Topic" - topic.written_on = "2003-12-12 23:23:00" - topic.save - topic.destroy - assert_raise(ActiveRecord::RecordNotFound) { Topic.find(topic.id) } - end - - def test_destroy_returns_self - topic = Topic.new("title" => "Yet Another Title") - assert topic.save - assert_equal topic, topic.destroy, "destroy did not return destroyed object" - end - - def test_record_not_found_exception - assert_raises(ActiveRecord::RecordNotFound) { topicReloaded = Topic.find(99999) } - end - - def test_initialize_with_attributes - topic = Topic.new({ - "title" => "initialized from attributes", "written_on" => "2003-12-12 23:23" - }) - - assert_equal("initialized from attributes", topic.title) - end - - def test_initialize_with_invalid_attribute - begin - topic = Topic.new({ "title" => "test", - "last_read(1i)" => "2005", "last_read(2i)" => "2", "last_read(3i)" => "31"}) - rescue ActiveRecord::MultiparameterAssignmentErrors => ex - assert_equal(1, ex.errors.size) - assert_equal("last_read", ex.errors[0].attribute) - end - end - - def test_load - topics = Topic.find(:all, :order => 'id') - assert_equal(2, topics.size) - assert_equal(topics(:first).title, topics.first.title) - end - - def test_load_with_condition - topics = Topic.find(:all, :conditions => "author_name = 'Mary'") - - assert_equal(1, topics.size) - assert_equal(topics(:second).title, topics.first.title) - end - - def test_table_name_guesses - assert_equal "topics", Topic.table_name - - assert_equal "categories", Category.table_name - assert_equal "smarts", Smarts.table_name - assert_equal "credit_cards", CreditCard.table_name - assert_equal "master_credit_cards", MasterCreditCard.table_name - - ActiveRecord::Base.pluralize_table_names = false - [Category, Smarts, CreditCard, MasterCreditCard].each{|c| c.reset_table_name} - assert_equal "category", Category.table_name - assert_equal "smarts", Smarts.table_name - assert_equal "credit_card", CreditCard.table_name - assert_equal "master_credit_card", MasterCreditCard.table_name - ActiveRecord::Base.pluralize_table_names = true - [Category, Smarts, CreditCard, MasterCreditCard].each{|c| c.reset_table_name} - - ActiveRecord::Base.table_name_prefix = "test_" - Category.reset_table_name - assert_equal "test_categories", Category.table_name - ActiveRecord::Base.table_name_suffix = "_test" - Category.reset_table_name - assert_equal "test_categories_test", Category.table_name - ActiveRecord::Base.table_name_prefix = "" - Category.reset_table_name - assert_equal "categories_test", Category.table_name - ActiveRecord::Base.table_name_suffix = "" - Category.reset_table_name - assert_equal "categories", Category.table_name - - ActiveRecord::Base.pluralize_table_names = false - ActiveRecord::Base.table_name_prefix = "test_" - Category.reset_table_name - assert_equal "test_category", Category.table_name - ActiveRecord::Base.table_name_suffix = "_test" - Category.reset_table_name - assert_equal "test_category_test", Category.table_name - ActiveRecord::Base.table_name_prefix = "" - Category.reset_table_name - assert_equal "category_test", Category.table_name - ActiveRecord::Base.table_name_suffix = "" - Category.reset_table_name - assert_equal "category", Category.table_name - ActiveRecord::Base.pluralize_table_names = true - [Category, Smarts, CreditCard, MasterCreditCard].each{|c| c.reset_table_name} - end - - def test_destroy_all - assert_equal 2, Topic.count - - Topic.destroy_all "author_name = 'Mary'" - assert_equal 1, Topic.count - end - - def test_destroy_many - assert_equal 3, Client.count - Client.destroy([2, 3]) - assert_equal 1, Client.count - end - - def test_delete_many - Topic.delete([1, 2]) - assert_equal 0, Topic.count - end - - def test_boolean_attributes - assert ! Topic.find(1).approved? - assert Topic.find(2).approved? - end - - def test_increment_counter - Topic.increment_counter("replies_count", 1) - assert_equal 1, Topic.find(1).replies_count - - Topic.increment_counter("replies_count", 1) - assert_equal 2, Topic.find(1).replies_count - end - - def test_decrement_counter - Topic.decrement_counter("replies_count", 2) - assert_equal 1, Topic.find(2).replies_count - - Topic.decrement_counter("replies_count", 2) - assert_equal 0, Topic.find(1).replies_count - end - - def test_update_all - # The ADO library doesn't support the number of affected rows - return true if current_adapter?(:SQLServerAdapter) - - assert_equal 2, Topic.update_all("content = 'bulk updated!'") - assert_equal "bulk updated!", Topic.find(1).content - assert_equal "bulk updated!", Topic.find(2).content - assert_equal 2, Topic.update_all(['content = ?', 'bulk updated again!']); - assert_equal "bulk updated again!", Topic.find(1).content - assert_equal "bulk updated again!", Topic.find(2).content - end - - def test_update_many - topic_data = { 1 => { "content" => "1 updated" }, 2 => { "content" => "2 updated" } } - updated = Topic.update(topic_data.keys, topic_data.values) - - assert_equal 2, updated.size - assert_equal "1 updated", Topic.find(1).content - assert_equal "2 updated", Topic.find(2).content - end - - def test_delete_all - # The ADO library doesn't support the number of affected rows - return true if current_adapter?(:SQLServerAdapter) - - assert_equal 2, Topic.delete_all - end - - def test_update_by_condition - Topic.update_all "content = 'bulk updated!'", ["approved = ?", true] - assert_equal "Have a nice day", Topic.find(1).content - assert_equal "bulk updated!", Topic.find(2).content - end - - def test_attribute_present - t = Topic.new - t.title = "hello there!" - t.written_on = Time.now - assert t.attribute_present?("title") - assert t.attribute_present?("written_on") - assert !t.attribute_present?("content") - end - - def test_attribute_keys_on_new_instance - t = Topic.new - assert_equal nil, t.title, "The topics table has a title column, so it should be nil" - assert_raise(NoMethodError) { t.title2 } - end - - def test_class_name - assert_equal "Firm", ActiveRecord::Base.class_name("firms") - assert_equal "Category", ActiveRecord::Base.class_name("categories") - assert_equal "AccountHolder", ActiveRecord::Base.class_name("account_holder") - - ActiveRecord::Base.pluralize_table_names = false - assert_equal "Firms", ActiveRecord::Base.class_name( "firms" ) - ActiveRecord::Base.pluralize_table_names = true - - ActiveRecord::Base.table_name_prefix = "test_" - assert_equal "Firm", ActiveRecord::Base.class_name( "test_firms" ) - ActiveRecord::Base.table_name_suffix = "_tests" - assert_equal "Firm", ActiveRecord::Base.class_name( "test_firms_tests" ) - ActiveRecord::Base.table_name_prefix = "" - assert_equal "Firm", ActiveRecord::Base.class_name( "firms_tests" ) - ActiveRecord::Base.table_name_suffix = "" - assert_equal "Firm", ActiveRecord::Base.class_name( "firms" ) - end - - def test_null_fields - assert_nil Topic.find(1).parent_id - assert_nil Topic.create("title" => "Hey you").parent_id - end - - def test_default_values - topic = Topic.new - assert topic.approved? - assert_nil topic.written_on - assert_nil topic.bonus_time - assert_nil topic.last_read - - topic.save - - topic = Topic.find(topic.id) - assert topic.approved? - assert_nil topic.last_read - - # Oracle has some funky default handling, so it requires a bit of - # extra testing. See ticket #2788. - if current_adapter?(:OCIAdapter) - test = TestOCIDefault.new - assert_equal "X", test.test_char - assert_equal "hello", test.test_string - assert_equal 3, test.test_int - end - end - - def test_utc_as_time_zone - # Oracle and SQLServer do not have a TIME datatype. - return true if current_adapter?(:SQLServerAdapter) || current_adapter?(:OCIAdapter) - - Topic.default_timezone = :utc - attributes = { "bonus_time" => "5:42:00AM" } - topic = Topic.find(1) - topic.attributes = attributes - assert_equal Time.utc(2000, 1, 1, 5, 42, 0), topic.bonus_time - Topic.default_timezone = :local - end - - def test_default_values_on_empty_strings - topic = Topic.new - topic.approved = nil - topic.last_read = nil - - topic.save - - topic = Topic.find(topic.id) - assert_nil topic.last_read - assert_nil topic.approved - end - - def test_equality - assert_equal Topic.find(1), Topic.find(2).parent - end - - def test_equality_of_new_records - assert_not_equal Topic.new, Topic.new - end - - def test_hashing - assert_equal [ Topic.find(1) ], [ Topic.find(2).parent ] & [ Topic.find(1) ] - end - - def test_destroy_new_record - client = Client.new - client.destroy - assert client.frozen? - end - - def test_destroy_record_with_associations - client = Client.find(3) - client.destroy - assert client.frozen? - assert_kind_of Firm, client.firm - assert_raises(TypeError) { client.name = "something else" } - end - - def test_update_attribute - assert !Topic.find(1).approved? - Topic.find(1).update_attribute("approved", true) - assert Topic.find(1).approved? - - Topic.find(1).update_attribute(:approved, false) - assert !Topic.find(1).approved? - end - - def test_mass_assignment_protection - firm = Firm.new - firm.attributes = { "name" => "Next Angle", "rating" => 5 } - assert_equal 1, firm.rating - end - - def test_customized_primary_key_remains_protected - subscriber = Subscriber.new(:nick => 'webster123', :name => 'nice try') - assert_nil subscriber.id - - keyboard = Keyboard.new(:key_number => 9, :name => 'nice try') - assert_nil keyboard.id - end - - def test_customized_primary_key_remains_protected_when_refered_to_as_id - subscriber = Subscriber.new(:id => 'webster123', :name => 'nice try') - assert_nil subscriber.id - - keyboard = Keyboard.new(:id => 9, :name => 'nice try') - assert_nil keyboard.id - end - - def test_mass_assignment_protection_on_defaults - firm = Firm.new - firm.attributes = { "id" => 5, "type" => "Client" } - assert_nil firm.id - assert_equal "Firm", firm[:type] - end - - def test_mass_assignment_accessible - reply = Reply.new("title" => "hello", "content" => "world", "approved" => true) - reply.save - - assert reply.approved? - - reply.approved = false - reply.save - - assert !reply.approved? - end - - def test_mass_assignment_protection_inheritance - assert_nil LoosePerson.accessible_attributes - assert_equal [ :credit_rating, :administrator ], LoosePerson.protected_attributes - - assert_nil LooseDescendant.accessible_attributes - assert_equal [ :credit_rating, :administrator, :phone_number ], LooseDescendant.protected_attributes - - assert_nil TightPerson.protected_attributes - assert_equal [ :name, :address ], TightPerson.accessible_attributes - - assert_nil TightDescendant.protected_attributes - assert_equal [ :name, :address, :phone_number ], TightDescendant.accessible_attributes - end - - def test_multiparameter_attributes_on_date - # SQL Server doesn't have a separate column type just for dates, so all are returned as time - return true if current_adapter?(:SQLServerAdapter) - - attributes = { "last_read(1i)" => "2004", "last_read(2i)" => "6", "last_read(3i)" => "24" } - topic = Topic.find(1) - topic.attributes = attributes - # note that extra #to_date call allows test to pass for Oracle, which - # treats dates/times the same - assert_equal Date.new(2004, 6, 24).to_s, topic.last_read.to_date.to_s - end - - def test_multiparameter_attributes_on_date_with_empty_date - # SQL Server doesn't have a separate column type just for dates, so all are returned as time - return true if current_adapter?(:SQLServerAdapter) - - attributes = { "last_read(1i)" => "2004", "last_read(2i)" => "6", "last_read(3i)" => "" } - topic = Topic.find(1) - topic.attributes = attributes - # note that extra #to_date call allows test to pass for Oracle, which - # treats dates/times the same - assert_equal Date.new(2004, 6, 1).to_s, topic.last_read.to_date.to_s - end - - def test_multiparameter_attributes_on_date_with_all_empty - attributes = { "last_read(1i)" => "", "last_read(2i)" => "", "last_read(3i)" => "" } - topic = Topic.find(1) - topic.attributes = attributes - assert_nil topic.last_read - end - - def test_multiparameter_attributes_on_time - attributes = { - "written_on(1i)" => "2004", "written_on(2i)" => "6", "written_on(3i)" => "24", - "written_on(4i)" => "16", "written_on(5i)" => "24", "written_on(6i)" => "00" - } - topic = Topic.find(1) - topic.attributes = attributes - assert_equal Time.local(2004, 6, 24, 16, 24, 0), topic.written_on - end - - def test_multiparameter_attributes_on_time_with_empty_seconds - attributes = { - "written_on(1i)" => "2004", "written_on(2i)" => "6", "written_on(3i)" => "24", - "written_on(4i)" => "16", "written_on(5i)" => "24", "written_on(6i)" => "" - } - topic = Topic.find(1) - topic.attributes = attributes - assert_equal Time.local(2004, 6, 24, 16, 24, 0), topic.written_on - end - - def test_multiparameter_mass_assignment_protector - task = Task.new - time = Time.mktime(2000, 1, 1, 1) - task.starting = time - attributes = { "starting(1i)" => "2004", "starting(2i)" => "6", "starting(3i)" => "24" } - task.attributes = attributes - assert_equal time, task.starting - end - - def test_attributes_on_dummy_time - # Oracle and SQL Server do not have a TIME datatype. - return true if current_adapter?(:SQLServerAdapter) || current_adapter?(:OCIAdapter) - - attributes = { - "bonus_time" => "5:42:00AM" - } - topic = Topic.find(1) - topic.attributes = attributes - assert_equal Time.local(2000, 1, 1, 5, 42, 0), topic.bonus_time - end - - def test_boolean - b_false = Booleantest.create({ "value" => false }) - false_id = b_false.id - b_true = Booleantest.create({ "value" => true }) - true_id = b_true.id - - b_false = Booleantest.find(false_id) - assert !b_false.value? - b_true = Booleantest.find(true_id) - assert b_true.value? - end - - def test_clone - topic = Topic.find(1) - cloned_topic = nil - assert_nothing_raised { cloned_topic = topic.clone } - assert_equal topic.title, cloned_topic.title - assert cloned_topic.new_record? - - # test if the attributes have been cloned - topic.title = "a" - cloned_topic.title = "b" - assert_equal "a", topic.title - assert_equal "b", cloned_topic.title - - # test if the attribute values have been cloned - topic.title = {"a" => "b"} - cloned_topic = topic.clone - cloned_topic.title["a"] = "c" - assert_equal "b", topic.title["a"] - - cloned_topic.save - assert !cloned_topic.new_record? - assert cloned_topic.id != topic.id - end - - def test_clone_with_aggregate_of_same_name_as_attribute - dev = DeveloperWithAggregate.find(1) - assert_kind_of DeveloperSalary, dev.salary - - clone = nil - assert_nothing_raised { clone = dev.clone } - assert_kind_of DeveloperSalary, clone.salary - assert_equal dev.salary.amount, clone.salary.amount - assert clone.new_record? - - # test if the attributes have been cloned - original_amount = clone.salary.amount - dev.salary.amount = 1 - assert_equal original_amount, clone.salary.amount - - assert clone.save - assert !clone.new_record? - assert clone.id != dev.id - end - - def test_clone_preserves_subtype - clone = nil - assert_nothing_raised { clone = Company.find(3).clone } - assert_kind_of Client, clone - end - - def test_bignum - company = Company.find(1) - company.rating = 2147483647 - company.save - company = Company.find(1) - assert_equal 2147483647, company.rating - end - - # TODO: extend defaults tests to other databases! - if current_adapter?(:PostgreSQLAdapter) - def test_default - default = Default.new - - # CURRENT_TIMESTAMP and NOW() timestamps - time_format = "%m/%d/%Y %H:%M" - now = Time.now.strftime(time_format) - assert_equal now, default.modified_time.strftime(time_format) - assert_equal now, default.modified_time_function.strftime(time_format) - - # CURRENT_DATE and NOW() dates - today = Date.today - assert_equal today, default.modified_date - assert_equal today, default.modified_date_function - - # fixed dates / times - assert_equal Date.new(2004, 1, 1), default.fixed_date - assert_equal Time.local(2004, 1,1,0,0,0,0), default.fixed_time - - # char types - assert_equal 'Y', default.char1 - assert_equal 'a varchar field', default.char2 - assert_equal 'a text field', default.char3 - end - - class Geometric < ActiveRecord::Base; end - def test_geometric_content - - # accepted format notes: - # ()'s aren't required - # values can be a mix of float or integer - - g = Geometric.new( - :a_point => '(5.0, 6.1)', - #:a_line => '((2.0, 3), (5.5, 7.0))' # line type is currently unsupported in postgresql - :a_line_segment => '(2.0, 3), (5.5, 7.0)', - :a_box => '2.0, 3, 5.5, 7.0', - :a_path => '[(2.0, 3), (5.5, 7.0), (8.5, 11.0)]', # [ ] is an open path - :a_polygon => '((2.0, 3), (5.5, 7.0), (8.5, 11.0))', - :a_circle => '<(5.3, 10.4), 2>' - ) - - assert g.save - - # Reload and check that we have all the geometric attributes. - h = Geometric.find(g.id) - - assert_equal '(5,6.1)', h.a_point - assert_equal '[(2,3),(5.5,7)]', h.a_line_segment - assert_equal '(5.5,7),(2,3)', h.a_box # reordered to store upper right corner then bottom left corner - assert_equal '[(2,3),(5.5,7),(8.5,11)]', h.a_path - assert_equal '((2,3),(5.5,7),(8.5,11))', h.a_polygon - assert_equal '<(5.3,10.4),2>', h.a_circle - - # use a geometric function to test for an open path - objs = Geometric.find_by_sql ["select isopen(a_path) from geometrics where id = ?", g.id] - assert_equal objs[0].isopen, 't' - - # test alternate formats when defining the geometric types - - g = Geometric.new( - :a_point => '5.0, 6.1', - #:a_line => '((2.0, 3), (5.5, 7.0))' # line type is currently unsupported in postgresql - :a_line_segment => '((2.0, 3), (5.5, 7.0))', - :a_box => '(2.0, 3), (5.5, 7.0)', - :a_path => '((2.0, 3), (5.5, 7.0), (8.5, 11.0))', # ( ) is a closed path - :a_polygon => '2.0, 3, 5.5, 7.0, 8.5, 11.0', - :a_circle => '((5.3, 10.4), 2)' - ) - - assert g.save - - # Reload and check that we have all the geometric attributes. - h = Geometric.find(g.id) - - assert_equal '(5,6.1)', h.a_point - assert_equal '[(2,3),(5.5,7)]', h.a_line_segment - assert_equal '(5.5,7),(2,3)', h.a_box # reordered to store upper right corner then bottom left corner - assert_equal '((2,3),(5.5,7),(8.5,11))', h.a_path - assert_equal '((2,3),(5.5,7),(8.5,11))', h.a_polygon - assert_equal '<(5.3,10.4),2>', h.a_circle - - # use a geometric function to test for an closed path - objs = Geometric.find_by_sql ["select isclosed(a_path) from geometrics where id = ?", g.id] - assert_equal objs[0].isclosed, 't' - end - end - - def test_auto_id - auto = AutoId.new - auto.save - assert (auto.id > 0) - end - - def quote_column_name(name) - "<#{name}>" - end - - def test_quote_keys - ar = AutoId.new - source = {"foo" => "bar", "baz" => "quux"} - actual = ar.send(:quote_columns, self, source) - inverted = actual.invert - assert_equal("", inverted["bar"]) - assert_equal("", inverted["quux"]) - end - - def test_column_name_properly_quoted - col_record = ColumnName.new - col_record.references = 40 - assert col_record.save - col_record.references = 41 - assert col_record.save - assert_not_nil c2 = ColumnName.find(col_record.id) - assert_equal(41, c2.references) - end - - MyObject = Struct.new :attribute1, :attribute2 - - def test_serialized_attribute - myobj = MyObject.new('value1', 'value2') - topic = Topic.create("content" => myobj) - Topic.serialize("content", MyObject) - assert_equal(myobj, topic.content) - end - - def test_serialized_attribute_with_class_constraint - myobj = MyObject.new('value1', 'value2') - topic = Topic.create("content" => myobj) - Topic.serialize(:content, Hash) - - assert_raise(ActiveRecord::SerializationTypeMismatch) { Topic.find(topic.id).content } - - settings = { "color" => "blue" } - Topic.find(topic.id).update_attribute("content", settings) - assert_equal(settings, Topic.find(topic.id).content) - Topic.serialize(:content) - end - - def test_quote - author_name = "\\ \001 ' \n \\n \"" - topic = Topic.create('author_name' => author_name) - assert_equal author_name, Topic.find(topic.id).author_name - end - - def test_class_level_destroy - should_be_destroyed_reply = Reply.create("title" => "hello", "content" => "world") - Topic.find(1).replies << should_be_destroyed_reply - - Topic.destroy(1) - assert_raise(ActiveRecord::RecordNotFound) { Topic.find(1) } - assert_raise(ActiveRecord::RecordNotFound) { Reply.find(should_be_destroyed_reply.id) } - end - - def test_class_level_delete - should_be_destroyed_reply = Reply.create("title" => "hello", "content" => "world") - Topic.find(1).replies << should_be_destroyed_reply - - Topic.delete(1) - assert_raise(ActiveRecord::RecordNotFound) { Topic.find(1) } - assert_nothing_raised { Reply.find(should_be_destroyed_reply.id) } - end - - def test_increment_attribute - assert_equal 0, topics(:first).replies_count - topics(:first).increment! :replies_count - assert_equal 1, topics(:first, :reload).replies_count - - topics(:first).increment(:replies_count).increment!(:replies_count) - assert_equal 3, topics(:first, :reload).replies_count - end - - def test_increment_nil_attribute - assert_nil topics(:first).parent_id - topics(:first).increment! :parent_id - assert_equal 1, topics(:first).parent_id - end - - def test_decrement_attribute - topics(:first).increment(:replies_count).increment!(:replies_count) - assert_equal 2, topics(:first).replies_count - - topics(:first).decrement!(:replies_count) - assert_equal 1, topics(:first, :reload).replies_count - - topics(:first).decrement(:replies_count).decrement!(:replies_count) - assert_equal -1, topics(:first, :reload).replies_count - end - - def test_toggle_attribute - assert !topics(:first).approved? - topics(:first).toggle!(:approved) - assert topics(:first).approved? - topic = topics(:first) - topic.toggle(:approved) - assert !topic.approved? - topic.reload - assert topic.approved? - end - - def test_reload - t1 = Topic.find(1) - t2 = Topic.find(1) - t1.title = "something else" - t1.save - t2.reload - assert_equal t1.title, t2.title - end - - def test_define_attr_method_with_value - k = Class.new( ActiveRecord::Base ) - k.send(:define_attr_method, :table_name, "foo") - assert_equal "foo", k.table_name - end - - def test_define_attr_method_with_block - k = Class.new( ActiveRecord::Base ) - k.send(:define_attr_method, :primary_key) { "sys_" + original_primary_key } - assert_equal "sys_id", k.primary_key - end - - def test_set_table_name_with_value - k = Class.new( ActiveRecord::Base ) - k.table_name = "foo" - assert_equal "foo", k.table_name - k.set_table_name "bar" - assert_equal "bar", k.table_name - end - - def test_set_table_name_with_block - k = Class.new( ActiveRecord::Base ) - k.set_table_name { "ks" } - assert_equal "ks", k.table_name - end - - def test_set_primary_key_with_value - k = Class.new( ActiveRecord::Base ) - k.primary_key = "foo" - assert_equal "foo", k.primary_key - k.set_primary_key "bar" - assert_equal "bar", k.primary_key - end - - def test_set_primary_key_with_block - k = Class.new( ActiveRecord::Base ) - k.set_primary_key { "sys_" + original_primary_key } - assert_equal "sys_id", k.primary_key - end - - def test_set_inheritance_column_with_value - k = Class.new( ActiveRecord::Base ) - k.inheritance_column = "foo" - assert_equal "foo", k.inheritance_column - k.set_inheritance_column "bar" - assert_equal "bar", k.inheritance_column - end - - def test_set_inheritance_column_with_block - k = Class.new( ActiveRecord::Base ) - k.set_inheritance_column { original_inheritance_column + "_id" } - assert_equal "type_id", k.inheritance_column - end - - def test_count_with_join - res = Post.count_by_sql "SELECT COUNT(*) FROM posts LEFT JOIN comments ON posts.id=comments.post_id WHERE posts.#{QUOTED_TYPE} = 'Post'" - res2 = res + 1 - assert_nothing_raised do - res2 = Post.count("posts.#{QUOTED_TYPE} = 'Post'", - "LEFT JOIN comments ON posts.id=comments.post_id") - end - assert_equal res, res2 - end - - def test_clear_association_cache_stored - firm = Firm.find(1) - assert_kind_of Firm, firm - - firm.clear_association_cache - assert_equal Firm.find(1).clients.collect{ |x| x.name }.sort, firm.clients.collect{ |x| x.name }.sort - end - - def test_clear_association_cache_new_record - firm = Firm.new - client_stored = Client.find(3) - client_new = Client.new - client_new.name = "The Joneses" - clients = [ client_stored, client_new ] - - firm.clients << clients - - firm.clear_association_cache - - assert_equal firm.clients.collect{ |x| x.name }.sort, clients.collect{ |x| x.name }.sort - end - - def test_interpolate_sql - assert_nothing_raised { Category.new.send(:interpolate_sql, 'foo@bar') } - assert_nothing_raised { Category.new.send(:interpolate_sql, 'foo bar) baz') } - assert_nothing_raised { Category.new.send(:interpolate_sql, 'foo bar} baz') } - end - - def test_scoped_find_conditions - developers = Developer.with_scope(:find => { :conditions => 'salary > 90000' }) do - Developer.find(:all, :conditions => 'id < 5') - end - david = Developer.find(1) - assert !developers.include?(david) # David's salary is less than 90,000 - assert_equal 3, developers.size - end - - def test_scoped_find_limit_offset - developers = Developer.with_scope(:find => { :limit => 3, :offset => 2 }) do - Developer.find(:all, :order => 'id') - end - david = Developer.find(1) - jamis = Developer.find(1) - assert !developers.include?(david) # David has id 1 - assert !developers.include?(jamis) # Jamis has id 2 - assert_equal 3, developers.size - - # Test without scoped find conditions to ensure we get the whole thing - developers = Developer.find(:all, :order => 'id') - assert_equal 10, developers.size - end - - # FIXME: this test ought to run, but it needs to run sandboxed so that it - # doesn't b0rk the current test environment by undefing everything. - # - #def test_dev_mode_memory_leak - # counts = [] - # 2.times do - # require_dependency 'fixtures/company' - # Firm.find(:first) - # Dependencies.clear - # ActiveRecord::Base.reset_subclasses - # Dependencies.remove_subclasses_for(ActiveRecord::Base) - # - # GC.start - # - # count = 0 - # ObjectSpace.each_object(Proc) { count += 1 } - # counts << count - # end - # assert counts.last <= counts.first, - # "expected last count (#{counts.last}) to be <= first count (#{counts.first})" - #end - - private - def assert_readers(model, exceptions) - expected_readers = model.column_names - (model.serialized_attributes.keys + exceptions + ['id']) - assert_equal expected_readers.sort, model.read_methods.to_a.sort - end -end diff --git a/tracks/vendor/rails/activerecord/test/binary_test.rb b/tracks/vendor/rails/activerecord/test/binary_test.rb deleted file mode 100644 index 8ba758a8..00000000 --- a/tracks/vendor/rails/activerecord/test/binary_test.rb +++ /dev/null @@ -1,37 +0,0 @@ -require 'abstract_unit' -require 'fixtures/binary' - -class BinaryTest < Test::Unit::TestCase - BINARY_FIXTURE_PATH = File.dirname(__FILE__) + '/fixtures/flowers.jpg' - - def setup - Binary.connection.execute 'DELETE FROM binaries' - @data = File.read(BINARY_FIXTURE_PATH).freeze - end - - def test_truth - assert true - end - - # Without using prepared statements, it makes no sense to test - # BLOB data with SQL Server, because the length of a statement is - # limited to 8KB. - # - # Without using prepared statements, it makes no sense to test - # BLOB data with DB2 or Firebird, because the length of a statement - # is limited to 32KB. - unless %w(SQLServer DB2 OCI Firebird).include? ActiveRecord::Base.connection.adapter_name - def test_load_save - bin = Binary.new - bin.data = @data - - assert @data == bin.data, 'Newly assigned data differs from original' - - bin.save - assert @data == bin.data, 'Data differs from original after save' - - db_bin = Binary.find(bin.id) - assert @data == db_bin.data, 'Reloaded data differs from original' - end - end -end diff --git a/tracks/vendor/rails/activerecord/test/callbacks_test.rb b/tracks/vendor/rails/activerecord/test/callbacks_test.rb deleted file mode 100644 index c1639c17..00000000 --- a/tracks/vendor/rails/activerecord/test/callbacks_test.rb +++ /dev/null @@ -1,382 +0,0 @@ -require 'abstract_unit' - -class CallbackDeveloper < ActiveRecord::Base - set_table_name 'developers' - - class << self - def callback_string(callback_method) - "history << [#{callback_method.to_sym.inspect}, :string]" - end - - def callback_proc(callback_method) - Proc.new { |model| model.history << [callback_method, :proc] } - end - - def define_callback_method(callback_method) - define_method("#{callback_method}_method") do |model| - model.history << [callback_method, :method] - end - end - - def callback_object(callback_method) - klass = Class.new - klass.send(:define_method, callback_method) do |model| - model.history << [callback_method, :object] - end - klass.new - end - end - - ActiveRecord::Callbacks::CALLBACKS.each do |callback_method| - callback_method_sym = callback_method.to_sym - define_callback_method(callback_method_sym) - send(callback_method, callback_method_sym) - send(callback_method, callback_string(callback_method_sym)) - send(callback_method, callback_proc(callback_method_sym)) - send(callback_method, callback_object(callback_method_sym)) - send(callback_method) { |model| model.history << [callback_method_sym, :block] } - end - - def history - @history ||= [] - end - - # after_initialize and after_find are invoked only if instance methods have been defined. - def after_initialize - end - - def after_find - end -end - -class RecursiveCallbackDeveloper < ActiveRecord::Base - set_table_name 'developers' - - before_save :on_before_save - after_save :on_after_save - - attr_reader :on_before_save_called, :on_after_save_called - - def on_before_save - @on_before_save_called ||= 0 - @on_before_save_called += 1 - save unless @on_before_save_called > 1 - end - - def on_after_save - @on_after_save_called ||= 0 - @on_after_save_called += 1 - save unless @on_after_save_called > 1 - end -end - -class ImmutableDeveloper < ActiveRecord::Base - set_table_name 'developers' - - validates_inclusion_of :salary, :in => 50000..200000 - - before_save :cancel - before_destroy :cancel - - def cancelled? - @cancelled == true - end - - private - def cancel - @cancelled = true - false - end -end - -class ImmutableMethodDeveloper < ActiveRecord::Base - set_table_name 'developers' - - validates_inclusion_of :salary, :in => 50000..200000 - - def cancelled? - @cancelled == true - end - - def before_save - @cancelled = true - false - end - - def before_destroy - @cancelled = true - false - end -end - -class CallbacksTest < Test::Unit::TestCase - fixtures :developers - - def test_initialize - david = CallbackDeveloper.new - assert_equal [ - [ :after_initialize, :string ], - [ :after_initialize, :proc ], - [ :after_initialize, :object ], - [ :after_initialize, :block ], - ], david.history - end - - def test_find - david = CallbackDeveloper.find(1) - assert_equal [ - [ :after_find, :string ], - [ :after_find, :proc ], - [ :after_find, :object ], - [ :after_find, :block ], - [ :after_initialize, :string ], - [ :after_initialize, :proc ], - [ :after_initialize, :object ], - [ :after_initialize, :block ], - ], david.history - end - - def test_new_valid? - david = CallbackDeveloper.new - david.valid? - assert_equal [ - [ :after_initialize, :string ], - [ :after_initialize, :proc ], - [ :after_initialize, :object ], - [ :after_initialize, :block ], - [ :before_validation, :string ], - [ :before_validation, :proc ], - [ :before_validation, :object ], - [ :before_validation, :block ], - [ :before_validation_on_create, :string ], - [ :before_validation_on_create, :proc ], - [ :before_validation_on_create, :object ], - [ :before_validation_on_create, :block ], - [ :after_validation, :string ], - [ :after_validation, :proc ], - [ :after_validation, :object ], - [ :after_validation, :block ], - [ :after_validation_on_create, :string ], - [ :after_validation_on_create, :proc ], - [ :after_validation_on_create, :object ], - [ :after_validation_on_create, :block ] - ], david.history - end - - def test_existing_valid? - david = CallbackDeveloper.find(1) - david.valid? - assert_equal [ - [ :after_find, :string ], - [ :after_find, :proc ], - [ :after_find, :object ], - [ :after_find, :block ], - [ :after_initialize, :string ], - [ :after_initialize, :proc ], - [ :after_initialize, :object ], - [ :after_initialize, :block ], - [ :before_validation, :string ], - [ :before_validation, :proc ], - [ :before_validation, :object ], - [ :before_validation, :block ], - [ :before_validation_on_update, :string ], - [ :before_validation_on_update, :proc ], - [ :before_validation_on_update, :object ], - [ :before_validation_on_update, :block ], - [ :after_validation, :string ], - [ :after_validation, :proc ], - [ :after_validation, :object ], - [ :after_validation, :block ], - [ :after_validation_on_update, :string ], - [ :after_validation_on_update, :proc ], - [ :after_validation_on_update, :object ], - [ :after_validation_on_update, :block ] - ], david.history - end - - def test_create - david = CallbackDeveloper.create('name' => 'David', 'salary' => 1000000) - assert_equal [ - [ :after_initialize, :string ], - [ :after_initialize, :proc ], - [ :after_initialize, :object ], - [ :after_initialize, :block ], - [ :before_validation, :string ], - [ :before_validation, :proc ], - [ :before_validation, :object ], - [ :before_validation, :block ], - [ :before_validation_on_create, :string ], - [ :before_validation_on_create, :proc ], - [ :before_validation_on_create, :object ], - [ :before_validation_on_create, :block ], - [ :after_validation, :string ], - [ :after_validation, :proc ], - [ :after_validation, :object ], - [ :after_validation, :block ], - [ :after_validation_on_create, :string ], - [ :after_validation_on_create, :proc ], - [ :after_validation_on_create, :object ], - [ :after_validation_on_create, :block ], - [ :before_save, :string ], - [ :before_save, :proc ], - [ :before_save, :object ], - [ :before_save, :block ], - [ :before_create, :string ], - [ :before_create, :proc ], - [ :before_create, :object ], - [ :before_create, :block ], - [ :after_create, :string ], - [ :after_create, :proc ], - [ :after_create, :object ], - [ :after_create, :block ], - [ :after_save, :string ], - [ :after_save, :proc ], - [ :after_save, :object ], - [ :after_save, :block ] - ], david.history - end - - def test_save - david = CallbackDeveloper.find(1) - david.save - assert_equal [ - [ :after_find, :string ], - [ :after_find, :proc ], - [ :after_find, :object ], - [ :after_find, :block ], - [ :after_initialize, :string ], - [ :after_initialize, :proc ], - [ :after_initialize, :object ], - [ :after_initialize, :block ], - [ :before_validation, :string ], - [ :before_validation, :proc ], - [ :before_validation, :object ], - [ :before_validation, :block ], - [ :before_validation_on_update, :string ], - [ :before_validation_on_update, :proc ], - [ :before_validation_on_update, :object ], - [ :before_validation_on_update, :block ], - [ :after_validation, :string ], - [ :after_validation, :proc ], - [ :after_validation, :object ], - [ :after_validation, :block ], - [ :after_validation_on_update, :string ], - [ :after_validation_on_update, :proc ], - [ :after_validation_on_update, :object ], - [ :after_validation_on_update, :block ], - [ :before_save, :string ], - [ :before_save, :proc ], - [ :before_save, :object ], - [ :before_save, :block ], - [ :before_update, :string ], - [ :before_update, :proc ], - [ :before_update, :object ], - [ :before_update, :block ], - [ :after_update, :string ], - [ :after_update, :proc ], - [ :after_update, :object ], - [ :after_update, :block ], - [ :after_save, :string ], - [ :after_save, :proc ], - [ :after_save, :object ], - [ :after_save, :block ] - ], david.history - end - - def test_destroy - david = CallbackDeveloper.find(1) - david.destroy - assert_equal [ - [ :after_find, :string ], - [ :after_find, :proc ], - [ :after_find, :object ], - [ :after_find, :block ], - [ :after_initialize, :string ], - [ :after_initialize, :proc ], - [ :after_initialize, :object ], - [ :after_initialize, :block ], - [ :before_destroy, :string ], - [ :before_destroy, :proc ], - [ :before_destroy, :object ], - [ :before_destroy, :block ], - [ :after_destroy, :string ], - [ :after_destroy, :proc ], - [ :after_destroy, :object ], - [ :after_destroy, :block ] - ], david.history - end - - def test_delete - david = CallbackDeveloper.find(1) - CallbackDeveloper.delete(david.id) - assert_equal [ - [ :after_find, :string ], - [ :after_find, :proc ], - [ :after_find, :object ], - [ :after_find, :block ], - [ :after_initialize, :string ], - [ :after_initialize, :proc ], - [ :after_initialize, :object ], - [ :after_initialize, :block ], - ], david.history - end - - def test_before_save_returning_false - david = ImmutableDeveloper.find(1) - assert david.valid? - assert david.save - assert david.cancelled? - - david = ImmutableDeveloper.find(1) - david.salary = 10_000_000 - assert !david.valid? - assert !david.save - assert !david.cancelled? - - david = ImmutableMethodDeveloper.find(1) - assert david.valid? - assert david.save - assert david.cancelled? - - david = ImmutableMethodDeveloper.find(1) - david.salary = 10_000_000 - assert !david.valid? - assert !david.save - assert !david.cancelled? - end - - def test_before_destroy_returning_false - david = ImmutableDeveloper.find(1) - david.destroy - assert david.cancelled? - assert_not_nil ImmutableDeveloper.find_by_id(1) - - david = ImmutableMethodDeveloper.find(1) - david.destroy - assert david.cancelled? - assert_not_nil ImmutableMethodDeveloper.find_by_id(1) - end - - - def test_zzz_callback_returning_false # must be run last since we modify CallbackDeveloper - david = CallbackDeveloper.find(1) - CallbackDeveloper.before_validation proc { |model| model.history << [:before_validation, :returning_false]; return false } - CallbackDeveloper.before_validation proc { |model| model.history << [:before_validation, :should_never_get_here] } - david.save - assert_equal [ - [ :after_find, :string ], - [ :after_find, :proc ], - [ :after_find, :object ], - [ :after_find, :block ], - [ :after_initialize, :string ], - [ :after_initialize, :proc ], - [ :after_initialize, :object ], - [ :after_initialize, :block ], - [ :before_validation, :string ], - [ :before_validation, :proc ], - [ :before_validation, :object ], - [ :before_validation, :block ], - [ :before_validation, :returning_false ] - ], david.history - end -end diff --git a/tracks/vendor/rails/activerecord/test/class_inheritable_attributes_test.rb b/tracks/vendor/rails/activerecord/test/class_inheritable_attributes_test.rb deleted file mode 100644 index 3419ffbd..00000000 --- a/tracks/vendor/rails/activerecord/test/class_inheritable_attributes_test.rb +++ /dev/null @@ -1,32 +0,0 @@ -require 'test/unit' -require 'abstract_unit' -require 'active_support/class_inheritable_attributes' - -class A - include ClassInheritableAttributes -end - -class B < A - write_inheritable_array "first", [ :one, :two ] -end - -class C < A - write_inheritable_array "first", [ :three ] -end - -class D < B - write_inheritable_array "first", [ :four ] -end - - -class ClassInheritableAttributesTest < Test::Unit::TestCase - def test_first_level - assert_equal [ :one, :two ], B.read_inheritable_attribute("first") - assert_equal [ :three ], C.read_inheritable_attribute("first") - end - - def test_second_level - assert_equal [ :one, :two, :four ], D.read_inheritable_attribute("first") - assert_equal [ :one, :two ], B.read_inheritable_attribute("first") - end -end diff --git a/tracks/vendor/rails/activerecord/test/column_alias_test.rb b/tracks/vendor/rails/activerecord/test/column_alias_test.rb deleted file mode 100644 index 729a252e..00000000 --- a/tracks/vendor/rails/activerecord/test/column_alias_test.rb +++ /dev/null @@ -1,17 +0,0 @@ -require 'abstract_unit' -require 'fixtures/topic' - -class TestColumnAlias < Test::Unit::TestCase - fixtures :topics - - QUERY = if 'OCI' == ActiveRecord::Base.connection.adapter_name - 'SELECT id AS pk FROM topics WHERE ROWNUM < 2' - else - 'SELECT id AS pk FROM topics' - end - - def test_column_alias - records = Topic.connection.select_all(QUERY) - assert_equal 'pk', records[0].keys[0] - end -end diff --git a/tracks/vendor/rails/activerecord/test/connections/native_db2/connection.rb b/tracks/vendor/rails/activerecord/test/connections/native_db2/connection.rb deleted file mode 100644 index aa736ccc..00000000 --- a/tracks/vendor/rails/activerecord/test/connections/native_db2/connection.rb +++ /dev/null @@ -1,24 +0,0 @@ -print "Using native DB2\n" -require_dependency 'fixtures/course' -require 'logger' - -ActiveRecord::Base.logger = Logger.new("debug.log") - -db1 = 'arunit' -db2 = 'arunit2' - -ActiveRecord::Base.establish_connection( - :adapter => "db2", - :host => "localhost", - :username => "arunit", - :password => "arunit", - :database => db1 -) - -Course.establish_connection( - :adapter => "db2", - :host => "localhost", - :username => "arunit2", - :password => "arunit2", - :database => db2 -) diff --git a/tracks/vendor/rails/activerecord/test/connections/native_firebird/connection.rb b/tracks/vendor/rails/activerecord/test/connections/native_firebird/connection.rb deleted file mode 100644 index c861d952..00000000 --- a/tracks/vendor/rails/activerecord/test/connections/native_firebird/connection.rb +++ /dev/null @@ -1,24 +0,0 @@ -print "Using native Firebird\n" -require_dependency 'fixtures/course' -require 'logger' - -ActiveRecord::Base.logger = Logger.new("debug.log") - -db1 = 'activerecord_unittest' -db2 = 'activerecord_unittest2' - -ActiveRecord::Base.establish_connection( - :adapter => "firebird", - :host => "localhost", - :username => "rails", - :password => "rails", - :database => db1 -) - -Course.establish_connection( - :adapter => "firebird", - :host => "localhost", - :username => "rails", - :password => "rails", - :database => db2 -) diff --git a/tracks/vendor/rails/activerecord/test/connections/native_mysql/connection.rb b/tracks/vendor/rails/activerecord/test/connections/native_mysql/connection.rb deleted file mode 100644 index dea33756..00000000 --- a/tracks/vendor/rails/activerecord/test/connections/native_mysql/connection.rb +++ /dev/null @@ -1,20 +0,0 @@ -print "Using native MySQL\n" -require_dependency 'fixtures/course' -require 'logger' - -ActiveRecord::Base.logger = Logger.new("debug.log") - -db1 = 'activerecord_unittest' -db2 = 'activerecord_unittest2' - -ActiveRecord::Base.establish_connection( - :adapter => "mysql", - :username => "rails", - :database => db1 -) - -Course.establish_connection( - :adapter => "mysql", - :username => "rails", - :database => db2 -) diff --git a/tracks/vendor/rails/activerecord/test/connections/native_oci/connection.rb b/tracks/vendor/rails/activerecord/test/connections/native_oci/connection.rb deleted file mode 100644 index 0b1babb8..00000000 --- a/tracks/vendor/rails/activerecord/test/connections/native_oci/connection.rb +++ /dev/null @@ -1,25 +0,0 @@ -print "Using OCI Oracle\n" -require_dependency 'fixtures/course' -require 'logger' - -ActiveRecord::Base.logger = Logger.new STDOUT -ActiveRecord::Base.logger.level = Logger::WARN - -db1 = 'activerecord_unittest' -db2 = 'activerecord_unittest2' - -ActiveRecord::Base.establish_connection( - :adapter => 'oci', - :host => '', # can use an oracle SID - :username => 'arunit', - :password => 'arunit', - :database => db1 -) - -Course.establish_connection( - :adapter => 'oci', - :host => '', # can use an oracle SID - :username => 'arunit2', - :password => 'arunit2', - :database => db2 -) diff --git a/tracks/vendor/rails/activerecord/test/connections/native_postgresql/connection.rb b/tracks/vendor/rails/activerecord/test/connections/native_postgresql/connection.rb deleted file mode 100644 index 1bdff730..00000000 --- a/tracks/vendor/rails/activerecord/test/connections/native_postgresql/connection.rb +++ /dev/null @@ -1,24 +0,0 @@ -print "Using native PostgreSQL\n" -require_dependency 'fixtures/course' -require 'logger' - -ActiveRecord::Base.logger = Logger.new("debug.log") - -db1 = 'activerecord_unittest' -db2 = 'activerecord_unittest2' - -ActiveRecord::Base.establish_connection( - :adapter => "postgresql", - :username => "postgres", - :password => "postgres", - :database => db1, - :min_messages => "warning" -) - -Course.establish_connection( - :adapter => "postgresql", - :username => "postgres", - :password => "postgres", - :database => db2, - :min_messages => "warning" -) diff --git a/tracks/vendor/rails/activerecord/test/connections/native_sqlite/connection.rb b/tracks/vendor/rails/activerecord/test/connections/native_sqlite/connection.rb deleted file mode 100644 index ce3494fb..00000000 --- a/tracks/vendor/rails/activerecord/test/connections/native_sqlite/connection.rb +++ /dev/null @@ -1,37 +0,0 @@ -print "Using native SQlite\n" -require_dependency 'fixtures/course' -require 'logger' -ActiveRecord::Base.logger = Logger.new("debug.log") - -class SqliteError < StandardError -end - -BASE_DIR = File.expand_path(File.dirname(__FILE__) + '/../../fixtures') -sqlite_test_db = "#{BASE_DIR}/fixture_database.sqlite" -sqlite_test_db2 = "#{BASE_DIR}/fixture_database_2.sqlite" - -def make_connection(clazz, db_file, db_definitions_file) - unless File.exist?(db_file) - puts "SQLite database not found at #{db_file}. Rebuilding it." - sqlite_command = %Q{sqlite #{db_file} "create table a (a integer); drop table a;"} - puts "Executing '#{sqlite_command}'" - raise SqliteError.new("Seems that there is no sqlite executable available") unless system(sqlite_command) - clazz.establish_connection( - :adapter => "sqlite", - :database => db_file) - script = File.read("#{BASE_DIR}/db_definitions/#{db_definitions_file}") - # SQLite-Ruby has problems with semi-colon separated commands, so split and execute one at a time - script.split(';').each do - |command| - clazz.connection.execute(command) unless command.strip.empty? - end - else - clazz.establish_connection( - :adapter => "sqlite", - :database => db_file) - end -end - -make_connection(ActiveRecord::Base, sqlite_test_db, 'sqlite.sql') -make_connection(Course, sqlite_test_db2, 'sqlite2.sql') - diff --git a/tracks/vendor/rails/activerecord/test/connections/native_sqlite3/connection.rb b/tracks/vendor/rails/activerecord/test/connections/native_sqlite3/connection.rb deleted file mode 100644 index ab668607..00000000 --- a/tracks/vendor/rails/activerecord/test/connections/native_sqlite3/connection.rb +++ /dev/null @@ -1,36 +0,0 @@ -print "Using native SQLite3\n" -require_dependency 'fixtures/course' -require 'logger' -ActiveRecord::Base.logger = Logger.new("debug.log") - -class SqliteError < StandardError -end - -BASE_DIR = File.expand_path(File.dirname(__FILE__) + '/../../fixtures') -sqlite_test_db = "#{BASE_DIR}/fixture_database.sqlite3" -sqlite_test_db2 = "#{BASE_DIR}/fixture_database_2.sqlite3" - -def make_connection(clazz, db_file, db_definitions_file) - unless File.exist?(db_file) - puts "SQLite3 database not found at #{db_file}. Rebuilding it." - sqlite_command = %Q{sqlite3 #{db_file} "create table a (a integer); drop table a;"} - puts "Executing '#{sqlite_command}'" - raise SqliteError.new("Seems that there is no sqlite3 executable available") unless system(sqlite_command) - clazz.establish_connection( - :adapter => "sqlite3", - :database => db_file) - script = File.read("#{BASE_DIR}/db_definitions/#{db_definitions_file}") - # SQLite-Ruby has problems with semi-colon separated commands, so split and execute one at a time - script.split(';').each do - |command| - clazz.connection.execute(command) unless command.strip.empty? - end - else - clazz.establish_connection( - :adapter => "sqlite3", - :database => db_file) - end -end - -make_connection(ActiveRecord::Base, sqlite_test_db, 'sqlite.sql') -make_connection(Course, sqlite_test_db2, 'sqlite2.sql') diff --git a/tracks/vendor/rails/activerecord/test/connections/native_sqlite3/in_memory_connection.rb b/tracks/vendor/rails/activerecord/test/connections/native_sqlite3/in_memory_connection.rb deleted file mode 100644 index 31b15970..00000000 --- a/tracks/vendor/rails/activerecord/test/connections/native_sqlite3/in_memory_connection.rb +++ /dev/null @@ -1,17 +0,0 @@ -print "Using native SQLite3\n" -require_dependency 'fixtures/course' -require 'logger' -ActiveRecord::Base.logger = Logger.new("debug.log") - -class SqliteError < StandardError -end - -def make_connection(clazz, db_definitions_file) - clazz.establish_connection(:adapter => 'sqlite3', :database => ':memory:') - File.read("#{File.dirname(__FILE__)}/../../fixtures/db_definitions/#{db_definitions_file}").split(';').each do |command| - clazz.connection.execute(command) unless command.strip.empty? - end -end - -make_connection(ActiveRecord::Base, 'sqlite.sql') -make_connection(Course, 'sqlite2.sql') diff --git a/tracks/vendor/rails/activerecord/test/connections/native_sqlserver/connection.rb b/tracks/vendor/rails/activerecord/test/connections/native_sqlserver/connection.rb deleted file mode 100644 index 24658d71..00000000 --- a/tracks/vendor/rails/activerecord/test/connections/native_sqlserver/connection.rb +++ /dev/null @@ -1,24 +0,0 @@ -print "Using native SQLServer\n" -require_dependency 'fixtures/course' -require 'logger' - -ActiveRecord::Base.logger = Logger.new("debug.log") - -db1 = 'activerecord_unittest' -db2 = 'activerecord_unittest2' - -ActiveRecord::Base.establish_connection( - :adapter => "sqlserver", - :host => "localhost", - :username => "sa", - :password => "", - :database => db1 -) - -Course.establish_connection( - :adapter => "sqlserver", - :host => "localhost", - :username => "sa", - :password => "", - :database => db2 -) diff --git a/tracks/vendor/rails/activerecord/test/connections/native_sqlserver_odbc/connection.rb b/tracks/vendor/rails/activerecord/test/connections/native_sqlserver_odbc/connection.rb deleted file mode 100644 index 918be3ed..00000000 --- a/tracks/vendor/rails/activerecord/test/connections/native_sqlserver_odbc/connection.rb +++ /dev/null @@ -1,26 +0,0 @@ -print "Using native SQLServer via ODBC\n" -require_dependency 'fixtures/course' -require 'logger' - -ActiveRecord::Base.logger = Logger.new("debug.log") - -dsn1 = 'activerecord_unittest' -dsn2 = 'activerecord_unittest2' - -ActiveRecord::Base.establish_connection( - :adapter => "sqlserver", - :mode => "ODBC", - :host => "localhost", - :username => "sa", - :password => "", - :dsn => dsn1 -) - -Course.establish_connection( - :adapter => "sqlserver", - :mode => "ODBC", - :host => "localhost", - :username => "sa", - :password => "", - :dsn => dsn2 -) diff --git a/tracks/vendor/rails/activerecord/test/copy_table_sqlite.rb b/tracks/vendor/rails/activerecord/test/copy_table_sqlite.rb deleted file mode 100644 index f3f5f1ce..00000000 --- a/tracks/vendor/rails/activerecord/test/copy_table_sqlite.rb +++ /dev/null @@ -1,64 +0,0 @@ -require 'abstract_unit' - -class CopyTableTest < Test::Unit::TestCase - fixtures :companies, :comments - - def setup - @connection = ActiveRecord::Base.connection - class << @connection - public :copy_table, :table_structure, :indexes - end - end - - def test_copy_table(from = 'companies', to = 'companies2', options = {}) - assert_nothing_raised {copy_table(from, to, options)} - assert_equal row_count(from), row_count(to) - - if block_given? - yield from, to, options - else - assert_equal column_names(from), column_names(to) - end - - @connection.drop_table(to) rescue nil - end - - def test_copy_table_renaming_column - test_copy_table('companies', 'companies2', - :rename => {'client_of' => 'fan_of'}) do |from, to, options| - assert_equal column_values(from, 'client_of').compact.sort, - column_values(to, 'fan_of').compact.sort - end - end - - def test_copy_table_with_index - test_copy_table('comments', 'comments_with_index') do - @connection.add_index('comments_with_index', ['post_id', 'type']) - test_copy_table('comments_with_index', 'comments_with_index2') do - assert_equal table_indexes_without_name('comments_with_index'), - table_indexes_without_name('comments_with_index2') - end - end - end - -protected - def copy_table(from, to, options = {}) - @connection.copy_table(from, to, {:temporary => true}.merge(options)) - end - - def column_names(table) - @connection.table_structure(table).map {|column| column['name']} - end - - def column_values(table, column) - @connection.select_all("SELECT #{column} FROM #{table}").map {|row| row[column]} - end - - def table_indexes_without_name(table) - @connection.indexes('comments_with_index').delete(:name) - end - - def row_count(table) - @connection.select_one("SELECT COUNT(*) AS count FROM #{table}")['count'] - end -end diff --git a/tracks/vendor/rails/activerecord/test/debug.log b/tracks/vendor/rails/activerecord/test/debug.log deleted file mode 100644 index 626fc31a..00000000 --- a/tracks/vendor/rails/activerecord/test/debug.log +++ /dev/null @@ -1,437 +0,0 @@ -# Logfile created on Wed Feb 22 09:02:35 GMT 2006 by logger.rb/1.5.2.4 - SQL (0.364451) CREATE TABLE 'accounts' ( - 'id' INTEGER PRIMARY KEY NOT NULL, - 'firm_id' INTEGER DEFAULT NULL, - 'credit_limit' INTEGER DEFAULT NULL -) - SQL (0.311816)  - -CREATE TABLE 'companies' ( - 'id' INTEGER PRIMARY KEY NOT NULL, - 'type' VARCHAR(255) DEFAULT NULL, - 'ruby_type' VARCHAR(255) DEFAULT NULL, - 'firm_id' INTEGER DEFAULT NULL, - 'name' TEXT DEFAULT NULL, - 'client_of' INTEGER DEFAULT NULL, - 'rating' INTEGER DEFAULT 1 -) - SQL (0.327027)  - - -CREATE TABLE 'topics' ( - 'id' INTEGER PRIMARY KEY NOT NULL, - 'title' VARCHAR(255) DEFAULT NULL, - 'author_name' VARCHAR(255) DEFAULT NULL, - 'author_email_address' VARCHAR(255) DEFAULT NULL, - 'written_on' DATETIME DEFAULT NULL, - 'bonus_time' TIME DEFAULT NULL, - 'last_read' DATE DEFAULT NULL, - 'content' TEXT, - 'approved' boolean DEFAULT 't', - 'replies_count' INTEGER DEFAULT 0, - 'parent_id' INTEGER DEFAULT NULL, - 'type' VARCHAR(255) DEFAULT NULL -) - SQL (0.356027)  - -CREATE TABLE 'developers' ( - 'id' INTEGER PRIMARY KEY NOT NULL, - 'name' TEXT DEFAULT NULL, - 'salary' INTEGER DEFAULT 70000, - 'created_at' DATETIME DEFAULT NULL, - 'updated_at' DATETIME DEFAULT NULL -) - SQL (0.327498)  - -CREATE TABLE 'projects' ( - 'id' INTEGER PRIMARY KEY NOT NULL, - 'name' TEXT DEFAULT NULL, - 'type' VARCHAR(255) DEFAULT NULL -) - SQL (0.327152)  - -CREATE TABLE 'developers_projects' ( - 'developer_id' INTEGER NOT NULL, - 'project_id' INTEGER NOT NULL, - 'joined_on' DATE DEFAULT NULL, - 'access_level' INTEGER DEFAULT 1 -) - SQL (0.326826)  - - -CREATE TABLE 'orders' ( - 'id' INTEGER PRIMARY KEY NOT NULL, - 'name' VARCHAR(255) DEFAULT NULL, - 'billing_customer_id' INTEGER DEFAULT NULL, - 'shipping_customer_id' INTEGER DEFAULT NULL -) - SQL (0.356291)  - -CREATE TABLE 'customers' ( - 'id' INTEGER PRIMARY KEY NOT NULL, - 'name' VARCHAR(255) DEFAULT NULL, - 'balance' INTEGER DEFAULT 0, - 'address_street' TEXT DEFAULT NULL, - 'address_city' TEXT DEFAULT NULL, - 'address_country' TEXT DEFAULT NULL, - 'gps_location' TEXT DEFAULT NULL -) - SQL (0.313541)  - -CREATE TABLE 'movies' ( - 'movieid' INTEGER PRIMARY KEY NOT NULL, - 'name' VARCHAR(255) DEFAULT NULL -) - SQL (0.341444)  - -CREATE TABLE subscribers ( - 'nick' VARCHAR(255) PRIMARY KEY NOT NULL, - 'name' VARCHAR(255) DEFAULT NULL -) - SQL (0.356109)  - -CREATE TABLE 'booleantests' ( - 'id' INTEGER PRIMARY KEY NOT NULL, - 'value' INTEGER DEFAULT NULL -) - SQL (0.299288)  - -CREATE TABLE 'auto_id_tests' ( - 'auto_id' INTEGER PRIMARY KEY NOT NULL, - 'value' INTEGER DEFAULT NULL -) - SQL (0.327438)  - -CREATE TABLE 'entrants' ( - 'id' INTEGER NOT NULL PRIMARY KEY, - 'name' VARCHAR(255) NOT NULL, - 'course_id' INTEGER NOT NULL -) - SQL (0.342461)  - -CREATE TABLE 'colnametests' ( - 'id' INTEGER NOT NULL PRIMARY KEY, - 'references' INTEGER NOT NULL -) - SQL (0.326617)  - -CREATE TABLE 'mixins' ( - 'id' INTEGER NOT NULL PRIMARY KEY, - 'parent_id' INTEGER DEFAULT NULL, - 'type' VARCHAR(40) DEFAULT NULL, - 'pos' INTEGER DEFAULT NULL, - 'lft' INTEGER DEFAULT NULL, - 'rgt' INTEGER DEFAULT NULL, - 'root_id' INTEGER DEFAULT NULL, - 'created_at' DATETIME DEFAULT NULL, - 'updated_at' DATETIME DEFAULT NULL -) - SQL (0.298901)  - -CREATE TABLE 'people' ( - 'id' INTEGER NOT NULL PRIMARY KEY, - 'first_name' VARCHAR(40) DEFAULT NULL, - 'lock_version' INTEGER NOT NULL DEFAULT 0 -) - SQL (0.383537)  - -CREATE TABLE 'binaries' ( - 'id' INTEGER NOT NULL PRIMARY KEY, - 'data' BLOB DEFAULT NULL -) - SQL (0.314553)  - -CREATE TABLE 'computers' ( - 'id' INTEGER NOT NULL PRIMARY KEY, - 'developer' INTEGER NOT NULL, - 'extendedWarranty' INTEGER NOT NULL -) - SQL (0.313509)  - -CREATE TABLE 'posts' ( - 'id' INTEGER NOT NULL PRIMARY KEY, - 'author_id' INTEGER, - 'title' VARCHAR(255) NOT NULL, - 'type' VARCHAR(255) NOT NULL, - 'body' TEXT NOT NULL -) - SQL (0.312656)  - -CREATE TABLE 'comments' ( - 'id' INTEGER NOT NULL PRIMARY KEY, - 'post_id' INTEGER NOT NULL, - 'type' VARCHAR(255) NOT NULL, - 'body' TEXT NOT NULL -) - SQL (0.370833)  - -CREATE TABLE 'authors' ( - 'id' INTEGER NOT NULL PRIMARY KEY, - 'name' VARCHAR(255) NOT NULL -) - SQL (0.341725)  - -CREATE TABLE 'tasks' ( - 'id' INTEGER NOT NULL PRIMARY KEY, - 'starting' DATETIME DEFAULT NULL, - 'ending' DATETIME DEFAULT NULL -) - SQL (0.313227)  - -CREATE TABLE 'categories' ( - 'id' INTEGER NOT NULL PRIMARY KEY, - 'name' VARCHAR(255) NOT NULL, - 'type' VARCHAR(255) DEFAULT NULL -) - SQL (0.342654)  - -CREATE TABLE 'categories_posts' ( - 'category_id' INTEGER NOT NULL, - 'post_id' INTEGER NOT NULL -) - SQL (0.355434)  - -CREATE TABLE 'fk_test_has_pk' ( - 'id' INTEGER NOT NULL PRIMARY KEY -) - SQL (0.313012)  - -CREATE TABLE 'fk_test_has_fk' ( - 'id' INTEGER NOT NULL PRIMARY KEY, - 'fk_id' INTEGER NOT NULL, - - FOREIGN KEY ('fk_id') REFERENCES 'fk_test_has_pk'('id') -) - SQL (0.327909)  - -CREATE TABLE 'keyboards' ( - 'key_number' INTEGER PRIMARY KEY NOT NULL, - 'name' VARCHAR(255) DEFAULT NULL -) - SQL (0.354369) CREATE TABLE 'courses' ( - 'id' INTEGER NOT NULL PRIMARY KEY, - 'name' VARCHAR(255) NOT NULL -) - SQL (0.008238) PRAGMA table_info(topics) - SQL (0.001936) INSERT INTO topics ("author_name", "title", "type", "approved", "bonus_time", "replies_count", "author_email_address", "content", "written_on", "last_read", "parent_id") VALUES(NULL, NULL, NULL, 't', NULL, 0, NULL, '--- -- one -- two -- three', '2006-02-22 09:02:48', NULL, NULL) - Topic Load (0.000691) SELECT * FROM topics WHERE (topics.id = 0) LIMIT 1 - Topic Load (0.004732) SELECT * FROM topics WHERE (topics.id = 1) LIMIT 1 - SQL (0.021708) PRAGMA table_info(auto_id_tests) - SQL (0.001471) INSERT INTO auto_id_tests ("value") VALUES(NULL) - Company Load (0.004551) SELECT * FROM companies WHERE (companies.id = 1) LIMIT 1 - SQL (0.011168) PRAGMA table_info(companies) - Firm Update (0.002707) UPDATE companies SET "name" = '37signals', "client_of" = NULL, "rating" = 2147483647, "firm_id" = NULL, "ruby_type" = 'Firm', "type" = 'Firm' WHERE id = 1 - Company Load (0.002322) SELECT * FROM companies WHERE (companies.id = 1) LIMIT 1 - SQL (0.011983) PRAGMA table_info(booleantests) - SQL (0.001625) INSERT INTO booleantests ("value") VALUES(0) - SQL (0.000608) INSERT INTO booleantests ("value") VALUES(1) - Booleantest Load (0.000551) SELECT * FROM booleantests WHERE (booleantests.id = 0) LIMIT 1 - Topic Load (0.004215) SELECT * FROM topics WHERE (topics.id = 1) LIMIT 1 - Topic Load (0.002738) SELECT * FROM topics WHERE (topics.id = 2) LIMIT 1 - Computer Load (0.004049) SELECT * FROM computers LIMIT 1 - SQL (0.007553) PRAGMA table_info(computers) - SQL (0.018187) PRAGMA table_info(topics) - SQL (0.004108) INSERT INTO topics ("author_name", "title", "type", "approved", "bonus_time", "replies_count", "author_email_address", "content", "written_on", "last_read", "parent_id") VALUES(NULL, 'hello', 'Reply', 't', NULL, 0, NULL, 'world', '2006-02-22 09:02:48', NULL, NULL) - Topic Load (0.002219) SELECT * FROM topics WHERE (topics.id = 1) LIMIT 1 - Reply Load (0.000843) SELECT * FROM topics WHERE (topics.parent_id = 1) AND ( (topics."type" = 'Reply' OR topics."type" = 'SillyReply' ) )  - Reply Update (0.002640) UPDATE topics SET "bonus_time" = NULL, "approved" = 't', "written_on" = '2006-02-22 09:02:48', "author_email_address" = NULL, "content" = 'world', "replies_count" = 0, "title" = 'hello', "author_name" = NULL, "parent_id" = 1, "last_read" = NULL, "type" = 'Reply' WHERE id = 0 - Topic Delete all (0.000936) DELETE FROM topics WHERE (id IN (1))  - Topic Load (0.000583) SELECT * FROM topics WHERE (topics.id = 1) LIMIT 1 - Reply Load (0.000979) SELECT * FROM topics WHERE (topics.id = 0) AND ( (topics."type" = 'Reply' OR topics."type" = 'SillyReply' ) ) LIMIT 1 - SQL (0.003438) INSERT INTO topics ("author_name", "title", "type", "approved", "bonus_time", "replies_count", "author_email_address", "content", "written_on", "last_read", "parent_id") VALUES(NULL, 'hello', 'Reply', 't', NULL, 0, NULL, 'world', '2006-02-22 09:02:48', NULL, NULL) - Topic Load (0.002749) SELECT * FROM topics WHERE (topics.id = 1) LIMIT 1 - Reply Load (0.000902) SELECT * FROM topics WHERE (topics.parent_id = 1) AND ( (topics."type" = 'Reply' OR topics."type" = 'SillyReply' ) )  - Reply Update (0.001912) UPDATE topics SET "bonus_time" = NULL, "approved" = 't', "written_on" = '2006-02-22 09:02:48', "author_email_address" = NULL, "content" = 'world', "replies_count" = 0, "title" = 'hello', "author_name" = NULL, "parent_id" = 1, "last_read" = NULL, "type" = 'Reply' WHERE id = 0 - Topic Load (0.002545) SELECT * FROM topics WHERE (topics.id = 1) LIMIT 1 - Reply Load (0.000860) SELECT * FROM topics WHERE (topics.parent_id = 1) AND ( (topics."type" = 'Reply' OR topics."type" = 'SillyReply' ) )  - Topic Delete all (0.000451) DELETE FROM topics WHERE (parent_id = 1)  - Topic Destroy (0.000557)  DELETE FROM topics - WHERE id = 1 - - Topic Load (0.001116) SELECT * FROM topics WHERE (topics.id = 1) LIMIT 1 - Reply Load (0.000589) SELECT * FROM topics WHERE (topics.id = 0) AND ( (topics."type" = 'Reply' OR topics."type" = 'SillyReply' ) ) LIMIT 1 - SQL (0.011551) PRAGMA table_info(companies) - Client Load (0.004009) SELECT * FROM companies WHERE (companies.id = 3) AND ( (companies."type" = 'Client' OR companies."type" = 'SpecialClient' OR companies."type" = 'VerySpecialClient' ) ) LIMIT 1 - Firm Load (0.007877) SELECT * FROM companies WHERE (companies.id = 1) AND ( (companies."type" = 'Firm' ) ) LIMIT 1 - Firm Load (0.002278) SELECT * FROM companies WHERE (companies.id = 1) AND ( (companies."type" = 'Firm' ) ) LIMIT 1 - Client Load (0.003355) SELECT * FROM companies WHERE (companies.firm_id = 1) AND ( (companies."type" = 'Client' OR companies."type" = 'SpecialClient' OR companies."type" = 'VerySpecialClient' ) ) ORDER BY id  - Client Load (0.005013) SELECT * FROM companies WHERE (companies.firm_id = 1) AND ( (companies."type" = 'Client' OR companies."type" = 'SpecialClient' OR companies."type" = 'VerySpecialClient' ) ) ORDER BY id  - Topic Load (0.010690) SELECT * FROM topics WHERE (topics.id = 1) LIMIT 1 - SQL (0.001431) INSERT INTO topics ("author_name", "title", "type", "approved", "bonus_time", "replies_count", "author_email_address", "content", "written_on", "last_read", "parent_id") VALUES('David', '--- -a: c', NULL, 'f', '2000-01-01 14:28:00', 0, 'david@loudthinking.com', 'Have a nice day', '2003-07-16 15:28:00', '2004-04-15', NULL) - Company Load (0.008524) SELECT * FROM companies WHERE (companies.id = 3) LIMIT 1 - DeveloperWithAggregate Load (0.008655) SELECT * FROM developers WHERE (developers.id = 1) LIMIT 1 - SQL (0.005846) PRAGMA table_info(developers) - SQL (0.002019) INSERT INTO developers ("name", "updated_at", "salary", "created_at") VALUES('David', '2006-02-22 09:02:49', 80000, '2006-02-22 09:02:49') - SQL (0.004239) PRAGMA table_info(colnametests) - SQL (0.002245) INSERT INTO colnametests ("references") VALUES(40) - ColumnName Update (0.002336) UPDATE colnametests SET "references" = 41 WHERE id = 0 - ColumnName Load (0.001016) SELECT * FROM colnametests WHERE (colnametests.id = 0) LIMIT 1 - Post Count (0.003503) SELECT COUNT(*) FROM posts LEFT JOIN comments ON posts.id=comments.post_id WHERE posts."type" = 'Post' - Post Count (0.001267) SELECT COUNT(*) FROM posts LEFT JOIN comments ON posts.id=comments.post_id WHERE (posts."type" = 'Post')  - SQL (0.003124) INSERT INTO topics ("author_name", "title", "type", "approved", "bonus_time", "replies_count", "author_email_address", "content", "written_on", "last_read", "parent_id") VALUES(NULL, 'New Topic', NULL, 't', NULL, 0, NULL, NULL, '2006-02-22 09:02:49', NULL, NULL) - Topic Load (0.000694) SELECT * FROM topics WHERE (topics.id = 0) LIMIT 1 - SQL (0.003434) INSERT INTO topics ("author_name", "title", "type", "approved", "bonus_time", "replies_count", "author_email_address", "content", "written_on", "last_read", "parent_id") VALUES(NULL, 'Another New Topic', NULL, 't', NULL, 0, NULL, NULL, '2006-02-22 09:02:49', NULL, NULL) - SQL (0.003293) INSERT INTO topics ("author_name", "title", "type", "approved", "bonus_time", "replies_count", "author_email_address", "content", "written_on", "last_read", "parent_id") VALUES(NULL, 'first', NULL, 't', NULL, 0, NULL, NULL, '2006-02-22 09:02:49', NULL, NULL) - SQL (0.000571) INSERT INTO topics ("author_name", "title", "type", "approved", "bonus_time", "replies_count", "author_email_address", "content", "written_on", "last_read", "parent_id") VALUES(NULL, 'second', NULL, 't', NULL, 0, NULL, NULL, '2006-02-22 09:02:49', NULL, NULL) - SQL (0.003338) INSERT INTO topics ("author_name", "title", "type", "approved", "bonus_time", "replies_count", "author_email_address", "content", "written_on", "last_read", "parent_id") VALUES(NULL, 'New Topic', NULL, 't', NULL, 0, NULL, NULL, '2006-02-22 09:02:49', NULL, NULL) - Topic Load (0.000593) SELECT * FROM topics WHERE (topics.id = 0) LIMIT 1 - SQL (0.006616) PRAGMA table_info(subscribers) - SQL (0.002865) PRAGMA table_info(keyboards) - Topic Load (0.004479) SELECT * FROM topics WHERE (topics.id = 1) LIMIT 1 - Topic Update (0.002569) UPDATE topics SET "bonus_time" = '2000-01-01 14:28:00', "approved" = 'f', "written_on" = '2003-07-16 15:28:00', "author_email_address" = 'david@loudthinking.com', "content" = 'Have a nice day', "replies_count" = 2, "title" = 'The First Topic', "author_name" = 'David', "parent_id" = NULL, "last_read" = '2004-04-15', "type" = NULL WHERE id = 1 - Topic Update (0.000962) UPDATE topics SET "bonus_time" = '2000-01-01 14:28:00', "approved" = 'f', "written_on" = '2003-07-16 15:28:00', "author_email_address" = 'david@loudthinking.com', "content" = 'Have a nice day', "replies_count" = 1, "title" = 'The First Topic', "author_name" = 'David', "parent_id" = NULL, "last_read" = '2004-04-15', "type" = NULL WHERE id = 1 - Reply Load (0.000735) SELECT * FROM topics WHERE (topics.parent_id = 1) AND ( (topics."type" = 'Reply' OR topics."type" = 'SillyReply' ) )  - Topic Load (0.002504) SELECT * FROM topics WHERE (topics.id = 1) LIMIT 1 - Topic Update (0.000755) UPDATE topics SET "bonus_time" = '2000-01-01 14:28:00', "approved" = 'f', "written_on" = '2003-07-16 15:28:00', "author_email_address" = 'david@loudthinking.com', "content" = 'Have a nice day', "replies_count" = -1, "title" = 'The First Topic', "author_name" = 'David', "parent_id" = NULL, "last_read" = '2004-04-15', "type" = NULL WHERE id = 1 - Reply Load (0.000948) SELECT * FROM topics WHERE (topics.parent_id = 1) AND ( (topics."type" = 'Reply' OR topics."type" = 'SillyReply' ) )  - Topic Load (0.002257) SELECT * FROM topics WHERE (topics.id = 1) LIMIT 1 - Topic Update (0.010406) UPDATE topics SET replies_count = replies_count - 1 WHERE (id = 2)  - Topic Load (0.002498) SELECT * FROM topics WHERE (topics.id = 2) LIMIT 1 - Topic Update (0.001241) UPDATE topics SET replies_count = replies_count - 1 WHERE (id = 2)  - Topic Load (0.002399) SELECT * FROM topics WHERE (topics.id = 1) LIMIT 1 - SQL (0.003381) INSERT INTO topics ("author_name", "title", "type", "approved", "bonus_time", "replies_count", "author_email_address", "content", "written_on", "last_read", "parent_id") VALUES(NULL, NULL, NULL, 't', NULL, 0, NULL, NULL, '2006-02-22 09:02:49', NULL, NULL) - Topic Load (0.001056) SELECT * FROM topics WHERE (topics.id = 0) LIMIT 1 - SQL (0.002852) INSERT INTO topics ("author_name", "title", "type", "approved", "bonus_time", "replies_count", "author_email_address", "content", "written_on", "last_read", "parent_id") VALUES(NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, '2006-02-22 09:02:49', NULL, NULL) - Topic Load (0.000600) SELECT * FROM topics WHERE (topics.id = 0) LIMIT 1 - Topic Delete all (0.040234) DELETE FROM topics WHERE 1=1 - Topic Delete all (0.003659) DELETE FROM topics WHERE (id IN (1,2))  - Topic Count (0.001563) SELECT COUNT(*) FROM topics  - SQL (0.003603) INSERT INTO topics ("author_name", "title", "type", "approved", "bonus_time", "replies_count", "author_email_address", "content", "written_on", "last_read", "parent_id") VALUES(NULL, 'Yet Another New Topic', NULL, 't', NULL, 0, NULL, NULL, '2003-12-12 23:23:00', NULL, NULL) - Reply Load (0.003346) SELECT * FROM topics WHERE (topics.parent_id = 0) AND ( (topics."type" = 'Reply' OR topics."type" = 'SillyReply' ) )  - Topic Delete all (0.000497) DELETE FROM topics WHERE (parent_id = 0)  - Topic Destroy (0.000409)  DELETE FROM topics - WHERE id = 0 - - Topic Load (0.001023) SELECT * FROM topics WHERE (topics.id = 0) LIMIT 1 - Topic Count (0.003070) SELECT COUNT(*) FROM topics  - Topic Load (0.002273) SELECT * FROM topics WHERE (author_name = 'Mary')  - Reply Load (0.001030) SELECT * FROM topics WHERE (topics.parent_id = 2) AND ( (topics."type" = 'Reply' OR topics."type" = 'SillyReply' ) )  - Topic Delete all (0.001630) DELETE FROM topics WHERE (parent_id = 2)  - Topic Destroy (0.000750)  DELETE FROM topics - WHERE id = 2 - - Topic Count (0.001248) SELECT COUNT(*) FROM topics  - Client Count (0.003684) SELECT COUNT(*) FROM companies WHERE ( (companies."type" = 'Client' OR companies."type" = 'SpecialClient' OR companies."type" = 'VerySpecialClient' ) )  - Client Load (0.007093) SELECT * FROM companies WHERE (companies.id = 2) AND ( (companies."type" = 'Client' OR companies."type" = 'SpecialClient' OR companies."type" = 'VerySpecialClient' ) ) LIMIT 1 - Firm Load (0.000661) SELECT * FROM companies WHERE (companies.id = 2) AND ( (companies."type" = 'Firm' ) ) LIMIT 1 - Client Destroy (0.001917)  DELETE FROM companies - WHERE id = 2 - - Client Load (0.001796) SELECT * FROM companies WHERE (companies.id = 3) AND ( (companies."type" = 'Client' OR companies."type" = 'SpecialClient' OR companies."type" = 'VerySpecialClient' ) ) LIMIT 1 - Firm Load (0.002688) SELECT * FROM companies WHERE (companies.id = 1) AND ( (companies."type" = 'Firm' ) ) LIMIT 1 - Client Destroy (0.000853)  DELETE FROM companies - WHERE id = 3 - - Client Count (0.001605) SELECT COUNT(*) FROM companies WHERE ( (companies."type" = 'Client' OR companies."type" = 'SpecialClient' OR companies."type" = 'VerySpecialClient' ) )  - Client Load (0.005973) SELECT * FROM companies WHERE (companies.id = 3) AND ( (companies."type" = 'Client' OR companies."type" = 'SpecialClient' OR companies."type" = 'VerySpecialClient' ) ) LIMIT 1 - Firm Load (0.002549) SELECT * FROM companies WHERE (companies.id = 1) AND ( (companies."type" = 'Firm' ) ) LIMIT 1 - Client Destroy (0.001864)  DELETE FROM companies - WHERE id = 3 - - SQL (0.003713) INSERT INTO topics ("author_name", "title", "type", "approved", "bonus_time", "replies_count", "author_email_address", "content", "written_on", "last_read", "parent_id") VALUES(NULL, 'Yet Another Title', NULL, 't', NULL, 0, NULL, NULL, '2006-02-22 09:02:49', NULL, NULL) - Reply Load (0.001058) SELECT * FROM topics WHERE (topics.parent_id = 0) AND ( (topics."type" = 'Reply' OR topics."type" = 'SillyReply' ) )  - Topic Delete all (0.000551) DELETE FROM topics WHERE (parent_id = 0)  - Topic Destroy (0.000773)  DELETE FROM topics - WHERE id = 0 - - Topic Load (0.008984) SELECT * FROM topics WHERE (topics.id = 1) LIMIT 1 - Topic Load (0.002726) SELECT * FROM topics WHERE (topics.id = 2) LIMIT 1 - Topic Load (0.002896) SELECT * FROM topics WHERE (topics.id = 1) LIMIT 1 - SQL (0.003320) INSERT INTO topics ("author_name", "title", "type", "approved", "bonus_time", "replies_count", "author_email_address", "content", "written_on", "last_read", "parent_id") VALUES(NULL, NULL, NULL, 't', NULL, 0, NULL, '--- -two: 2 -one: 1', '2006-02-22 09:02:49', NULL, NULL) - Topic Load (0.000604) SELECT * FROM topics WHERE (topics.id = 0) LIMIT 1 - Topic Load (0.009243) SELECT * FROM topics WHERE (topics.id = 1) LIMIT 1 - Topic Load (0.002759) SELECT * FROM topics WHERE (topics.id = 2) LIMIT 1 - Topic Load (0.005795) SELECT * FROM topics WHERE (topics.id = 1) LIMIT 1 - Topic Load (0.002667) SELECT * FROM topics WHERE (topics.id = 1) LIMIT 1 - Topic Load (0.008666) SELECT * FROM topics WHERE (topics.id = 1) LIMIT 1 - Topic Update (0.002875) UPDATE topics SET "bonus_time" = '2000-01-01 14:28:00', "approved" = 'f', "written_on" = '2003-07-16 15:28:00', "author_email_address" = 'david@loudthinking.com', "content" = 'Have a nice day', "replies_count" = 1, "title" = 'The First Topic', "author_name" = 'David', "parent_id" = NULL, "last_read" = '2004-04-15', "type" = NULL WHERE id = 1 - Topic Load (0.003552) SELECT * FROM topics WHERE (topics.id = 1) LIMIT 1 - Topic Update (0.001403) UPDATE topics SET "bonus_time" = '2000-01-01 14:28:00', "approved" = 'f', "written_on" = '2003-07-16 15:28:00', "author_email_address" = 'david@loudthinking.com', "content" = 'Have a nice day', "replies_count" = 3, "title" = 'The First Topic', "author_name" = 'David', "parent_id" = NULL, "last_read" = '2004-04-15', "type" = NULL WHERE id = 1 - Reply Load (0.000694) SELECT * FROM topics WHERE (topics.parent_id = 1) AND ( (topics."type" = 'Reply' OR topics."type" = 'SillyReply' ) )  - Topic Load (0.002520) SELECT * FROM topics WHERE (topics.id = 1) LIMIT 1 - Topic Update (0.009274) UPDATE topics SET replies_count = replies_count + 1 WHERE (id = 1)  - Topic Load (0.002998) SELECT * FROM topics WHERE (topics.id = 1) LIMIT 1 - Topic Update (0.000938) UPDATE topics SET replies_count = replies_count + 1 WHERE (id = 1)  - Topic Load (0.002618) SELECT * FROM topics WHERE (topics.id = 1) LIMIT 1 - Topic Load (0.009468) SELECT * FROM topics WHERE (topics.id = 1) LIMIT 1 - Topic Update (0.005177) UPDATE topics SET "bonus_time" = '2000-01-01 14:28:00', "approved" = 'f', "written_on" = '2003-07-16 15:28:00', "author_email_address" = 'david@loudthinking.com', "content" = 'Have a nice day', "replies_count" = 0, "title" = 'The First Topic', "author_name" = 'David', "parent_id" = 1, "last_read" = '2004-04-15', "type" = NULL WHERE id = 1 - SQL (0.010030) INSERT INTO auto_id_tests ("value") VALUES(NULL) - AutoId Load (0.000585) SELECT * FROM auto_id_tests WHERE (auto_id_tests.auto_id = 0) LIMIT 1 - SQL (0.006707) PRAGMA table_info(categories) - Topic Load (0.012476) SELECT * FROM topics ORDER BY id  - Topic Load (0.002900) SELECT * FROM topics WHERE (topics.id = 1) LIMIT 1 - Topic Load (0.009610) SELECT * FROM topics WHERE (author_name = 'Mary')  - Topic Load (0.002122) SELECT * FROM topics WHERE (topics.id = 2) LIMIT 1 - SQL (0.006091) INSERT INTO topics ("author_name", "title", "type", "approved", "bonus_time", "replies_count", "author_email_address", "content", "written_on", "last_read", "parent_id") VALUES(NULL, 'hello', 'Reply', 't', NULL, 0, NULL, 'world', '2006-02-22 09:02:50', NULL, NULL) - Reply Update (0.002221) UPDATE topics SET "bonus_time" = NULL, "approved" = 'f', "written_on" = '2006-02-22 09:02:50', "author_email_address" = NULL, "content" = 'world', "replies_count" = 0, "title" = 'hello', "author_name" = NULL, "parent_id" = NULL, "last_read" = NULL, "type" = 'Reply' WHERE id = 0 - Topic Load (0.004532) SELECT * FROM topics WHERE (topics.id = 1) LIMIT 1 - Topic Load (0.011355) SELECT * FROM topics WHERE (topics.id = 1) LIMIT 1 - Topic Load (0.003861) SELECT * FROM topics WHERE (topics.id = 1) LIMIT 1 - Topic Load (0.004536) SELECT * FROM topics WHERE (topics.id = 1) LIMIT 1 - Topic Load (0.009412) SELECT * FROM topics WHERE (topics.id = 1) LIMIT 1 - SQL (0.012033) PRAGMA table_info(tasks) - Topic Load (0.003992) SELECT * FROM topics WHERE (topics.id = 1) LIMIT 1 - SQL (0.002058) INSERT INTO topics ("author_name", "title", "type", "approved", "bonus_time", "replies_count", "author_email_address", "content", "written_on", "last_read", "parent_id") VALUES(NULL, 'Hey you', NULL, 't', NULL, 0, NULL, NULL, '2006-02-22 09:02:50', NULL, NULL) - Topic Load (0.013915) SELECT * FROM topics WHERE (topics.id = 1) LIMIT 1 - Topic Load (0.004504) SELECT * FROM topics WHERE (topics.id = 1) LIMIT 1 - Topic Load (0.002590) SELECT * FROM topics WHERE (topics.id = 1) LIMIT 1 - SQL (0.003083) INSERT INTO topics ("author_name", "title", "type", "approved", "bonus_time", "replies_count", "author_email_address", "content", "written_on", "last_read", "parent_id") VALUES('\  '' - \n "', NULL, NULL, 't', NULL, 0, NULL, NULL, '2006-02-22 09:02:50', NULL, NULL) - Topic Load (0.000578) SELECT * FROM topics WHERE (topics.id = 0) LIMIT 1 - Topic Load (0.006271) SELECT * FROM topics WHERE (topics.id = 1) LIMIT 1 - Topic Load (0.012460) SELECT * FROM topics WHERE (topics.id = 1) LIMIT 1 - Topic Load (0.005476) SELECT * FROM topics LIMIT 1 -Exception occured during reader method compilation. -Maybe mumub-jumbo is not a valid Ruby identifier? -(eval):1:in `class_eval': compile error -(eval):1: syntax error -def mumub-jumbo; raise NoMethodError, 'missing attribute: mumub-jumbo', caller unless @attributes.has_key?('mumub-jumbo'); @attributes['mumub-jumbo']; end - ^ -(eval):1: syntax error -def mumub-jumbo; raise NoMethodError, 'missing attribute: mumub-jumbo', caller unless @attributes.has_key?('mumub-jumbo'); @attributes['mumub-jumbo']; end - ^ - Topic Load (0.010857) SELECT * FROM topics LIMIT 1 - Firm Load (0.002415) SELECT * FROM companies WHERE ( (companies."type" = 'Firm' ) ) LIMIT 1 - Client Load (0.001866) SELECT * FROM companies WHERE ( (companies."type" = 'Client' OR companies."type" = 'SpecialClient' OR companies."type" = 'VerySpecialClient' ) ) LIMIT 1 - Topic Load (0.002584) SELECT * FROM topics WHERE (topics.id = 99999) LIMIT 1 - Topic Load (0.011069) SELECT * FROM topics WHERE (topics.id = 1) LIMIT 1 - Topic Load (0.002149) SELECT * FROM topics WHERE (topics.id = 1) LIMIT 1 - Topic Update (0.003213) UPDATE topics SET "bonus_time" = '2000-01-01 14:28:00', "approved" = 'f', "written_on" = '2003-07-16 15:28:00', "author_email_address" = 'david@loudthinking.com', "content" = 'Have a nice day', "replies_count" = 0, "title" = 'something else', "author_name" = 'David', "parent_id" = NULL, "last_read" = '2004-04-15', "type" = NULL WHERE id = 1 - Topic Load (0.002511) SELECT * FROM topics WHERE (topics.id = 1) LIMIT 1 - Topic Load (0.004236) SELECT * FROM topics WHERE (topics.id = 1) LIMIT 1 - Developer Load (0.003825) SELECT * FROM developers WHERE (salary > 90000) AND (id < 5)  - Developer Load (0.001538) SELECT * FROM developers WHERE (developers.id = 1) LIMIT 1 - SQL (0.003689) PRAGMA table_info(developers) - Developer Load (0.012198) SELECT * FROM developers ORDER BY id LIMIT 3 OFFSET 2 - Developer Load (0.001852) SELECT * FROM developers WHERE (developers.id = 1) LIMIT 1 - Developer Load (0.003312) SELECT * FROM developers WHERE (developers.id = 1) LIMIT 1 - Developer Load (0.005539) SELECT * FROM developers ORDER BY id  - SQL (0.003824) INSERT INTO topics ("author_name", "title", "type", "approved", "bonus_time", "replies_count", "author_email_address", "content", "written_on", "last_read", "parent_id") VALUES(NULL, NULL, NULL, 't', NULL, 0, NULL, '--- !ruby/struct:BasicsTest::MyObject -attribute1: value1 -attribute2: value2', '2006-02-22 09:02:50', NULL, NULL) - SQL (0.003664) INSERT INTO topics ("author_name", "title", "type", "approved", "bonus_time", "replies_count", "author_email_address", "content", "written_on", "last_read", "parent_id") VALUES(NULL, NULL, NULL, 't', NULL, 0, NULL, '--- !ruby/struct:BasicsTest::MyObject -attribute1: value1 -attribute2: value2', '2006-02-22 09:02:50', NULL, NULL) - Topic Load (0.000653) SELECT * FROM topics WHERE (topics.id = 0) LIMIT 1 - Topic Load (0.004584) SELECT * FROM topics WHERE (topics.id = 1) LIMIT 1 - SQL (0.011570) SELECT name FROM sqlite_master WHERE type = 'table' - SQL (0.013690) SELECT name FROM sqlite_master WHERE type = 'table' - Topic Load (0.004343) SELECT * FROM topics WHERE (topics.id = 1) LIMIT 1 - SQL (0.003293) INSERT INTO topics ("author_name", "title", "type", "approved", "bonus_time", "replies_count", "author_email_address", "content", "written_on", "last_read", "parent_id") VALUES(NULL, 'Another New Topic', NULL, 't', NULL, 0, NULL, NULL, '2003-12-12 23:23:00', NULL, NULL) - Topic Load (0.000615) SELECT * FROM topics WHERE (topics.id = 0) LIMIT 1 - Topic Update (0.004120) UPDATE topics SET content = 'bulk updated!'  - Topic Load (0.002553) SELECT * FROM topics WHERE (topics.id = 1) LIMIT 1 - Topic Load (0.004413) SELECT * FROM topics WHERE (topics.id = 1) LIMIT 1 - Topic Load (0.002548) SELECT * FROM topics WHERE (topics.id = 1) LIMIT 1 - Topic Update (0.004526) UPDATE topics SET content = 'bulk updated!' WHERE (approved = 't')  - Topic Load (0.002641) SELECT * FROM topics WHERE (topics.id = 1) LIMIT 1 - SQL (0.003577) INSERT INTO topics ("author_name", "title", "type", "approved", "bonus_time", "replies_count", "author_email_address", "content", "written_on", "last_read", "parent_id") VALUES(NULL, 'Still another topic', NULL, 't', NULL, 0, NULL, NULL, '2006-02-22 09:02:51', NULL, NULL) - Topic Load (0.000582) SELECT * FROM topics WHERE (topics.id = 0) LIMIT 1 - Topic Load (0.004113) SELECT * FROM topics WHERE (topics.id = 1) LIMIT 1 - Topic Load (0.011675) SELECT * FROM topics WHERE (topics.id = 1) LIMIT 1 diff --git a/tracks/vendor/rails/activerecord/test/default_test_firebird.rb b/tracks/vendor/rails/activerecord/test/default_test_firebird.rb deleted file mode 100644 index 4f3d14ce..00000000 --- a/tracks/vendor/rails/activerecord/test/default_test_firebird.rb +++ /dev/null @@ -1,16 +0,0 @@ -require 'abstract_unit' -require 'fixtures/default' - -class DefaultTest < Test::Unit::TestCase - def test_default_timestamp - default = Default.new - assert_instance_of(Time, default.default_timestamp) - assert_equal(:datetime, default.column_for_attribute(:default_timestamp).type) - - # Variance should be small; increase if required -- e.g., if test db is on - # remote host and clocks aren't synchronized. - t1 = Time.new - accepted_variance = 1.0 - assert_in_delta(t1.to_f, default.default_timestamp.to_f, accepted_variance) - end -end diff --git a/tracks/vendor/rails/activerecord/test/deprecated_associations_test.rb b/tracks/vendor/rails/activerecord/test/deprecated_associations_test.rb deleted file mode 100644 index 5772ab13..00000000 --- a/tracks/vendor/rails/activerecord/test/deprecated_associations_test.rb +++ /dev/null @@ -1,352 +0,0 @@ -require 'abstract_unit' -require 'fixtures/developer' -require 'fixtures/project' -require 'fixtures/company' -require 'fixtures/topic' -require 'fixtures/reply' - -# Can't declare new classes in test case methods, so tests before that -bad_collection_keys = false -begin - class Car < ActiveRecord::Base; has_many :wheels, :name => "wheels"; end -rescue ArgumentError - bad_collection_keys = true -end -raise "ActiveRecord should have barked on bad collection keys" unless bad_collection_keys - - -class DeprecatedAssociationsTest < Test::Unit::TestCase - fixtures :accounts, :companies, :developers, :projects, :topics, - :developers_projects - - def test_has_many_find - assert_equal 2, Firm.find_first.clients.length - end - - def test_has_many_orders - assert_equal "Summit", Firm.find_first.clients.first.name - end - - def test_has_many_class_name - assert_equal "Microsoft", Firm.find_first.clients_sorted_desc.first.name - end - - def test_has_many_foreign_key - assert_equal "Microsoft", Firm.find_first.clients_of_firm.first.name - end - - def test_has_many_conditions - assert_equal "Microsoft", Firm.find_first.clients_like_ms.first.name - end - - def test_has_many_sql - firm = Firm.find_first - assert_equal "Microsoft", firm.clients_using_sql.first.name - assert_equal 1, firm.clients_using_sql_count - assert_equal 1, Firm.find_first.clients_using_sql_count - end - - def test_has_many_counter_sql - assert_equal 1, Firm.find_first.clients_using_counter_sql_count - end - - def test_has_many_queries - assert Firm.find_first.has_clients? - firm = Firm.find_first - assert_equal 2, firm.clients_count # tests using class count - firm.clients - assert firm.has_clients? - assert_equal 2, firm.clients_count # tests using collection length - end - - def test_has_many_dependence - assert_equal 3, Client.find_all.length - Firm.find_first.destroy - assert_equal 1, Client.find_all.length - end - - uses_transaction :test_has_many_dependence_with_transaction_support_on_failure - def test_has_many_dependence_with_transaction_support_on_failure - assert_equal 3, Client.find_all.length - - firm = Firm.find_first - clients = firm.clients - clients.last.instance_eval { def before_destroy() raise "Trigger rollback" end } - - firm.destroy rescue "do nothing" - - assert_equal 3, Client.find_all.length - end - - def test_has_one_dependence - num_accounts = Account.count - firm = Firm.find(1) - assert firm.has_account? - firm.destroy - assert_equal num_accounts - 1, Account.count - end - - def test_has_one_dependence_with_missing_association - Account.destroy_all - firm = Firm.find(1) - assert !firm.has_account? - firm.destroy - end - - def test_belongs_to - assert_equal companies(:first_firm).name, Client.find(3).firm.name - assert Client.find(3).has_firm?, "Microsoft should have a firm" - # assert !Company.find(1).has_firm?, "37signals shouldn't have a firm" - end - - def test_belongs_to_with_different_class_name - assert_equal Company.find(1).name, Company.find(3).firm_with_other_name.name - assert Company.find(3).has_firm_with_other_name?, "Microsoft should have a firm" - end - - def test_belongs_to_with_condition - assert_equal Company.find(1).name, Company.find(3).firm_with_condition.name - assert Company.find(3).has_firm_with_condition?, "Microsoft should have a firm" - end - - def test_belongs_to_equality - assert Company.find(3).firm?(Company.find(1)), "Microsoft should have 37signals as firm" - assert_raises(RuntimeError) { !Company.find(3).firm?(Company.find(3)) } # "Summit shouldn't have itself as firm" - end - - def test_has_one - assert companies(:first_firm).account?(Account.find(1)) - assert_equal Account.find(1).credit_limit, companies(:first_firm).account.credit_limit - assert companies(:first_firm).has_account?, "37signals should have an account" - assert Account.find(1).firm?(companies(:first_firm)), "37signals account should be able to backtrack" - assert Account.find(1).has_firm?, "37signals account should be able to backtrack" - - assert !Account.find(2).has_firm?, "Unknown isn't linked" - assert !Account.find(2).firm?(companies(:first_firm)), "Unknown isn't linked" - end - - def test_has_many_dependence_on_account - num_accounts = Account.count - companies(:first_firm).destroy - assert_equal num_accounts - 1, Account.count - end - - def test_find_in - assert_equal Client.find(2).name, companies(:first_firm).find_in_clients(2).name - assert_raises(ActiveRecord::RecordNotFound) { companies(:first_firm).find_in_clients(6) } - end - - def test_force_reload - firm = Firm.new("name" => "A New Firm, Inc") - firm.save - firm.clients.each {|c|} # forcing to load all clients - assert firm.clients.empty?, "New firm shouldn't have client objects" - assert !firm.has_clients?, "New firm shouldn't have clients" - assert_equal 0, firm.clients_count, "New firm should have 0 clients" - - client = Client.new("name" => "TheClient.com", "firm_id" => firm.id) - client.save - - assert firm.clients.empty?, "New firm should have cached no client objects" - assert !firm.has_clients?, "New firm should have cached a no-clients response" - assert_equal 0, firm.clients_count, "New firm should have cached 0 clients count" - - assert !firm.clients(true).empty?, "New firm should have reloaded client objects" - assert firm.has_clients?(true), "New firm should have reloaded with a have-clients response" - assert_equal 1, firm.clients_count(true), "New firm should have reloaded clients count" - end - - def test_included_in_collection - assert companies(:first_firm).clients.include?(Client.find(2)) - end - - def test_build_to_collection - assert_equal 1, companies(:first_firm).clients_of_firm_count - new_client = companies(:first_firm).build_to_clients_of_firm("name" => "Another Client") - assert_equal "Another Client", new_client.name - assert new_client.save - - assert new_client.firm?(companies(:first_firm)) - assert_equal 2, companies(:first_firm).clients_of_firm_count(true) - end - - def test_create_in_collection - assert_equal companies(:first_firm).create_in_clients_of_firm("name" => "Another Client"), companies(:first_firm).clients_of_firm(true).last - end - - def test_has_and_belongs_to_many - david = Developer.find(1) - assert david.has_projects? - assert_equal 2, david.projects_count - - active_record = Project.find(1) - assert active_record.has_developers? - assert_equal 2, active_record.developers_count - assert active_record.developers.include?(david) - end - - def test_has_and_belongs_to_many_removing - david = Developer.find(1) - active_record = Project.find(1) - - david.remove_projects(active_record) - - assert_equal 1, david.projects_count - assert_equal 1, active_record.developers_count - end - - def test_has_and_belongs_to_many_zero - david = Developer.find(1) - david.remove_projects(Project.find_all) - - assert_equal 0, david.projects_count - assert !david.has_projects? - end - - def test_has_and_belongs_to_many_adding - jamis = Developer.find(2) - action_controller = Project.find(2) - - jamis.add_projects(action_controller) - - assert_equal 2, jamis.projects_count - assert_equal 2, action_controller.developers_count - end - - def test_has_and_belongs_to_many_adding_from_the_project - jamis = Developer.find(2) - action_controller = Project.find(2) - - action_controller.add_developers(jamis) - - assert_equal 2, jamis.projects_count - assert_equal 2, action_controller.developers_count - end - - def test_has_and_belongs_to_many_adding_a_collection - aredridel = Developer.new("name" => "Aredridel") - aredridel.save - - aredridel.add_projects([ Project.find(1), Project.find(2) ]) - assert_equal 2, aredridel.projects_count - end - - def test_belongs_to_counter - topic = Topic.create("title" => "Apple", "content" => "hello world") - assert_equal 0, topic.send(:read_attribute, "replies_count"), "No replies yet" - - reply = topic.create_in_replies("title" => "I'm saying no!", "content" => "over here") - assert_equal 1, Topic.find(topic.id).send(:read_attribute, "replies_count"), "First reply created" - - reply.destroy - assert_equal 0, Topic.find(topic.id).send(:read_attribute, "replies_count"), "First reply deleted" - end - - def test_natural_assignment_of_has_one - apple = Firm.create("name" => "Apple") - citibank = Account.create("credit_limit" => 10) - apple.account = citibank - assert_equal apple.id, citibank.firm_id - end - - def test_natural_assignment_of_belongs_to - apple = Firm.create("name" => "Apple") - citibank = Account.create("credit_limit" => 10) - citibank.firm = apple - assert_equal apple.id, citibank.firm_id - end - - def test_natural_assignment_of_has_many - apple = Firm.create("name" => "Apple") - natural = Client.create("name" => "Natural Company") - apple.clients << natural - assert_equal apple.id, natural.firm_id - assert_equal Client.find(natural.id), Firm.find(apple.id).clients.find(natural.id) - apple.clients.delete natural - assert_raises(ActiveRecord::RecordNotFound) { - Firm.find(apple.id).clients.find(natural.id) - } - end - - def test_natural_adding_of_has_and_belongs_to_many - rails = Project.create("name" => "Rails") - ap = Project.create("name" => "Action Pack") - john = Developer.create("name" => "John") - mike = Developer.create("name" => "Mike") - rails.developers << john - rails.developers << mike - - assert_equal Developer.find(john.id), Project.find(rails.id).developers.find(john.id) - assert_equal Developer.find(mike.id), Project.find(rails.id).developers.find(mike.id) - assert_equal Project.find(rails.id), Developer.find(mike.id).projects.find(rails.id) - assert_equal Project.find(rails.id), Developer.find(john.id).projects.find(rails.id) - ap.developers << john - assert_equal Developer.find(john.id), Project.find(ap.id).developers.find(john.id) - assert_equal Project.find(ap.id), Developer.find(john.id).projects.find(ap.id) - - ap.developers.delete john - assert_raises(ActiveRecord::RecordNotFound) { - Project.find(ap.id).developers.find(john.id) - } - assert_raises(ActiveRecord::RecordNotFound) { - Developer.find(john.id).projects.find(ap.id) - } - end - - def test_storing_in_pstore - require "pstore" - require "tmpdir" - apple = Firm.create("name" => "Apple") - natural = Client.new("name" => "Natural Company") - apple.clients << natural - - db = PStore.new(File.join(Dir.tmpdir, "ar-pstore-association-test")) - db.transaction do - db["apple"] = apple - end - - db = PStore.new(File.join(Dir.tmpdir, "ar-pstore-association-test")) - db.transaction do - assert_equal "Natural Company", db["apple"].clients.first.name - end - end - - def test_has_many_find_all - assert_equal 2, Firm.find_first.find_all_in_clients("#{QUOTED_TYPE} = 'Client'").length - assert_equal 1, Firm.find_first.find_all_in_clients("name = 'Summit'").length - end - - def test_has_one - assert companies(:first_firm).account?(Account.find(1)) - assert companies(:first_firm).has_account?, "37signals should have an account" - assert Account.find(1).firm?(companies(:first_firm)), "37signals account should be able to backtrack" - assert Account.find(1).has_firm?, "37signals account should be able to backtrack" - - assert !Account.find(2).has_firm?, "Unknown isn't linked" - assert !Account.find(2).firm?(companies(:first_firm)), "Unknown isn't linked" - end - - def test_has_one_build - firm = Firm.new("name" => "GlobalMegaCorp") - assert firm.save - - account = firm.build_account("credit_limit" => 1000) - assert account.save - assert_equal account, firm.account - end - - def test_has_one_failing_build_association - firm = Firm.new("name" => "GlobalMegaCorp") - firm.save - - account = firm.build_account - assert !account.save - assert_equal "can't be empty", account.errors.on("credit_limit") - end - - def test_has_one_create - firm = Firm.new("name" => "GlobalMegaCorp") - firm.save - assert_equal firm.create_account("credit_limit" => 1000), firm.account - end -end diff --git a/tracks/vendor/rails/activerecord/test/deprecated_finder_test.rb b/tracks/vendor/rails/activerecord/test/deprecated_finder_test.rb deleted file mode 100644 index 1409e0d1..00000000 --- a/tracks/vendor/rails/activerecord/test/deprecated_finder_test.rb +++ /dev/null @@ -1,140 +0,0 @@ -require 'abstract_unit' -require 'fixtures/company' -require 'fixtures/topic' -require 'fixtures/entrant' -require 'fixtures/developer' - -class DeprecatedFinderTest < Test::Unit::TestCase - fixtures :companies, :topics, :entrants, :developers - - def test_find_all_with_limit - entrants = Entrant.find_all nil, "id ASC", 2 - - assert_equal(2, entrants.size) - assert_equal(entrants(:first).name, entrants.first.name) - end - - def test_find_all_with_prepared_limit_and_offset - entrants = Entrant.find_all nil, "id ASC", [2, 1] - - assert_equal(2, entrants.size) - assert_equal(entrants(:second).name, entrants.first.name) - end - - def test_find_first - first = Topic.find_first "title = 'The First Topic'" - assert_equal(topics(:first).title, first.title) - end - - def test_find_first_failing - first = Topic.find_first "title = 'The First Topic!'" - assert_nil(first) - end - - def test_deprecated_find_on_conditions - assert Topic.find_on_conditions(1, ["approved = ?", false]) - assert_raises(ActiveRecord::RecordNotFound) { Topic.find_on_conditions(1, ["approved = ?", true]) } - end - - def test_condition_interpolation - assert_kind_of Firm, Company.find_first(["name = '%s'", "37signals"]) - assert_nil Company.find_first(["name = '%s'", "37signals!"]) - assert_nil Company.find_first(["name = '%s'", "37signals!' OR 1=1"]) - assert_kind_of Time, Topic.find_first(["id = %d", 1]).written_on - end - - def test_bind_variables - assert_kind_of Firm, Company.find_first(["name = ?", "37signals"]) - assert_nil Company.find_first(["name = ?", "37signals!"]) - assert_nil Company.find_first(["name = ?", "37signals!' OR 1=1"]) - assert_kind_of Time, Topic.find_first(["id = ?", 1]).written_on - assert_raises(ActiveRecord::PreparedStatementInvalid) { - Company.find_first(["id=? AND name = ?", 2]) - } - assert_raises(ActiveRecord::PreparedStatementInvalid) { - Company.find_first(["id=?", 2, 3, 4]) - } - end - - def test_bind_variables_with_quotes - Company.create("name" => "37signals' go'es agains") - assert Company.find_first(["name = ?", "37signals' go'es agains"]) - end - - def test_named_bind_variables_with_quotes - Company.create("name" => "37signals' go'es agains") - assert Company.find_first(["name = :name", {:name => "37signals' go'es agains"}]) - end - - def test_named_bind_variables - assert_equal '1', bind(':a', :a => 1) # ' ruby-mode - assert_equal '1 1', bind(':a :a', :a => 1) # ' ruby-mode - - assert_kind_of Firm, Company.find_first(["name = :name", { :name => "37signals" }]) - assert_nil Company.find_first(["name = :name", { :name => "37signals!" }]) - assert_nil Company.find_first(["name = :name", { :name => "37signals!' OR 1=1" }]) - assert_kind_of Time, Topic.find_first(["id = :id", { :id => 1 }]).written_on - assert_raises(ActiveRecord::PreparedStatementInvalid) { - Company.find_first(["id=:id and name=:name", { :id=>3 }]) - } - assert_raises(ActiveRecord::PreparedStatementInvalid) { - Company.find_first(["id=:id", { :id=>3, :name=>"37signals!" }]) - } - end - - def test_count - assert_equal(0, Entrant.count("id > 3")) - assert_equal(1, Entrant.count(["id > ?", 2])) - assert_equal(2, Entrant.count(["id > ?", 1])) - end - - def test_count_by_sql - assert_equal(0, Entrant.count_by_sql("SELECT COUNT(*) FROM entrants WHERE id > 3")) - assert_equal(1, Entrant.count_by_sql(["SELECT COUNT(*) FROM entrants WHERE id > ?", 2])) - assert_equal(2, Entrant.count_by_sql(["SELECT COUNT(*) FROM entrants WHERE id > ?", 1])) - end - - def test_find_all_with_limit - first_five_developers = Developer.find_all nil, 'id ASC', 5 - assert_equal 5, first_five_developers.length - assert_equal 'David', first_five_developers.first.name - assert_equal 'fixture_5', first_five_developers.last.name - - no_developers = Developer.find_all nil, 'id ASC', 0 - assert_equal 0, no_developers.length - - assert_equal first_five_developers, Developer.find_all(nil, 'id ASC', [5]) - assert_equal no_developers, Developer.find_all(nil, 'id ASC', [0]) - end - - def test_find_all_with_limit_and_offset - first_three_developers = Developer.find_all nil, 'id ASC', [3, 0] - second_three_developers = Developer.find_all nil, 'id ASC', [3, 3] - last_two_developers = Developer.find_all nil, 'id ASC', [2, 8] - - assert_equal 3, first_three_developers.length - assert_equal 3, second_three_developers.length - assert_equal 2, last_two_developers.length - - assert_equal 'David', first_three_developers.first.name - assert_equal 'fixture_4', second_three_developers.first.name - assert_equal 'fixture_9', last_two_developers.first.name - end - - def test_find_all_by_one_attribute_with_options - topics = Topic.find_all_by_content("Have a nice day", "id DESC") - assert topics(:first), topics.last - - topics = Topic.find_all_by_content("Have a nice day", "id DESC") - assert topics(:first), topics.first - end - - protected - def bind(statement, *vars) - if vars.first.is_a?(Hash) - ActiveRecord::Base.send(:replace_named_bind_variables, statement, vars.first) - else - ActiveRecord::Base.send(:replace_bind_variables, statement, vars) - end - end -end diff --git a/tracks/vendor/rails/activerecord/test/finder_test.rb b/tracks/vendor/rails/activerecord/test/finder_test.rb deleted file mode 100644 index 7e73eec7..00000000 --- a/tracks/vendor/rails/activerecord/test/finder_test.rb +++ /dev/null @@ -1,378 +0,0 @@ -require 'abstract_unit' -require 'fixtures/company' -require 'fixtures/topic' -require 'fixtures/entrant' -require 'fixtures/developer' -require 'fixtures/post' - -class FinderTest < Test::Unit::TestCase - fixtures :companies, :topics, :entrants, :developers, :developers_projects, :posts - - def test_find - assert_equal(topics(:first).title, Topic.find(1).title) - end - - def test_exists - assert (Topic.exists?(1)) - assert !(Topic.exists?(45)) - assert !(Topic.exists?("foo")) - assert !(Topic.exists?([1,2])) - end - - def test_find_by_array_of_one_id - assert_kind_of(Array, Topic.find([ 1 ])) - assert_equal(1, Topic.find([ 1 ]).length) - end - - def test_find_by_ids - assert_equal(2, Topic.find(1, 2).length) - assert_equal(topics(:second).title, Topic.find([ 2 ]).first.title) - end - - def test_find_an_empty_array - assert_equal [], Topic.find([]) - end - - def test_find_by_ids_missing_one - assert_raises(ActiveRecord::RecordNotFound) { - Topic.find(1, 2, 45) - } - end - - def test_find_all_with_limit - entrants = Entrant.find(:all, :order => "id ASC", :limit => 2) - - assert_equal(2, entrants.size) - assert_equal(entrants(:first).name, entrants.first.name) - end - - def test_find_all_with_prepared_limit_and_offset - entrants = Entrant.find(:all, :order => "id ASC", :limit => 2, :offset => 1) - - assert_equal(2, entrants.size) - assert_equal(entrants(:second).name, entrants.first.name) - - entrants = Entrant.find(:all, :order => "id ASC", :limit => 2, :offset => 2) - assert_equal(1, entrants.size) - assert_equal(entrants(:third).name, entrants.first.name) - end - - def test_find_with_limit_and_condition - developers = Developer.find(:all, :order => "id DESC", :conditions => "salary = 100000", :limit => 3, :offset =>7) - assert_equal(1, developers.size) - assert_equal("fixture_3", developers.first.name) - end - - def test_find_with_entire_select_statement - topics = Topic.find_by_sql "SELECT * FROM topics WHERE author_name = 'Mary'" - - assert_equal(1, topics.size) - assert_equal(topics(:second).title, topics.first.title) - end - - def test_find_with_prepared_select_statement - topics = Topic.find_by_sql ["SELECT * FROM topics WHERE author_name = ?", "Mary"] - - assert_equal(1, topics.size) - assert_equal(topics(:second).title, topics.first.title) - end - - def test_find_first - first = Topic.find(:first, :conditions => "title = 'The First Topic'") - assert_equal(topics(:first).title, first.title) - end - - def test_find_first_failing - first = Topic.find(:first, :conditions => "title = 'The First Topic!'") - assert_nil(first) - end - - def test_unexisting_record_exception_handling - assert_raises(ActiveRecord::RecordNotFound) { - Topic.find(1).parent - } - - Topic.find(2).parent - end - - def test_find_only_some_columns - topic = Topic.find(1, :select => "author_name") - assert_raises(NoMethodError) { topic.title } - assert_equal "David", topic.author_name - assert !topic.attribute_present?("title") - assert !topic.respond_to?("title") - assert topic.attribute_present?("author_name") - assert topic.respond_to?("author_name") - end - - def test_find_on_conditions - assert Topic.find(1, :conditions => ["approved = ?", false]) - assert_raises(ActiveRecord::RecordNotFound) { Topic.find(1, :conditions => ["approved = ?", true]) } - end - - def test_condition_interpolation - assert_kind_of Firm, Company.find(:first, :conditions => ["name = '%s'", "37signals"]) - assert_nil Company.find(:first, :conditions => ["name = '%s'", "37signals!"]) - assert_nil Company.find(:first, :conditions => ["name = '%s'", "37signals!' OR 1=1"]) - assert_kind_of Time, Topic.find(:first, :conditions => ["id = %d", 1]).written_on - end - - def test_bind_variables - assert_kind_of Firm, Company.find(:first, :conditions => ["name = ?", "37signals"]) - assert_nil Company.find(:first, :conditions => ["name = ?", "37signals!"]) - assert_nil Company.find(:first, :conditions => ["name = ?", "37signals!' OR 1=1"]) - assert_kind_of Time, Topic.find(:first, :conditions => ["id = ?", 1]).written_on - assert_raises(ActiveRecord::PreparedStatementInvalid) { - Company.find(:first, :conditions => ["id=? AND name = ?", 2]) - } - assert_raises(ActiveRecord::PreparedStatementInvalid) { - Company.find(:first, :conditions => ["id=?", 2, 3, 4]) - } - end - - def test_bind_variables_with_quotes - Company.create("name" => "37signals' go'es agains") - assert Company.find(:first, :conditions => ["name = ?", "37signals' go'es agains"]) - end - - def test_named_bind_variables_with_quotes - Company.create("name" => "37signals' go'es agains") - assert Company.find(:first, :conditions => ["name = :name", {:name => "37signals' go'es agains"}]) - end - - def test_bind_arity - assert_nothing_raised { bind '' } - assert_raises(ActiveRecord::PreparedStatementInvalid) { bind '', 1 } - - assert_raises(ActiveRecord::PreparedStatementInvalid) { bind '?' } - assert_nothing_raised { bind '?', 1 } - assert_raises(ActiveRecord::PreparedStatementInvalid) { bind '?', 1, 1 } - end - - def test_named_bind_variables - assert_equal '1', bind(':a', :a => 1) # ' ruby-mode - assert_equal '1 1', bind(':a :a', :a => 1) # ' ruby-mode - - assert_kind_of Firm, Company.find(:first, :conditions => ["name = :name", { :name => "37signals" }]) - assert_nil Company.find(:first, :conditions => ["name = :name", { :name => "37signals!" }]) - assert_nil Company.find(:first, :conditions => ["name = :name", { :name => "37signals!' OR 1=1" }]) - assert_kind_of Time, Topic.find(:first, :conditions => ["id = :id", { :id => 1 }]).written_on - assert_raises(ActiveRecord::PreparedStatementInvalid) { - Company.find(:first, :conditions => ["id=:id and name=:name", { :id=>3 }]) - } - assert_raises(ActiveRecord::PreparedStatementInvalid) { - Company.find(:first, :conditions => ["id=:id", { :id=>3, :name=>"37signals!" }]) - } - end - - def test_named_bind_arity - assert_nothing_raised { bind '', {} } - assert_raises(ActiveRecord::PreparedStatementInvalid) { bind '', :a => 1 } - assert_raises(ActiveRecord::PreparedStatementInvalid) { bind ':a', {} } # ' ruby-mode - assert_nothing_raised { bind ':a', :a => 1 } # ' ruby-mode - assert_raises(ActiveRecord::PreparedStatementInvalid) { bind ':a', :a => 1, :b => 2 } # ' ruby-mode - assert_nothing_raised { bind ':a :a', :a => 1 } # ' ruby-mode - assert_raises(ActiveRecord::PreparedStatementInvalid) { bind ':a :a', :a => 1, :b => 2 } # ' ruby-mode - end - - def test_bind_enumerable - assert_equal '1,2,3', bind('?', [1, 2, 3]) - assert_equal %('a','b','c'), bind('?', %w(a b c)) - - assert_equal '1,2,3', bind(':a', :a => [1, 2, 3]) - assert_equal %('a','b','c'), bind(':a', :a => %w(a b c)) # ' - - require 'set' - assert_equal '1,2,3', bind('?', Set.new([1, 2, 3])) - assert_equal %('a','b','c'), bind('?', Set.new(%w(a b c))) - - assert_equal '1,2,3', bind(':a', :a => Set.new([1, 2, 3])) - assert_equal %('a','b','c'), bind(':a', :a => Set.new(%w(a b c))) # ' - end - - def test_bind_string - assert_equal "''", bind('?', '') - end - - def test_string_sanitation - assert_not_equal "'something ' 1=1'", ActiveRecord::Base.sanitize("something ' 1=1") - assert_equal "'something; select table'", ActiveRecord::Base.sanitize("something; select table") - end - - def test_count - assert_equal(0, Entrant.count("id > 3")) - assert_equal(1, Entrant.count(["id > ?", 2])) - assert_equal(2, Entrant.count(["id > ?", 1])) - end - - def test_count_by_sql - assert_equal(0, Entrant.count_by_sql("SELECT COUNT(*) FROM entrants WHERE id > 3")) - assert_equal(1, Entrant.count_by_sql(["SELECT COUNT(*) FROM entrants WHERE id > ?", 2])) - assert_equal(2, Entrant.count_by_sql(["SELECT COUNT(*) FROM entrants WHERE id > ?", 1])) - end - - def test_find_by_one_attribute - assert_equal topics(:first), Topic.find_by_title("The First Topic") - assert_nil Topic.find_by_title("The First Topic!") - end - - def test_find_by_one_missing_attribute - assert_raises(NoMethodError) { Topic.find_by_undertitle("The First Topic!") } - end - - def test_find_by_two_attributes - assert_equal topics(:first), Topic.find_by_title_and_author_name("The First Topic", "David") - assert_nil Topic.find_by_title_and_author_name("The First Topic", "Mary") - end - - def test_find_all_by_one_attribute - topics = Topic.find_all_by_content("Have a nice day") - assert_equal 2, topics.size - assert topics.include?(topics(:first)) - - assert_equal [], Topic.find_all_by_title("The First Topic!!") - end - - def test_find_all_by_one_attribute_with_options - topics = Topic.find_all_by_content("Have a nice day", :order => "id DESC") - assert topics(:first), topics.last - - topics = Topic.find_all_by_content("Have a nice day", :order => "id") - assert topics(:first), topics.first - end - - def test_find_all_by_array_attribute - assert_equal 2, Topic.find_all_by_title(["The First Topic", "The Second Topic's of the day"]).size - end - - def test_find_all_by_boolean_attribute - topics = Topic.find_all_by_approved(false) - assert_equal 1, topics.size - assert topics.include?(topics(:first)) - - topics = Topic.find_all_by_approved(true) - assert_equal 1, topics.size - assert topics.include?(topics(:second)) - end - - def test_find_by_nil_attribute - topic = Topic.find_by_last_read nil - assert_not_nil topic - assert_nil topic.last_read - end - - def test_find_all_by_nil_attribute - topics = Topic.find_all_by_last_read nil - assert_equal 1, topics.size - assert_nil topics[0].last_read - end - - def test_find_by_nil_and_not_nil_attributes - topic = Topic.find_by_last_read_and_author_name nil, "Mary" - assert_equal "Mary", topic.author_name - end - - def test_find_all_by_nil_and_not_nil_attributes - topics = Topic.find_all_by_last_read_and_author_name nil, "Mary" - assert_equal 1, topics.size - assert_equal "Mary", topics[0].author_name - end - - def test_find_or_create_from_one_attribute - number_of_companies = Company.count - sig38 = Company.find_or_create_by_name("38signals") - assert_equal number_of_companies + 1, Company.count - assert_equal sig38, Company.find_or_create_by_name("38signals") - end - - def test_find_or_create_from_two_attributes - number_of_companies = Company.count - sig38 = Company.find_or_create_by_name("38signals") - assert_equal number_of_companies + 1, Company.count - assert_equal sig38, Company.find_or_create_by_name("38signals") - end - - def test_find_with_bad_sql - assert_raises(ActiveRecord::StatementInvalid) { Topic.find_by_sql "select 1 from badtable" } - end - - def test_find_with_invalid_params - assert_raises(ArgumentError) { Topic.find :first, :join => "It should be `joins'" } - assert_raises(ArgumentError) { Topic.find :first, :conditions => '1 = 1', :join => "It should be `joins'" } - end - - def test_find_all_with_limit - first_five_developers = Developer.find :all, :order => 'id ASC', :limit => 5 - assert_equal 5, first_five_developers.length - assert_equal 'David', first_five_developers.first.name - assert_equal 'fixture_5', first_five_developers.last.name - - no_developers = Developer.find :all, :order => 'id ASC', :limit => 0 - assert_equal 0, no_developers.length - end - - def test_find_all_with_limit_and_offset - first_three_developers = Developer.find :all, :order => 'id ASC', :limit => 3, :offset => 0 - second_three_developers = Developer.find :all, :order => 'id ASC', :limit => 3, :offset => 3 - last_two_developers = Developer.find :all, :order => 'id ASC', :limit => 2, :offset => 8 - - assert_equal 3, first_three_developers.length - assert_equal 3, second_three_developers.length - assert_equal 2, last_two_developers.length - - assert_equal 'David', first_three_developers.first.name - assert_equal 'fixture_4', second_three_developers.first.name - assert_equal 'fixture_9', last_two_developers.first.name - end - - def test_find_all_with_limit_and_offset_and_multiple_order_clauses - first_three_posts = Post.find :all, :order => 'author_id, id', :limit => 3, :offset => 0 - second_three_posts = Post.find :all, :order => ' author_id,id ', :limit => 3, :offset => 3 - last_posts = Post.find :all, :order => ' author_id, id ', :limit => 3, :offset => 6 - - assert_equal [[0,3],[1,1],[1,2]], first_three_posts.map { |p| [p.author_id, p.id] } - assert_equal [[1,4],[1,5],[1,6]], second_three_posts.map { |p| [p.author_id, p.id] } - assert_equal [[2,7]], last_posts.map { |p| [p.author_id, p.id] } - end - - def test_find_all_with_join - developers_on_project_one = Developer.find( - :all, - :joins => 'LEFT JOIN developers_projects ON developers.id = developers_projects.developer_id', - :conditions => 'project_id=1' - ) - assert_equal 2, developers_on_project_one.length - developer_names = developers_on_project_one.map { |d| d.name } - assert developer_names.include?('David') - assert developer_names.include?('Jamis') - end - - def test_find_by_id_with_conditions_with_or - assert_nothing_raised do - Post.find([1,2,3], - :conditions => "posts.id <= 3 OR posts.#{QUOTED_TYPE} = 'Post'") - end - end - - def test_select_value - assert_equal "37signals", Company.connection.select_value("SELECT name FROM companies WHERE id = 1") - assert_nil Company.connection.select_value("SELECT name FROM companies WHERE id = -1") - # make sure we didn't break count... - assert_equal 0, Company.count_by_sql("SELECT COUNT(*) FROM companies WHERE name = 'Halliburton'") - assert_equal 1, Company.count_by_sql("SELECT COUNT(*) FROM companies WHERE name = '37signals'") - end - - def test_select_values - assert_equal ["1","2","3","4","5","6","7","8"], Company.connection.select_values("SELECT id FROM companies ORDER BY id").map! { |i| i.to_s } - assert_equal ["37signals","Summit","Microsoft", "Flamboyant Software", "Ex Nihilo", "RailsCore", "Leetsoft", "Jadedpixel"], Company.connection.select_values("SELECT name FROM companies ORDER BY id") - end - - protected - def bind(statement, *vars) - if vars.first.is_a?(Hash) - ActiveRecord::Base.send(:replace_named_bind_variables, statement, vars.first) - else - ActiveRecord::Base.send(:replace_bind_variables, statement, vars) - end - end -end diff --git a/tracks/vendor/rails/activerecord/test/fixtures/accounts.yml b/tracks/vendor/rails/activerecord/test/fixtures/accounts.yml deleted file mode 100644 index 8cff4389..00000000 --- a/tracks/vendor/rails/activerecord/test/fixtures/accounts.yml +++ /dev/null @@ -1,13 +0,0 @@ -signals37: - id: 1 - firm_id: 1 - credit_limit: 50 - -unknown: - id: 2 - credit_limit: 50 - -rails_core_account: - id: 3 - firm_id: 6 - credit_limit: 50 diff --git a/tracks/vendor/rails/activerecord/test/fixtures/author.rb b/tracks/vendor/rails/activerecord/test/fixtures/author.rb deleted file mode 100644 index e98d15e3..00000000 --- a/tracks/vendor/rails/activerecord/test/fixtures/author.rb +++ /dev/null @@ -1,46 +0,0 @@ -class Author < ActiveRecord::Base - has_many :posts - has_many :posts_with_comments, :include => :comments, :class_name => "Post" - has_many :posts_with_categories, :include => :categories, :class_name => "Post" - has_many :posts_with_comments_and_categories, :include => [ :comments, :categories ], :order => "posts.id", :class_name => "Post" - - has_many :posts_with_callbacks, :class_name => "Post", :before_add => :log_before_adding, - :after_add => :log_after_adding, :before_remove => :log_before_removing, - :after_remove => :log_after_removing - has_many :posts_with_proc_callbacks, :class_name => "Post", - :before_add => Proc.new {|o, r| o.post_log << "before_adding#{r.id}"}, - :after_add => Proc.new {|o, r| o.post_log << "after_adding#{r.id}"}, - :before_remove => Proc.new {|o, r| o.post_log << "before_removing#{r.id}"}, - :after_remove => Proc.new {|o, r| o.post_log << "after_removing#{r.id}"} - has_many :posts_with_multiple_callbacks, :class_name => "Post", - :before_add => [:log_before_adding, Proc.new {|o, r| o.post_log << "before_adding_proc#{r.id}"}], - :after_add => [:log_after_adding, Proc.new {|o, r| o.post_log << "after_adding_proc#{r.id}"}] - has_many :unchangable_posts, :class_name => "Post", :before_add => :raise_exception, :after_add => :log_after_adding - - attr_accessor :post_log - - def after_initialize - @post_log = [] - end - - private - def log_before_adding(object) - @post_log << "before_adding#{object.id}" - end - - def log_after_adding(object) - @post_log << "after_adding#{object.id}" - end - - def log_before_removing(object) - @post_log << "before_removing#{object.id}" - end - - def log_after_removing(object) - @post_log << "after_removing#{object.id}" - end - - def raise_exception(object) - raise Exception.new("You can't add a post") - end -end diff --git a/tracks/vendor/rails/activerecord/test/fixtures/authors.yml b/tracks/vendor/rails/activerecord/test/fixtures/authors.yml deleted file mode 100644 index f59b84fa..00000000 --- a/tracks/vendor/rails/activerecord/test/fixtures/authors.yml +++ /dev/null @@ -1,7 +0,0 @@ -david: - id: 1 - name: David - -mary: - id: 2 - name: Mary diff --git a/tracks/vendor/rails/activerecord/test/fixtures/auto_id.rb b/tracks/vendor/rails/activerecord/test/fixtures/auto_id.rb deleted file mode 100644 index d720e2be..00000000 --- a/tracks/vendor/rails/activerecord/test/fixtures/auto_id.rb +++ /dev/null @@ -1,4 +0,0 @@ -class AutoId < ActiveRecord::Base - def self.table_name () "auto_id_tests" end - def self.primary_key () "auto_id" end -end diff --git a/tracks/vendor/rails/activerecord/test/fixtures/bad_fixtures/attr_with_numeric_first_char b/tracks/vendor/rails/activerecord/test/fixtures/bad_fixtures/attr_with_numeric_first_char deleted file mode 100644 index ef27947f..00000000 --- a/tracks/vendor/rails/activerecord/test/fixtures/bad_fixtures/attr_with_numeric_first_char +++ /dev/null @@ -1 +0,0 @@ -1b => 1 diff --git a/tracks/vendor/rails/activerecord/test/fixtures/bad_fixtures/attr_with_spaces b/tracks/vendor/rails/activerecord/test/fixtures/bad_fixtures/attr_with_spaces deleted file mode 100644 index 46fd6f2f..00000000 --- a/tracks/vendor/rails/activerecord/test/fixtures/bad_fixtures/attr_with_spaces +++ /dev/null @@ -1 +0,0 @@ -a b => 1 diff --git a/tracks/vendor/rails/activerecord/test/fixtures/bad_fixtures/blank_line b/tracks/vendor/rails/activerecord/test/fixtures/bad_fixtures/blank_line deleted file mode 100644 index 3ea1f717..00000000 --- a/tracks/vendor/rails/activerecord/test/fixtures/bad_fixtures/blank_line +++ /dev/null @@ -1,3 +0,0 @@ -a => 1 - -b => 2 diff --git a/tracks/vendor/rails/activerecord/test/fixtures/bad_fixtures/duplicate_attributes b/tracks/vendor/rails/activerecord/test/fixtures/bad_fixtures/duplicate_attributes deleted file mode 100644 index cc0236f2..00000000 --- a/tracks/vendor/rails/activerecord/test/fixtures/bad_fixtures/duplicate_attributes +++ /dev/null @@ -1,3 +0,0 @@ -a => 1 -b => 2 -a => 3 diff --git a/tracks/vendor/rails/activerecord/test/fixtures/bad_fixtures/missing_value b/tracks/vendor/rails/activerecord/test/fixtures/bad_fixtures/missing_value deleted file mode 100644 index fb59ec33..00000000 --- a/tracks/vendor/rails/activerecord/test/fixtures/bad_fixtures/missing_value +++ /dev/null @@ -1 +0,0 @@ -a => diff --git a/tracks/vendor/rails/activerecord/test/fixtures/binary.rb b/tracks/vendor/rails/activerecord/test/fixtures/binary.rb deleted file mode 100644 index 950c4591..00000000 --- a/tracks/vendor/rails/activerecord/test/fixtures/binary.rb +++ /dev/null @@ -1,2 +0,0 @@ -class Binary < ActiveRecord::Base -end \ No newline at end of file diff --git a/tracks/vendor/rails/activerecord/test/fixtures/categories.yml b/tracks/vendor/rails/activerecord/test/fixtures/categories.yml deleted file mode 100644 index b0770a09..00000000 --- a/tracks/vendor/rails/activerecord/test/fixtures/categories.yml +++ /dev/null @@ -1,14 +0,0 @@ -general: - id: 1 - name: General - type: Category - -technology: - id: 2 - name: Technology - type: Category - -sti_test: - id: 3 - name: Special category - type: SpecialCategory diff --git a/tracks/vendor/rails/activerecord/test/fixtures/categories_ordered.yml b/tracks/vendor/rails/activerecord/test/fixtures/categories_ordered.yml deleted file mode 100644 index 294a6368..00000000 --- a/tracks/vendor/rails/activerecord/test/fixtures/categories_ordered.yml +++ /dev/null @@ -1,7 +0,0 @@ ---- !omap -<% 100.times do |i| %> -- fixture_no_<%= i %>: - id: <%= i %> - name: <%= "Category #{i}" %> - type: Category -<% end %> diff --git a/tracks/vendor/rails/activerecord/test/fixtures/categories_posts.yml b/tracks/vendor/rails/activerecord/test/fixtures/categories_posts.yml deleted file mode 100644 index 0d77d8c0..00000000 --- a/tracks/vendor/rails/activerecord/test/fixtures/categories_posts.yml +++ /dev/null @@ -1,19 +0,0 @@ -general_welcome: - category_id: 1 - post_id: 1 - -technology_welcome: - category_id: 2 - post_id: 1 - -general_thinking: - category_id: 1 - post_id: 2 - -general_sti_habtm: - category_id: 1 - post_id: 6 - -sti_test_sti_habtm: - category_id: 3 - post_id: 6 diff --git a/tracks/vendor/rails/activerecord/test/fixtures/category.rb b/tracks/vendor/rails/activerecord/test/fixtures/category.rb deleted file mode 100644 index 880eb157..00000000 --- a/tracks/vendor/rails/activerecord/test/fixtures/category.rb +++ /dev/null @@ -1,15 +0,0 @@ -class Category < ActiveRecord::Base - has_and_belongs_to_many :posts - - def self.what_are_you - 'a category...' - end -end - -class SpecialCategory < Category - - def self.what_are_you - 'a special category...' - end - -end diff --git a/tracks/vendor/rails/activerecord/test/fixtures/column_name.rb b/tracks/vendor/rails/activerecord/test/fixtures/column_name.rb deleted file mode 100644 index ec07205a..00000000 --- a/tracks/vendor/rails/activerecord/test/fixtures/column_name.rb +++ /dev/null @@ -1,3 +0,0 @@ -class ColumnName < ActiveRecord::Base - def self.table_name () "colnametests" end -end \ No newline at end of file diff --git a/tracks/vendor/rails/activerecord/test/fixtures/comment.rb b/tracks/vendor/rails/activerecord/test/fixtures/comment.rb deleted file mode 100644 index 3eab263f..00000000 --- a/tracks/vendor/rails/activerecord/test/fixtures/comment.rb +++ /dev/null @@ -1,23 +0,0 @@ -class Comment < ActiveRecord::Base - belongs_to :post - - def self.what_are_you - 'a comment...' - end - - def self.search_by_type(q) - self.find(:all, :conditions => ["#{QUOTED_TYPE} = ?", q]) - end -end - -class SpecialComment < Comment - def self.what_are_you - 'a special comment...' - end -end - -class VerySpecialComment < Comment - def self.what_are_you - 'a very special comment...' - end -end \ No newline at end of file diff --git a/tracks/vendor/rails/activerecord/test/fixtures/comments.yml b/tracks/vendor/rails/activerecord/test/fixtures/comments.yml deleted file mode 100644 index 758eaf6d..00000000 --- a/tracks/vendor/rails/activerecord/test/fixtures/comments.yml +++ /dev/null @@ -1,65 +0,0 @@ -greetings: - id: 1 - post_id: 1 - body: Thank you for the welcome - type: Comment - -more_greetings: - id: 2 - post_id: 1 - body: Thank you again for the welcome - type: Comment - -does_it_hurt: - id: 3 - post_id: 2 - body: Don't think too hard - type: SpecialComment - -eager_sti_on_associations_comment: - id: 4 - post_id: 4 - body: Normal type - type: Comment - -eager_sti_on_associations_vs_comment: - id: 5 - post_id: 4 - body: Very Special type - type: VerySpecialComment - -eager_sti_on_associations_s_comment1: - id: 6 - post_id: 4 - body: Special type - type: SpecialComment - -eager_sti_on_associations_s_comment2: - id: 7 - post_id: 4 - body: Special type 2 - type: SpecialComment - -eager_sti_on_associations_comment: - id: 8 - post_id: 4 - body: Normal type - type: Comment - -check_eager_sti_on_associations: - id: 9 - post_id: 5 - body: Normal type - type: Comment - -check_eager_sti_on_associations2: - id: 10 - post_id: 5 - body: Special Type - type: SpecialComment - -eager_other_comment1: - id: 11 - post_id: 7 - body: go crazy - type: SpecialComment diff --git a/tracks/vendor/rails/activerecord/test/fixtures/companies.yml b/tracks/vendor/rails/activerecord/test/fixtures/companies.yml deleted file mode 100644 index f2e638d3..00000000 --- a/tracks/vendor/rails/activerecord/test/fixtures/companies.yml +++ /dev/null @@ -1,50 +0,0 @@ -first_client: - id: 2 - type: Client - firm_id: 1 - client_of: 2 - name: Summit - ruby_type: Client - -first_firm: - id: 1 - type: Firm - name: 37signals - ruby_type: Firm - -second_client: - id: 3 - type: Client - firm_id: 1 - client_of: 1 - name: Microsoft - ruby_type: Client - -another_firm: - id: 4 - type: Firm - name: Flamboyant Software - ruby_type: Firm - -another_client: - id: 5 - type: Client - firm_id: 4 - client_of: 4 - name: Ex Nihilo - ruby_type: Client - -rails_core: - id: 6 - name: RailsCore - type: DependentFirm - -leetsoft: - id: 7 - name: Leetsoft - client_of: 6 - -jadedpixel: - id: 8 - name: Jadedpixel - client_of: 6 \ No newline at end of file diff --git a/tracks/vendor/rails/activerecord/test/fixtures/company.rb b/tracks/vendor/rails/activerecord/test/fixtures/company.rb deleted file mode 100644 index 6d33d4e1..00000000 --- a/tracks/vendor/rails/activerecord/test/fixtures/company.rb +++ /dev/null @@ -1,73 +0,0 @@ -class Company < ActiveRecord::Base - attr_protected :rating - set_sequence_name :companies_nonstd_seq - - validates_presence_of :name -end - - -class Firm < Company - has_many :clients, :order => "id", :dependent => true, :counter_sql => - "SELECT COUNT(*) FROM companies WHERE firm_id = 1 " + - "AND (#{QUOTED_TYPE} = 'Client' OR #{QUOTED_TYPE} = 'SpecialClient' OR #{QUOTED_TYPE} = 'VerySpecialClient' )" - has_many :clients_sorted_desc, :class_name => "Client", :order => "id DESC" - has_many :clients_of_firm, :foreign_key => "client_of", :class_name => "Client", :order => "id" - has_many :dependent_clients_of_firm, :foreign_key => "client_of", :class_name => "Client", :order => "id", :dependent => true - has_many :exclusively_dependent_clients_of_firm, :foreign_key => "client_of", :class_name => "Client", :order => "id", :exclusively_dependent => true - has_many :clients_like_ms, :conditions => "name = 'Microsoft'", :class_name => "Client", :order => "id" - has_many :clients_using_sql, :class_name => "Client", :finder_sql => 'SELECT * FROM companies WHERE client_of = #{id}' - has_many :clients_using_counter_sql, :class_name => "Client", - :finder_sql => 'SELECT * FROM companies WHERE client_of = #{id}', - :counter_sql => 'SELECT COUNT(*) FROM companies WHERE client_of = #{id}' - has_many :clients_using_zero_counter_sql, :class_name => "Client", - :finder_sql => 'SELECT * FROM companies WHERE client_of = #{id}', - :counter_sql => 'SELECT 0 FROM companies WHERE client_of = #{id}' - has_many :no_clients_using_counter_sql, :class_name => "Client", - :finder_sql => 'SELECT * FROM companies WHERE client_of = 1000', - :counter_sql => 'SELECT COUNT(*) FROM companies WHERE client_of = 1000' - - has_one :account, :foreign_key => "firm_id", :dependent => true -end - -class DependentFirm < Company - has_one :account, :foreign_key => "firm_id", :dependent => :nullify - has_many :companies, :foreign_key => 'client_of', :order => "id", :dependent => :nullify -end - - -class Client < Company - belongs_to :firm, :foreign_key => "client_of" - belongs_to :firm_with_basic_id, :class_name => "Firm", :foreign_key => "firm_id" - belongs_to :firm_with_other_name, :class_name => "Firm", :foreign_key => "client_of" - belongs_to :firm_with_condition, :class_name => "Firm", :foreign_key => "client_of", :conditions => "1 = 1" - - # Record destruction so we can test whether firm.clients.clear has - # is calling client.destroy, deleting from the database, or setting - # foreign keys to NULL. - def self.destroyed_client_ids - @destroyed_client_ids ||= Hash.new { |h,k| h[k] = [] } - end - - before_destroy do |client| - if client.firm - Client.destroyed_client_ids[client.firm.id] << client.id - end - true - end -end - - -class SpecialClient < Client -end - -class VerySpecialClient < SpecialClient -end - -class Account < ActiveRecord::Base - belongs_to :firm - - protected - def validate - errors.add_on_empty "credit_limit" - end -end \ No newline at end of file diff --git a/tracks/vendor/rails/activerecord/test/fixtures/company_in_module.rb b/tracks/vendor/rails/activerecord/test/fixtures/company_in_module.rb deleted file mode 100644 index 52b5d37b..00000000 --- a/tracks/vendor/rails/activerecord/test/fixtures/company_in_module.rb +++ /dev/null @@ -1,47 +0,0 @@ -module MyApplication - module Business - class Company < ActiveRecord::Base - attr_protected :rating - end - - class Firm < Company - has_many :clients, :order => "id", :dependent => true - has_many :clients_sorted_desc, :class_name => "Client", :order => "id DESC" - has_many :clients_of_firm, :foreign_key => "client_of", :class_name => "Client", :order => "id" - has_many :clients_like_ms, :conditions => "name = 'Microsoft'", :class_name => "Client", :order => "id" - has_many :clients_using_sql, :class_name => "Client", :finder_sql => 'SELECT * FROM companies WHERE client_of = #{id}' - - has_one :account, :dependent => true - end - - class Client < Company - belongs_to :firm, :foreign_key => "client_of" - belongs_to :firm_with_other_name, :class_name => "Firm", :foreign_key => "client_of" - end - - class Developer < ActiveRecord::Base - has_and_belongs_to_many :projects - - protected - def validate - errors.add_on_boundary_breaking("name", 3..20) - end - end - - class Project < ActiveRecord::Base - has_and_belongs_to_many :developers - end - - end - - module Billing - class Account < ActiveRecord::Base - belongs_to :firm, :class_name => "MyApplication::Business::Firm" - - protected - def validate - errors.add_on_empty "credit_limit" - end - end - end -end diff --git a/tracks/vendor/rails/activerecord/test/fixtures/computer.rb b/tracks/vendor/rails/activerecord/test/fixtures/computer.rb deleted file mode 100644 index cc8deb1b..00000000 --- a/tracks/vendor/rails/activerecord/test/fixtures/computer.rb +++ /dev/null @@ -1,3 +0,0 @@ -class Computer < ActiveRecord::Base - belongs_to :developer, :foreign_key=>'developer' -end diff --git a/tracks/vendor/rails/activerecord/test/fixtures/computers.yml b/tracks/vendor/rails/activerecord/test/fixtures/computers.yml deleted file mode 100644 index daf969d7..00000000 --- a/tracks/vendor/rails/activerecord/test/fixtures/computers.yml +++ /dev/null @@ -1,4 +0,0 @@ -workstation: - id: 1 - developer: 1 - extendedWarranty: 1 diff --git a/tracks/vendor/rails/activerecord/test/fixtures/course.rb b/tracks/vendor/rails/activerecord/test/fixtures/course.rb deleted file mode 100644 index 8a40fa74..00000000 --- a/tracks/vendor/rails/activerecord/test/fixtures/course.rb +++ /dev/null @@ -1,3 +0,0 @@ -class Course < ActiveRecord::Base - has_many :entrants -end diff --git a/tracks/vendor/rails/activerecord/test/fixtures/courses.yml b/tracks/vendor/rails/activerecord/test/fixtures/courses.yml deleted file mode 100644 index 5ee19160..00000000 --- a/tracks/vendor/rails/activerecord/test/fixtures/courses.yml +++ /dev/null @@ -1,7 +0,0 @@ -ruby: - id: 1 - name: Ruby Development - -java: - id: 2 - name: Java Development diff --git a/tracks/vendor/rails/activerecord/test/fixtures/customer.rb b/tracks/vendor/rails/activerecord/test/fixtures/customer.rb deleted file mode 100644 index 2eba052e..00000000 --- a/tracks/vendor/rails/activerecord/test/fixtures/customer.rb +++ /dev/null @@ -1,51 +0,0 @@ -class Customer < ActiveRecord::Base - composed_of :address, :mapping => [ %w(address_street street), %w(address_city city), %w(address_country country) ] - composed_of :balance, :class_name => "Money", :mapping => %w(balance amount) - composed_of :gps_location -end - -class Address - attr_reader :street, :city, :country - - def initialize(street, city, country) - @street, @city, @country = street, city, country - end - - def close_to?(other_address) - city == other_address.city && country == other_address.country - end -end - -class Money - attr_reader :amount, :currency - - EXCHANGE_RATES = { "USD_TO_DKK" => 6, "DKK_TO_USD" => 0.6 } - - def initialize(amount, currency = "USD") - @amount, @currency = amount, currency - end - - def exchange_to(other_currency) - Money.new((amount * EXCHANGE_RATES["#{currency}_TO_#{other_currency}"]).floor, other_currency) - end -end - -class GpsLocation - attr_reader :gps_location - - def initialize(gps_location) - @gps_location = gps_location - end - - def latitude - gps_location.split("x").first - end - - def longitude - gps_location.split("x").last - end - - def ==(other) - self.latitude == other.latitude && self.longitude == other.longitude - end -end \ No newline at end of file diff --git a/tracks/vendor/rails/activerecord/test/fixtures/customers.yml b/tracks/vendor/rails/activerecord/test/fixtures/customers.yml deleted file mode 100644 index 9169d7d4..00000000 --- a/tracks/vendor/rails/activerecord/test/fixtures/customers.yml +++ /dev/null @@ -1,8 +0,0 @@ -david: - id: 1 - name: David - balance: 50 - address_street: Funny Street - address_city: Scary Town - address_country: Loony Land - gps_location: 35.544623640962634x-105.9309951055148 diff --git a/tracks/vendor/rails/activerecord/test/fixtures/db_definitions/create_oracle_db.bat b/tracks/vendor/rails/activerecord/test/fixtures/db_definitions/create_oracle_db.bat deleted file mode 100644 index e69de29b..00000000 diff --git a/tracks/vendor/rails/activerecord/test/fixtures/db_definitions/create_oracle_db.sh b/tracks/vendor/rails/activerecord/test/fixtures/db_definitions/create_oracle_db.sh deleted file mode 100644 index e69de29b..00000000 diff --git a/tracks/vendor/rails/activerecord/test/fixtures/db_definitions/db2.drop.sql b/tracks/vendor/rails/activerecord/test/fixtures/db_definitions/db2.drop.sql deleted file mode 100644 index ce2d3688..00000000 --- a/tracks/vendor/rails/activerecord/test/fixtures/db_definitions/db2.drop.sql +++ /dev/null @@ -1,27 +0,0 @@ -DROP TABLE accounts; -DROP TABLE companies; -DROP TABLE topics; -DROP TABLE developers; -DROP TABLE projects; -DROP TABLE developers_projects; -DROP TABLE orders; -DROP TABLE customers; -DROP TABLE movies; -DROP TABLE subscribers; -DROP TABLE booleantests; -DROP TABLE auto_id_tests; -DROP TABLE entrants; -DROP TABLE colnametests; -DROP TABLE mixins; -DROP TABLE people; -DROP TABLE binaries; -DROP TABLE computers; -DROP TABLE posts; -DROP TABLE comments; -DROP TABLE authors; -DROP TABLE tasks; -DROP TABLE categories; -DROP TABLE categories_posts; -DROP TABLE fk_test_has_pk; -DROP TABLE fk_test_has_fk; -DROP TABLE keyboards; diff --git a/tracks/vendor/rails/activerecord/test/fixtures/db_definitions/db2.sql b/tracks/vendor/rails/activerecord/test/fixtures/db_definitions/db2.sql deleted file mode 100644 index 49f31aba..00000000 --- a/tracks/vendor/rails/activerecord/test/fixtures/db_definitions/db2.sql +++ /dev/null @@ -1,196 +0,0 @@ -CREATE TABLE accounts ( - id int generated by default as identity (start with +10000), - firm_id int default NULL, - credit_limit int default NULL, - PRIMARY KEY (id) -); - -CREATE TABLE companies ( - id int generated by default as identity (start with +10000), - type varchar(50) default NULL, - ruby_type varchar(50) default NULL, - firm_id int default NULL, - name varchar(50) default NULL, - client_of int default NULL, - rating int default 1, - PRIMARY KEY (id) -); - -CREATE TABLE topics ( - id int generated by default as identity (start with +10000), - title varchar(255) default NULL, - author_name varchar(255) default NULL, - author_email_address varchar(255) default NULL, - written_on timestamp default NULL, - bonus_time time default NULL, - last_read date default NULL, - content varchar(3000), - approved smallint default 1, - replies_count int default 0, - parent_id int default NULL, - type varchar(50) default NULL, - PRIMARY KEY (id) -); - -CREATE TABLE developers ( - id int generated by default as identity (start with +10000), - name varchar(100) default NULL, - salary int default 70000, - created_at timestamp default NULL, - updated_at timestamp default NULL, - PRIMARY KEY (id) -); - -CREATE TABLE projects ( - id int generated by default as identity (start with +10000), - name varchar(100) default NULL, - type varchar(255) default NULL, - PRIMARY KEY (id) -); - -CREATE TABLE developers_projects ( - developer_id int NOT NULL, - project_id int NOT NULL, - joined_on date default NULL, - access_level smallint default 1 -); - -CREATE TABLE orders ( - id int generated by default as identity (start with +10000), - name varchar(100) default NULL, - billing_customer_id int default NULL, - shipping_customer_id int default NULL, - PRIMARY KEY (id) -); - -CREATE TABLE customers ( - id int generated by default as identity (start with +10000), - name varchar(100) default NULL, - balance int default 0, - address_street varchar(100) default NULL, - address_city varchar(100) default NULL, - address_country varchar(100) default NULL, - gps_location varchar(100) default NULL, - PRIMARY KEY (id) -); - -CREATE TABLE movies ( - movieid int generated by default as identity (start with +10000), - name varchar(100) default NULL, - PRIMARY KEY (movieid) -); - -CREATE TABLE subscribers ( - nick varchar(100) NOT NULL, - name varchar(100) default NULL, - PRIMARY KEY (nick) -); - -CREATE TABLE booleantests ( - id int generated by default as identity (start with +10000), - value int default NULL, - PRIMARY KEY (id) -); - -CREATE TABLE auto_id_tests ( - auto_id int generated by default as identity (start with +10000), - value int default NULL, - PRIMARY KEY (auto_id) -); - -CREATE TABLE entrants ( - id int NOT NULL PRIMARY KEY, - name varchar(255) NOT NULL, - course_id int NOT NULL -); - -CREATE TABLE colnametests ( - id int generated by default as identity (start with +10000), - references int NOT NULL, - PRIMARY KEY (id) -); - -CREATE TABLE mixins ( - id int generated by default as identity (start with +10000), - parent_id int default NULL, - pos int default NULL, - created_at timestamp default NULL, - updated_at timestamp default NULL, - lft int default NULL, - rgt int default NULL, - root_id int default NULL, - type varchar(40) default NULL, - PRIMARY KEY (id) -); - -CREATE TABLE people ( - id int generated by default as identity (start with +10000), - first_name varchar(40) NOT NULL, - lock_version int default 0, - PRIMARY KEY (id) -); - -CREATE TABLE binaries ( - id int generated by default as identity (start with +10000), - data blob(50000), - PRIMARY KEY (id) -); - -CREATE TABLE computers ( - id int generated by default as identity (start with +10000), - developer int NOT NULL, - extendedWarranty int NOT NULL -); - -CREATE TABLE posts ( - id int generated by default as identity (start with +10000), - author_id int default NULL, - title varchar(255) default NULL, - type varchar(255) default NULL, - body varchar(3000) default NULL -); - -CREATE TABLE comments ( - id int generated by default as identity (start with +10000), - post_id int default NULL, - type varchar(255) default NULL, - body varchar(3000) default NULL -); - -CREATE TABLE authors ( - id int generated by default as identity (start with +10000), - name varchar(255) default NULL -); - -CREATE TABLE tasks ( - id int generated by default as identity (start with +10000), - starting timestamp default NULL, - ending timestamp default NULL -); - -CREATE TABLE categories ( - id int generated by default as identity (start with +10000), - name varchar(255) NOT NULL, - type varchar(40) default NULL -); - -CREATE TABLE categories_posts ( - category_id int NOT NULL, - post_id int NOT NULL -); - -CREATE TABLE keyboards ( - key_number int generated by default as identity (start with +10000), - name VARCHAR(255) -); - -CREATE TABLE fk_test_has_pk ( - id INTEGER NOT NULL PRIMARY KEY -); - -CREATE TABLE fk_test_has_fk ( - id INTEGER NOT NULL PRIMARY KEY, - fk_id INTEGER NOT NULL, - - FOREIGN KEY (fk_id) REFERENCES fk_test_has_pk(id) -); diff --git a/tracks/vendor/rails/activerecord/test/fixtures/db_definitions/db22.drop.sql b/tracks/vendor/rails/activerecord/test/fixtures/db_definitions/db22.drop.sql deleted file mode 100644 index df00ffd7..00000000 --- a/tracks/vendor/rails/activerecord/test/fixtures/db_definitions/db22.drop.sql +++ /dev/null @@ -1,2 +0,0 @@ -DROP TABLE courses; - diff --git a/tracks/vendor/rails/activerecord/test/fixtures/db_definitions/db22.sql b/tracks/vendor/rails/activerecord/test/fixtures/db_definitions/db22.sql deleted file mode 100644 index 9198cf5f..00000000 --- a/tracks/vendor/rails/activerecord/test/fixtures/db_definitions/db22.sql +++ /dev/null @@ -1,5 +0,0 @@ -CREATE TABLE courses ( - id int NOT NULL PRIMARY KEY, - name varchar(255) NOT NULL -); - diff --git a/tracks/vendor/rails/activerecord/test/fixtures/db_definitions/firebird.drop.sql b/tracks/vendor/rails/activerecord/test/fixtures/db_definitions/firebird.drop.sql deleted file mode 100644 index 44b3be41..00000000 --- a/tracks/vendor/rails/activerecord/test/fixtures/db_definitions/firebird.drop.sql +++ /dev/null @@ -1,54 +0,0 @@ -DROP TABLE accounts; -DROP TABLE companies; -DROP TABLE topics; -DROP TABLE developers; -DROP TABLE projects; -DROP TABLE developers_projects; -DROP TABLE orders; -DROP TABLE customers; -DROP TABLE movies; -DROP TABLE subscribers; -DROP TABLE booleantests; -DROP TABLE auto_id_tests; -DROP TABLE entrants; -DROP TABLE colnametests; -DROP TABLE mixins; -DROP TABLE people; -DROP TABLE binaries; -DROP TABLE computers; -DROP TABLE posts; -DROP TABLE comments; -DROP TABLE authors; -DROP TABLE tasks; -DROP TABLE categories; -DROP TABLE categories_posts; -DROP TABLE fk_test_has_fk; -DROP TABLE fk_test_has_pk; -DROP TABLE keyboards; -DROP TABLE defaults; - -DROP DOMAIN D_BOOLEAN; - -DROP GENERATOR accounts_seq; -DROP GENERATOR companies_nonstd_seq; -DROP GENERATOR topics_seq; -DROP GENERATOR developers_seq; -DROP GENERATOR projects_seq; -DROP GENERATOR orders_seq; -DROP GENERATOR customers_seq; -DROP GENERATOR movies_seq; -DROP GENERATOR booleantests_seq; -DROP GENERATOR auto_id_tests_seq; -DROP GENERATOR entrants_seq; -DROP GENERATOR colnametests_seq; -DROP GENERATOR mixins_seq; -DROP GENERATOR people_seq; -DROP GENERATOR binaries_seq; -DROP GENERATOR computers_seq; -DROP GENERATOR posts_seq; -DROP GENERATOR comments_seq; -DROP GENERATOR authors_seq; -DROP GENERATOR tasks_seq; -DROP GENERATOR categories_seq; -DROP GENERATOR keyboards_seq; -DROP GENERATOR defaults_seq; diff --git a/tracks/vendor/rails/activerecord/test/fixtures/db_definitions/firebird.sql b/tracks/vendor/rails/activerecord/test/fixtures/db_definitions/firebird.sql deleted file mode 100644 index 8d7316d4..00000000 --- a/tracks/vendor/rails/activerecord/test/fixtures/db_definitions/firebird.sql +++ /dev/null @@ -1,259 +0,0 @@ -CREATE DOMAIN D_BOOLEAN AS SMALLINT CHECK (VALUE IN (0, 1)); - -CREATE TABLE accounts ( - id BIGINT NOT NULL, - firm_id BIGINT, - credit_limit INTEGER, - PRIMARY KEY (id) -); -CREATE GENERATOR accounts_seq; -SET GENERATOR accounts_seq TO 10000; - -CREATE TABLE companies ( - id BIGINT NOT NULL, - "TYPE" VARCHAR(50), - ruby_type VARCHAR(50), - firm_id BIGINT, - name VARCHAR(50), - client_of INTEGER, - rating INTEGER DEFAULT 1, - PRIMARY KEY (id) -); -CREATE GENERATOR companies_nonstd_seq; -SET GENERATOR companies_nonstd_seq TO 10000; - -CREATE TABLE topics ( - id BIGINT NOT NULL, - title VARCHAR(255), - author_name VARCHAR(255), - author_email_address VARCHAR(255), - written_on TIMESTAMP, - bonus_time TIME, - last_read DATE, - content VARCHAR(4000), - approved D_BOOLEAN DEFAULT 1, - replies_count INTEGER DEFAULT 0, - parent_id BIGINT, - "TYPE" VARCHAR(50), - PRIMARY KEY (id) -); -CREATE GENERATOR topics_seq; -SET GENERATOR topics_seq TO 10000; - -CREATE TABLE developers ( - id BIGINT NOT NULL, - name VARCHAR(100), - salary INTEGER DEFAULT 70000, - created_at TIMESTAMP, - updated_at TIMESTAMP, - PRIMARY KEY (id) -); -CREATE GENERATOR developers_seq; -SET GENERATOR developers_seq TO 10000; - -CREATE TABLE projects ( - id BIGINT NOT NULL, - name VARCHAR(100), - "TYPE" VARCHAR(255), - PRIMARY KEY (id) -); -CREATE GENERATOR projects_seq; -SET GENERATOR projects_seq TO 10000; - -CREATE TABLE developers_projects ( - developer_id BIGINT NOT NULL, - project_id BIGINT NOT NULL, - joined_on DATE, - access_level SMALLINT DEFAULT 1 -); - -CREATE TABLE orders ( - id BIGINT NOT NULL, - name VARCHAR(100), - billing_customer_id BIGINT, - shipping_customer_id BIGINT, - PRIMARY KEY (id) -); -CREATE GENERATOR orders_seq; -SET GENERATOR orders_seq TO 10000; - -CREATE TABLE customers ( - id BIGINT NOT NULL, - name VARCHAR(100), - balance INTEGER DEFAULT 0, - address_street VARCHAR(100), - address_city VARCHAR(100), - address_country VARCHAR(100), - gps_location VARCHAR(100), - PRIMARY KEY (id) -); -CREATE GENERATOR customers_seq; -SET GENERATOR customers_seq TO 10000; - -CREATE TABLE movies ( - movieid BIGINT NOT NULL, - name varchar(100), - PRIMARY KEY (movieid) -); -CREATE GENERATOR movies_seq; -SET GENERATOR movies_seq TO 10000; - -CREATE TABLE subscribers ( - nick VARCHAR(100) NOT NULL, - name VARCHAR(100), - PRIMARY KEY (nick) -); - -CREATE TABLE booleantests ( - id BIGINT NOT NULL, - "VALUE" D_BOOLEAN, - PRIMARY KEY (id) -); -CREATE GENERATOR booleantests_seq; -SET GENERATOR booleantests_seq TO 10000; - -CREATE TABLE auto_id_tests ( - auto_id BIGINT NOT NULL, - "VALUE" INTEGER, - PRIMARY KEY (auto_id) -); -CREATE GENERATOR auto_id_tests_seq; -SET GENERATOR auto_id_tests_seq TO 10000; - -CREATE TABLE entrants ( - id BIGINT NOT NULL, - name VARCHAR(255) NOT NULL, - course_id INTEGER NOT NULL, - PRIMARY KEY (id) -); -CREATE GENERATOR entrants_seq; -SET GENERATOR entrants_seq TO 10000; - -CREATE TABLE colnametests ( - id BIGINT NOT NULL, - "REFERENCES" INTEGER NOT NULL, - PRIMARY KEY (id) -); -CREATE GENERATOR colnametests_seq; -SET GENERATOR colnametests_seq TO 10000; - -CREATE TABLE mixins ( - id BIGINT NOT NULL, - parent_id BIGINT, - pos INTEGER, - created_at TIMESTAMP, - updated_at TIMESTAMP, - lft INTEGER, - rgt INTEGER, - root_id BIGINT, - "TYPE" VARCHAR(40), - PRIMARY KEY (id) -); -CREATE GENERATOR mixins_seq; -SET GENERATOR mixins_seq TO 10000; - -CREATE TABLE people ( - id BIGINT NOT NULL, - first_name VARCHAR(40), - lock_version INTEGER DEFAULT 0 NOT NULL, - PRIMARY KEY (id) -); -CREATE GENERATOR people_seq; -SET GENERATOR people_seq TO 10000; - -CREATE TABLE binaries ( - id BIGINT NOT NULL, - data BLOB, - PRIMARY KEY (id) -); -CREATE GENERATOR binaries_seq; -SET GENERATOR binaries_seq TO 10000; - -CREATE TABLE computers ( - id BIGINT NOT NULL, - developer INTEGER NOT NULL, - "extendedWarranty" INTEGER NOT NULL, - PRIMARY KEY (id) -); -CREATE GENERATOR computers_seq; -SET GENERATOR computers_seq TO 10000; - -CREATE TABLE posts ( - id BIGINT NOT NULL, - author_id BIGINT, - title VARCHAR(255) NOT NULL, - "TYPE" VARCHAR(255) NOT NULL, - body VARCHAR(3000) NOT NULL, - PRIMARY KEY (id) -); -CREATE GENERATOR posts_seq; -SET GENERATOR posts_seq TO 10000; - -CREATE TABLE comments ( - id BIGINT NOT NULL, - post_id BIGINT NOT NULL, - "TYPE" VARCHAR(255) NOT NULL, - body VARCHAR(3000) NOT NULL, - PRIMARY KEY (id) -); -CREATE GENERATOR comments_seq; -SET GENERATOR comments_seq TO 10000; - -CREATE TABLE authors ( - id BIGINT NOT NULL, - name VARCHAR(255) NOT NULL, - PRIMARY KEY (id) -); -CREATE GENERATOR authors_seq; -SET GENERATOR authors_seq TO 10000; - -CREATE TABLE tasks ( - id BIGINT NOT NULL, - "STARTING" TIMESTAMP, - ending TIMESTAMP, - PRIMARY KEY (id) -); -CREATE GENERATOR tasks_seq; -SET GENERATOR tasks_seq TO 10000; - -CREATE TABLE categories ( - id BIGINT NOT NULL, - name VARCHAR(255) NOT NULL, - "TYPE" VARCHAR(255) NOT NULL, - PRIMARY KEY (id) -); -CREATE GENERATOR categories_seq; -SET GENERATOR categories_seq TO 10000; - -CREATE TABLE categories_posts ( - category_id BIGINT NOT NULL, - post_id BIGINT NOT NULL, - PRIMARY KEY (category_id, post_id) -); - -CREATE TABLE fk_test_has_pk ( - id BIGINT NOT NULL, - PRIMARY KEY (id) -); - -CREATE TABLE fk_test_has_fk ( - id BIGINT NOT NULL, - fk_id BIGINT NOT NULL, - PRIMARY KEY (id), - FOREIGN KEY (fk_id) REFERENCES fk_test_has_pk(id) -); - -CREATE TABLE keyboards ( - key_number BIGINT NOT NULL, - name VARCHAR(50), - PRIMARY KEY (key_number) -); -CREATE GENERATOR keyboards_seq; -SET GENERATOR keyboards_seq TO 10000; - -CREATE TABLE defaults ( - id BIGINT NOT NULL, - default_timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP -); -CREATE GENERATOR defaults_seq; -SET GENERATOR defaults_seq TO 10000; diff --git a/tracks/vendor/rails/activerecord/test/fixtures/db_definitions/firebird2.drop.sql b/tracks/vendor/rails/activerecord/test/fixtures/db_definitions/firebird2.drop.sql deleted file mode 100644 index c59fb1f2..00000000 --- a/tracks/vendor/rails/activerecord/test/fixtures/db_definitions/firebird2.drop.sql +++ /dev/null @@ -1,2 +0,0 @@ -DROP TABLE courses; -DROP GENERATOR courses_seq; diff --git a/tracks/vendor/rails/activerecord/test/fixtures/db_definitions/firebird2.sql b/tracks/vendor/rails/activerecord/test/fixtures/db_definitions/firebird2.sql deleted file mode 100644 index c1bc251f..00000000 --- a/tracks/vendor/rails/activerecord/test/fixtures/db_definitions/firebird2.sql +++ /dev/null @@ -1,6 +0,0 @@ -CREATE TABLE courses ( - id BIGINT NOT NULL PRIMARY KEY, - name VARCHAR(255) NOT NULL -); -CREATE GENERATOR courses_seq; -SET GENERATOR courses_seq TO 10000; diff --git a/tracks/vendor/rails/activerecord/test/fixtures/db_definitions/mysql.drop.sql b/tracks/vendor/rails/activerecord/test/fixtures/db_definitions/mysql.drop.sql deleted file mode 100644 index 8a37e2de..00000000 --- a/tracks/vendor/rails/activerecord/test/fixtures/db_definitions/mysql.drop.sql +++ /dev/null @@ -1,27 +0,0 @@ -DROP TABLE accounts; -DROP TABLE companies; -DROP TABLE topics; -DROP TABLE developers; -DROP TABLE projects; -DROP TABLE developers_projects; -DROP TABLE customers; -DROP TABLE orders; -DROP TABLE movies; -DROP TABLE subscribers; -DROP TABLE booleantests; -DROP TABLE auto_id_tests; -DROP TABLE entrants; -DROP TABLE colnametests; -DROP TABLE mixins; -DROP TABLE people; -DROP TABLE binaries; -DROP TABLE computers; -DROP TABLE tasks; -DROP TABLE posts; -DROP TABLE comments; -DROP TABLE authors; -DROP TABLE categories; -DROP TABLE categories_posts; -DROP TABLE fk_test_has_fk; -DROP TABLE fk_test_has_pk; -DROP TABLE keyboards; diff --git a/tracks/vendor/rails/activerecord/test/fixtures/db_definitions/mysql.sql b/tracks/vendor/rails/activerecord/test/fixtures/db_definitions/mysql.sql deleted file mode 100644 index d9b98042..00000000 --- a/tracks/vendor/rails/activerecord/test/fixtures/db_definitions/mysql.sql +++ /dev/null @@ -1,199 +0,0 @@ -CREATE TABLE `accounts` ( - `id` int(11) NOT NULL auto_increment, - `firm_id` int(11) default NULL, - `credit_limit` int(5) default NULL, - PRIMARY KEY (`id`) -) TYPE=InnoDB; - -CREATE TABLE `companies` ( - `id` int(11) NOT NULL auto_increment, - `type` varchar(50) default NULL, - `ruby_type` varchar(50) default NULL, - `firm_id` int(11) default NULL, - `name` varchar(50) default NULL, - `client_of` int(11) default NULL, - `rating` int(11) default NULL default 1, - PRIMARY KEY (`id`) -) TYPE=InnoDB; - - -CREATE TABLE `topics` ( - `id` int(11) NOT NULL auto_increment, - `title` varchar(255) default NULL, - `author_name` varchar(255) default NULL, - `author_email_address` varchar(255) default NULL, - `written_on` datetime default NULL, - `bonus_time` time default NULL, - `last_read` date default NULL, - `content` text, - `approved` tinyint default 1, - `replies_count` int(11) default 0, - `parent_id` int(11) default NULL, - `type` varchar(50) default NULL, - PRIMARY KEY (`id`) -) TYPE=InnoDB; - -CREATE TABLE `developers` ( - `id` int(11) NOT NULL auto_increment, - `name` varchar(100) default NULL, - `salary` int(11) default 70000, - `created_at` datetime default NULL, - `updated_at` datetime default NULL, - PRIMARY KEY (`id`) -) TYPE=InnoDB; - -CREATE TABLE `projects` ( - `id` int(11) NOT NULL auto_increment, - `name` varchar(100) default NULL, - `type` VARCHAR(255) NOT NULL, - PRIMARY KEY (`id`) -) TYPE=InnoDB; - -CREATE TABLE `developers_projects` ( - `developer_id` int(11) NOT NULL, - `project_id` int(11) NOT NULL, - `joined_on` date default NULL, - `access_level` smallint default 1 -) TYPE=InnoDB; - -CREATE TABLE `orders` ( - `id` int(11) NOT NULL auto_increment, - `name` varchar(100) default NULL, - `billing_customer_id` int(11) default NULL, - `shipping_customer_id` int(11) default NULL, - PRIMARY KEY (`id`) -) TYPE=InnoDB; - -CREATE TABLE `customers` ( - `id` int(11) NOT NULL auto_increment, - `name` varchar(100) default NULL, - `balance` int(6) default 0, - `address_street` varchar(100) default NULL, - `address_city` varchar(100) default NULL, - `address_country` varchar(100) default NULL, - `gps_location` varchar(100) default NULL, - PRIMARY KEY (`id`) -) TYPE=InnoDB; - -CREATE TABLE `movies` ( - `movieid` int(11) NOT NULL auto_increment, - `name` varchar(100) default NULL, - PRIMARY KEY (`movieid`) -) TYPE=InnoDB; - -CREATE TABLE `subscribers` ( - `nick` varchar(100) NOT NULL, - `name` varchar(100) default NULL, - PRIMARY KEY (`nick`) -) TYPE=InnoDB; - -CREATE TABLE `booleantests` ( - `id` int(11) NOT NULL auto_increment, - `value` integer default NULL, - PRIMARY KEY (`id`) -) TYPE=InnoDB; - -CREATE TABLE `auto_id_tests` ( - `auto_id` int(11) NOT NULL auto_increment, - `value` integer default NULL, - PRIMARY KEY (`auto_id`) -) TYPE=InnoDB; - -CREATE TABLE `entrants` ( - `id` INTEGER NOT NULL PRIMARY KEY, - `name` VARCHAR(255) NOT NULL, - `course_id` INTEGER NOT NULL -); - -CREATE TABLE `colnametests` ( - `id` int(11) NOT NULL auto_increment, - `references` int(11) NOT NULL, - PRIMARY KEY (`id`) -) TYPE=InnoDB; - -CREATE TABLE `mixins` ( - `id` int(11) NOT NULL auto_increment, - `parent_id` int(11) default NULL, - `pos` int(11) default NULL, - `created_at` datetime default NULL, - `updated_at` datetime default NULL, - `lft` int(11) default NULL, - `rgt` int(11) default NULL, - `root_id` int(11) default NULL, - `type` varchar(40) default NULL, - PRIMARY KEY (`id`) -) TYPE=InnoDB; - -CREATE TABLE `people` ( - `id` INTEGER NOT NULL PRIMARY KEY, - `first_name` VARCHAR(40) NOT NULL, - `lock_version` INTEGER NOT NULL DEFAULT 0 -) TYPE=InnoDB; - -CREATE TABLE `binaries` ( - `id` int(11) NOT NULL auto_increment, - `data` mediumblob, - PRIMARY KEY (`id`) -) TYPE=InnoDB; - -CREATE TABLE `computers` ( - `id` INTEGER NOT NULL PRIMARY KEY, - `developer` INTEGER NOT NULL, - `extendedWarranty` INTEGER NOT NULL -) TYPE=InnoDB; - -CREATE TABLE `posts` ( - `id` INTEGER NOT NULL PRIMARY KEY, - `author_id` INTEGER, - `title` VARCHAR(255) NOT NULL, - `body` TEXT NOT NULL, - `type` VARCHAR(255) NOT NULL -) TYPE=InnoDB; - -CREATE TABLE `comments` ( - `id` INTEGER NOT NULL PRIMARY KEY, - `post_id` INTEGER NOT NULL, - `body` TEXT NOT NULL, - `type` VARCHAR(255) NOT NULL -) TYPE=InnoDB; - -CREATE TABLE `authors` ( - `id` INTEGER NOT NULL PRIMARY KEY, - `name` VARCHAR(255) NOT NULL -) TYPE=InnoDB; - -CREATE TABLE `tasks` ( - `id` int(11) NOT NULL auto_increment, - `starting` datetime NOT NULL default '0000-00-00 00:00:00', - `ending` datetime NOT NULL default '0000-00-00 00:00:00', - PRIMARY KEY (`id`) -) TYPE=InnoDB; - -CREATE TABLE `categories` ( - `id` int(11) NOT NULL auto_increment, - `name` VARCHAR(255) NOT NULL, - `type` VARCHAR(255) NOT NULL, - PRIMARY KEY (`id`) -) TYPE=InnoDB; - -CREATE TABLE `categories_posts` ( - `category_id` int(11) NOT NULL, - `post_id` int(11) NOT NULL -) TYPE=InnoDB; - -CREATE TABLE `fk_test_has_pk` ( - `id` INTEGER NOT NULL PRIMARY KEY -) TYPE=InnoDB; - -CREATE TABLE `fk_test_has_fk` ( - `id` INTEGER NOT NULL PRIMARY KEY, - `fk_id` INTEGER NOT NULL, - - FOREIGN KEY (`fk_id`) REFERENCES `fk_test_has_pk`(`id`) -) TYPE=InnoDB; - - -CREATE TABLE `keyboards` ( - `key_number` int(11) NOT NULL auto_increment primary key, - `name` varchar(50) default NULL -); diff --git a/tracks/vendor/rails/activerecord/test/fixtures/db_definitions/mysql2.drop.sql b/tracks/vendor/rails/activerecord/test/fixtures/db_definitions/mysql2.drop.sql deleted file mode 100644 index df00ffd7..00000000 --- a/tracks/vendor/rails/activerecord/test/fixtures/db_definitions/mysql2.drop.sql +++ /dev/null @@ -1,2 +0,0 @@ -DROP TABLE courses; - diff --git a/tracks/vendor/rails/activerecord/test/fixtures/db_definitions/mysql2.sql b/tracks/vendor/rails/activerecord/test/fixtures/db_definitions/mysql2.sql deleted file mode 100644 index 0bfd2e6f..00000000 --- a/tracks/vendor/rails/activerecord/test/fixtures/db_definitions/mysql2.sql +++ /dev/null @@ -1,5 +0,0 @@ -CREATE TABLE `courses` ( - `id` INTEGER NOT NULL PRIMARY KEY, - `name` VARCHAR(255) NOT NULL -) TYPE=InnoDB; - diff --git a/tracks/vendor/rails/activerecord/test/fixtures/db_definitions/oci.drop.sql b/tracks/vendor/rails/activerecord/test/fixtures/db_definitions/oci.drop.sql deleted file mode 100644 index 5a3a6637..00000000 --- a/tracks/vendor/rails/activerecord/test/fixtures/db_definitions/oci.drop.sql +++ /dev/null @@ -1,55 +0,0 @@ -drop table accounts; -drop table companies; -drop table topics; -drop synonym subjects; -drop table developers_projects; -drop table computers; -drop table developers; -drop table projects; -drop table customers; -drop table orders; -drop table movies; -drop table subscribers; -drop table booleantests; -drop table auto_id_tests; -drop table entrants; -drop table colnametests; -drop table mixins; -drop table people; -drop table binaries; -drop table comments; -drop table authors; -drop table tasks; -drop table categories_posts; -drop table categories; -drop table posts; -drop table fk_test_has_pk; -drop table fk_test_has_fk; -drop table keyboards; -drop sequence accounts_seq; -drop sequence companies_nonstd_seq; -drop sequence topics_seq; -drop sequence developers_seq; -drop sequence projects_seq; -drop sequence developers_projects_seq; -drop sequence customers_seq; -drop sequence orders_seq; -drop sequence movies_seq; -drop sequence subscribers_seq; -drop sequence booleantests_seq; -drop sequence auto_id_tests_seq; -drop sequence entrants_seq; -drop sequence colnametests_seq; -drop sequence mixins_seq; -drop sequence people_seq; -drop sequence binaries_seq; -drop sequence posts_seq; -drop sequence comments_seq; -drop sequence authors_seq; -drop sequence tasks_seq; -drop sequence computers_seq; -drop sequence categories_seq; -drop sequence categories_posts_seq; -drop sequence fk_test_has_pk_seq; -drop sequence fk_test_has_fk_seq; -drop sequence keyboards_seq; diff --git a/tracks/vendor/rails/activerecord/test/fixtures/db_definitions/oci.sql b/tracks/vendor/rails/activerecord/test/fixtures/db_definitions/oci.sql deleted file mode 100644 index 832396d0..00000000 --- a/tracks/vendor/rails/activerecord/test/fixtures/db_definitions/oci.sql +++ /dev/null @@ -1,271 +0,0 @@ -create table companies ( - id integer not null, - type varchar(50) default null, - ruby_type varchar(50) default null, - firm_id integer default null references companies initially deferred disable, - name varchar(50) default null, - client_of integer default null references companies initially deferred disable, - companies_count integer default 0, - rating integer default 1, - primary key (id) -); - --- non-standard sequence name used to test set_sequence_name --- -create sequence companies_nonstd_seq minvalue 10000; - -create table accounts ( - id integer not null, - firm_id integer default null references companies initially deferred disable, - credit_limit integer default null, - primary key (id) -); -create sequence accounts_seq minvalue 10000; - -create table topics ( - id integer not null, - title varchar(255) default null, - author_name varchar(255) default null, - author_email_address varchar(255) default null, - written_on timestamp default null, - bonus_time timestamp default null, - last_read timestamp default null, - content varchar(4000), - approved integer default 1, - replies_count integer default 0, - parent_id integer references topics initially deferred disable, - type varchar(50) default null, - primary key (id) -); --- try again for 8i -create table topics ( - id integer not null, - title varchar(255) default null, - author_name varchar(255) default null, - author_email_address varchar(255) default null, - written_on date default null, - bonus_time date default null, - last_read date default null, - content varchar(4000), - approved integer default 1, - replies_count integer default 0, - parent_id integer references topics initially deferred disable, - type varchar(50) default null, - primary key (id) -); -create sequence topics_seq minvalue 10000; - -create synonym subjects for topics; - -create table developers ( - id integer not null, - name varchar(100) default null, - salary integer default 70000, - created_at timestamp default null, - updated_at timestamp default null, - primary key (id) -); -create sequence developers_seq minvalue 10000; - -create table projects ( - id integer not null, - name varchar(100) default null, - type varchar(255) default null, - primary key (id) -); -create sequence projects_seq minvalue 10000; - -create table developers_projects ( - developer_id integer not null references developers initially deferred disable, - project_id integer not null references projects initially deferred disable, - joined_on timestamp default null, - access_level integer default 1 -); --- Try again for 8i -create table developers_projects ( - developer_id integer not null references developers initially deferred disable, - project_id integer not null references projects initially deferred disable, - joined_on date default null -); -create sequence developers_projects_seq minvalue 10000; - -create table orders ( - id integer not null, - name varchar(100) default null, - billing_customer_id integer default null, - shipping_customer_id integer default null, - primary key (id) -); -create sequence orders_seq minvalue 10000; - -create table customers ( - id integer not null, - name varchar(100) default null, - balance integer default 0, - address_street varchar(100) default null, - address_city varchar(100) default null, - address_country varchar(100) default null, - gps_location varchar(100) default null, - primary key (id) -); -create sequence customers_seq minvalue 10000; - -create table movies ( - movieid integer not null, - name varchar(100) default null, - primary key (movieid) -); -create sequence movies_seq minvalue 10000; - -create table subscribers ( - nick varchar(100) not null, - name varchar(100) default null, - primary key (nick) -); -create sequence subscribers_seq minvalue 10000; - -create table booleantests ( - id integer not null, - value integer default null, - primary key (id) -); -create sequence booleantests_seq minvalue 10000; - -create table auto_id_tests ( - auto_id integer not null, - value integer default null, - primary key (auto_id) -); -create sequence auto_id_tests_seq minvalue 10000; - -create table entrants ( - id integer not null primary key, - name varchar(255) not null, - course_id integer not null -); -create sequence entrants_seq minvalue 10000; - -create table colnametests ( - id integer not null, - references integer not null, - primary key (id) -); -create sequence colnametests_seq minvalue 10000; - -create table mixins ( - id integer not null, - parent_id integer default null references mixins initially deferred disable, - type varchar(40) default null, - pos integer default null, - lft integer default null, - rgt integer default null, - root_id integer default null, - created_at timestamp default null, - updated_at timestamp default null, - primary key (id) -); --- try again for 8i -create table mixins ( - id integer not null, - parent_id integer default null references mixins initially deferred disable, - type varchar(40) default null, - pos integer default null, - lft integer default null, - rgt integer default null, - root_id integer default null, - created_at date default null, - updated_at date default null, - primary key (id) -); -create sequence mixins_seq minvalue 10000; - -create table people ( - id integer not null, - first_name varchar(40) null, - lock_version integer default 0, - primary key (id) -); -create sequence people_seq minvalue 10000; - -create table binaries ( - id integer not null, - data blob null, - primary key (id) -); -create sequence binaries_seq minvalue 10000; - -create table computers ( - id integer not null primary key, - developer integer not null references developers initially deferred disable, - "extendedWarranty" integer not null -); -create sequence computers_seq minvalue 10000; - -create table posts ( - id integer not null primary key, - author_id integer default null, - title varchar(255) default null, - type varchar(255) default null, - body varchar(3000) default null -); -create sequence posts_seq minvalue 10000; - -create table comments ( - id integer not null primary key, - post_id integer default null, - type varchar(255) default null, - body varchar(3000) default null -); -create sequence comments_seq minvalue 10000; - -create table authors ( - id integer not null primary key, - name varchar(255) default null -); -create sequence authors_seq minvalue 10000; - -create table tasks ( - id integer not null primary key, - starting date default null, - ending date default null -); -create sequence tasks_seq minvalue 10000; - -create table categories ( - id integer not null primary key, - name varchar(255) default null, - type varchar(255) default null -); -create sequence categories_seq minvalue 10000; - -create table categories_posts ( - category_id integer not null references categories initially deferred disable, - post_id integer not null references posts initially deferred disable -); -create sequence categories_posts_seq minvalue 10000; - -create table fk_test_has_pk ( - id integer not null primary key -); -create sequence fk_test_has_pk_seq minvalue 10000; - -create table fk_test_has_fk ( - id integer not null primary key, - fk_id integer not null references fk_test_has_fk initially deferred disable -); -create sequence fk_test_has_fk_seq minvalue 10000; - -create table keyboards ( - key_number integer not null, - name varchar(50) default null -); -create sequence keyboards_seq minvalue 10000; - -create table test_oci_defaults ( - id integer not null primary key, - test_char char(1) default 'X' not null, - test_string varchar2(20) default 'hello' not null, - test_int integer default 3 not null -); -create sequence test_oci_defaults_seq minvalue 10000; - diff --git a/tracks/vendor/rails/activerecord/test/fixtures/db_definitions/oci2.drop.sql b/tracks/vendor/rails/activerecord/test/fixtures/db_definitions/oci2.drop.sql deleted file mode 100644 index abe7e55c..00000000 --- a/tracks/vendor/rails/activerecord/test/fixtures/db_definitions/oci2.drop.sql +++ /dev/null @@ -1,2 +0,0 @@ -drop table courses; -drop sequence courses_seq; diff --git a/tracks/vendor/rails/activerecord/test/fixtures/db_definitions/oci2.sql b/tracks/vendor/rails/activerecord/test/fixtures/db_definitions/oci2.sql deleted file mode 100644 index 3c171f4f..00000000 --- a/tracks/vendor/rails/activerecord/test/fixtures/db_definitions/oci2.sql +++ /dev/null @@ -1,6 +0,0 @@ -create table courses ( - id int not null primary key, - name varchar(255) not null -); - -create sequence courses_seq minvalue 10000; diff --git a/tracks/vendor/rails/activerecord/test/fixtures/db_definitions/postgresql.drop.sql b/tracks/vendor/rails/activerecord/test/fixtures/db_definitions/postgresql.drop.sql deleted file mode 100644 index 7919d13a..00000000 --- a/tracks/vendor/rails/activerecord/test/fixtures/db_definitions/postgresql.drop.sql +++ /dev/null @@ -1,30 +0,0 @@ -DROP TABLE accounts; -DROP TABLE companies; -DROP SEQUENCE companies_nonstd_seq; -DROP TABLE topics; -DROP TABLE developers; -DROP TABLE projects; -DROP TABLE developers_projects; -DROP TABLE customers; -DROP TABLE orders; -DROP TABLE movies; -DROP TABLE subscribers; -DROP TABLE booleantests; -DROP TABLE auto_id_tests; -DROP TABLE entrants; -DROP TABLE colnametests; -DROP TABLE mixins; -DROP TABLE people; -DROP TABLE binaries; -DROP TABLE computers; -DROP TABLE posts; -DROP TABLE comments; -DROP TABLE authors; -DROP TABLE tasks; -DROP TABLE categories; -DROP TABLE categories_posts; -DROP TABLE defaults; -DROP TABLE fk_test_has_fk; -DROP TABLE fk_test_has_pk; -DROP TABLE geometrics; -DROP TABLE keyboards; diff --git a/tracks/vendor/rails/activerecord/test/fixtures/db_definitions/postgresql.sql b/tracks/vendor/rails/activerecord/test/fixtures/db_definitions/postgresql.sql deleted file mode 100644 index cce4eec8..00000000 --- a/tracks/vendor/rails/activerecord/test/fixtures/db_definitions/postgresql.sql +++ /dev/null @@ -1,227 +0,0 @@ -CREATE SEQUENCE public.accounts_id_seq START 100; - -CREATE TABLE accounts ( - id integer DEFAULT nextval('public.accounts_id_seq'), - firm_id integer, - credit_limit integer, - PRIMARY KEY (id) -); - -CREATE SEQUENCE companies_nonstd_seq START 101; - -CREATE TABLE companies ( - id integer DEFAULT nextval('companies_nonstd_seq'), - "type" character varying(50), - "ruby_type" character varying(50), - firm_id integer, - name character varying(50), - client_of integer, - rating integer default 1, - PRIMARY KEY (id) -); - -CREATE TABLE developers_projects ( - developer_id integer NOT NULL, - project_id integer NOT NULL, - joined_on date, - access_level integer default 1 -); - -CREATE TABLE developers ( - id serial, - name character varying(100), - salary integer DEFAULT 70000, - created_at timestamp, - updated_at timestamp, - PRIMARY KEY (id) -); -SELECT setval('developers_id_seq', 100); - -CREATE TABLE projects ( - id serial, - name character varying(100), - type varchar(255), - PRIMARY KEY (id) -); -SELECT setval('projects_id_seq', 100); - -CREATE TABLE topics ( - id serial, - title character varying(255), - author_name character varying(255), - author_email_address character varying(255), - written_on timestamp without time zone, - bonus_time time, - last_read date, - content text, - approved boolean default true, - replies_count integer default 0, - parent_id integer, - "type" character varying(50), - PRIMARY KEY (id) -); -SELECT setval('topics_id_seq', 100); - -CREATE TABLE customers ( - id serial, - name character varying, - balance integer default 0, - address_street character varying, - address_city character varying, - address_country character varying, - gps_location character varying, - PRIMARY KEY (id) -); -SELECT setval('customers_id_seq', 100); - -CREATE TABLE orders ( - id serial, - name character varying, - billing_customer_id integer, - shipping_customer_id integer, - PRIMARY KEY (id) -); -SELECT setval('orders_id_seq', 100); - -CREATE TABLE movies ( - movieid serial, - name text, - PRIMARY KEY (movieid) -); - -CREATE TABLE subscribers ( - nick text NOT NULL, - name text, - PRIMARY KEY (nick) -); - -CREATE TABLE booleantests ( - id serial, - value boolean, - PRIMARY KEY (id) -); - -CREATE TABLE defaults ( - id serial, - modified_date date default CURRENT_DATE, - modified_date_function date default now(), - fixed_date date default '2004-01-01', - modified_time timestamp default CURRENT_TIMESTAMP, - modified_time_function timestamp default now(), - fixed_time timestamp default '2004-01-01 00:00:00.000000-00', - char1 char(1) default 'Y', - char2 character varying(50) default 'a varchar field', - char3 text default 'a text field' -); - -CREATE TABLE auto_id_tests ( - auto_id serial, - value integer, - PRIMARY KEY (auto_id) -); - -CREATE TABLE entrants ( - id serial, - name text, - course_id integer -); - -CREATE TABLE colnametests ( - id serial, - "references" integer NOT NULL -); - -CREATE TABLE mixins ( - id serial, - parent_id integer, - type character varying, - pos integer, - lft integer, - rgt integer, - root_id integer, - created_at timestamp, - updated_at timestamp, - PRIMARY KEY (id) -); - -CREATE TABLE people ( - id serial, - first_name text, - lock_version integer default 0, - PRIMARY KEY (id) -); - -CREATE TABLE binaries ( - id serial , - data bytea, - PRIMARY KEY (id) -); - -CREATE TABLE computers ( - id serial, - developer integer NOT NULL, - "extendedWarranty" integer NOT NULL -); - -CREATE TABLE posts ( - id serial, - author_id integer, - title varchar(255), - type varchar(255), - body text -); - -CREATE TABLE comments ( - id serial, - post_id integer, - type varchar(255), - body text -); - -CREATE TABLE authors ( - id serial, - name varchar(255) default NULL -); - -CREATE TABLE tasks ( - id serial, - starting timestamp, - ending timestamp, - PRIMARY KEY (id) -); - -CREATE TABLE categories ( - id serial, - name varchar(255), - type varchar(255) -); - -CREATE TABLE categories_posts ( - category_id integer NOT NULL, - post_id integer NOT NULL -); - -CREATE TABLE fk_test_has_pk ( - id INTEGER NOT NULL PRIMARY KEY -); - -CREATE TABLE fk_test_has_fk ( - id INTEGER NOT NULL PRIMARY KEY, - fk_id INTEGER NOT NULL REFERENCES fk_test_has_fk(id) -); - -CREATE TABLE geometrics ( - id serial primary key, - a_point point, - -- a_line line, (the line type is currently not implemented in postgresql) - a_line_segment lseg, - a_box box, - a_path path, - a_polygon polygon, - a_circle circle -); - -CREATE TABLE keyboards ( - key_number serial primary key, - "name" character varying(50) -); diff --git a/tracks/vendor/rails/activerecord/test/fixtures/db_definitions/postgresql2.drop.sql b/tracks/vendor/rails/activerecord/test/fixtures/db_definitions/postgresql2.drop.sql deleted file mode 100644 index df00ffd7..00000000 --- a/tracks/vendor/rails/activerecord/test/fixtures/db_definitions/postgresql2.drop.sql +++ /dev/null @@ -1,2 +0,0 @@ -DROP TABLE courses; - diff --git a/tracks/vendor/rails/activerecord/test/fixtures/db_definitions/postgresql2.sql b/tracks/vendor/rails/activerecord/test/fixtures/db_definitions/postgresql2.sql deleted file mode 100644 index c0d7f79b..00000000 --- a/tracks/vendor/rails/activerecord/test/fixtures/db_definitions/postgresql2.sql +++ /dev/null @@ -1,5 +0,0 @@ -CREATE TABLE courses ( - id serial, - name text -); - diff --git a/tracks/vendor/rails/activerecord/test/fixtures/db_definitions/sqlite.drop.sql b/tracks/vendor/rails/activerecord/test/fixtures/db_definitions/sqlite.drop.sql deleted file mode 100644 index 8a37e2de..00000000 --- a/tracks/vendor/rails/activerecord/test/fixtures/db_definitions/sqlite.drop.sql +++ /dev/null @@ -1,27 +0,0 @@ -DROP TABLE accounts; -DROP TABLE companies; -DROP TABLE topics; -DROP TABLE developers; -DROP TABLE projects; -DROP TABLE developers_projects; -DROP TABLE customers; -DROP TABLE orders; -DROP TABLE movies; -DROP TABLE subscribers; -DROP TABLE booleantests; -DROP TABLE auto_id_tests; -DROP TABLE entrants; -DROP TABLE colnametests; -DROP TABLE mixins; -DROP TABLE people; -DROP TABLE binaries; -DROP TABLE computers; -DROP TABLE tasks; -DROP TABLE posts; -DROP TABLE comments; -DROP TABLE authors; -DROP TABLE categories; -DROP TABLE categories_posts; -DROP TABLE fk_test_has_fk; -DROP TABLE fk_test_has_pk; -DROP TABLE keyboards; diff --git a/tracks/vendor/rails/activerecord/test/fixtures/db_definitions/sqlite.sql b/tracks/vendor/rails/activerecord/test/fixtures/db_definitions/sqlite.sql deleted file mode 100644 index 2e643f59..00000000 --- a/tracks/vendor/rails/activerecord/test/fixtures/db_definitions/sqlite.sql +++ /dev/null @@ -1,183 +0,0 @@ -CREATE TABLE 'accounts' ( - 'id' INTEGER PRIMARY KEY NOT NULL, - 'firm_id' INTEGER DEFAULT NULL, - 'credit_limit' INTEGER DEFAULT NULL -); - -CREATE TABLE 'companies' ( - 'id' INTEGER PRIMARY KEY NOT NULL, - 'type' VARCHAR(255) DEFAULT NULL, - 'ruby_type' VARCHAR(255) DEFAULT NULL, - 'firm_id' INTEGER DEFAULT NULL, - 'name' TEXT DEFAULT NULL, - 'client_of' INTEGER DEFAULT NULL, - 'rating' INTEGER DEFAULT 1 -); - - -CREATE TABLE 'topics' ( - 'id' INTEGER PRIMARY KEY NOT NULL, - 'title' VARCHAR(255) DEFAULT NULL, - 'author_name' VARCHAR(255) DEFAULT NULL, - 'author_email_address' VARCHAR(255) DEFAULT NULL, - 'written_on' DATETIME DEFAULT NULL, - 'bonus_time' TIME DEFAULT NULL, - 'last_read' DATE DEFAULT NULL, - 'content' TEXT, - 'approved' boolean DEFAULT 't', - 'replies_count' INTEGER DEFAULT 0, - 'parent_id' INTEGER DEFAULT NULL, - 'type' VARCHAR(255) DEFAULT NULL -); - -CREATE TABLE 'developers' ( - 'id' INTEGER PRIMARY KEY NOT NULL, - 'name' TEXT DEFAULT NULL, - 'salary' INTEGER DEFAULT 70000, - 'created_at' DATETIME DEFAULT NULL, - 'updated_at' DATETIME DEFAULT NULL -); - -CREATE TABLE 'projects' ( - 'id' INTEGER PRIMARY KEY NOT NULL, - 'name' TEXT DEFAULT NULL, - 'type' VARCHAR(255) DEFAULT NULL -); - -CREATE TABLE 'developers_projects' ( - 'developer_id' INTEGER NOT NULL, - 'project_id' INTEGER NOT NULL, - 'joined_on' DATE DEFAULT NULL, - 'access_level' INTEGER DEFAULT 1 -); - - -CREATE TABLE 'orders' ( - 'id' INTEGER PRIMARY KEY NOT NULL, - 'name' VARCHAR(255) DEFAULT NULL, - 'billing_customer_id' INTEGER DEFAULT NULL, - 'shipping_customer_id' INTEGER DEFAULT NULL -); - -CREATE TABLE 'customers' ( - 'id' INTEGER PRIMARY KEY NOT NULL, - 'name' VARCHAR(255) DEFAULT NULL, - 'balance' INTEGER DEFAULT 0, - 'address_street' TEXT DEFAULT NULL, - 'address_city' TEXT DEFAULT NULL, - 'address_country' TEXT DEFAULT NULL, - 'gps_location' TEXT DEFAULT NULL -); - -CREATE TABLE 'movies' ( - 'movieid' INTEGER PRIMARY KEY NOT NULL, - 'name' VARCHAR(255) DEFAULT NULL -); - -CREATE TABLE subscribers ( - 'nick' VARCHAR(255) PRIMARY KEY NOT NULL, - 'name' VARCHAR(255) DEFAULT NULL -); - -CREATE TABLE 'booleantests' ( - 'id' INTEGER PRIMARY KEY NOT NULL, - 'value' INTEGER DEFAULT NULL -); - -CREATE TABLE 'auto_id_tests' ( - 'auto_id' INTEGER PRIMARY KEY NOT NULL, - 'value' INTEGER DEFAULT NULL -); - -CREATE TABLE 'entrants' ( - 'id' INTEGER NOT NULL PRIMARY KEY, - 'name' VARCHAR(255) NOT NULL, - 'course_id' INTEGER NOT NULL -); - -CREATE TABLE 'colnametests' ( - 'id' INTEGER NOT NULL PRIMARY KEY, - 'references' INTEGER NOT NULL -); - -CREATE TABLE 'mixins' ( - 'id' INTEGER NOT NULL PRIMARY KEY, - 'parent_id' INTEGER DEFAULT NULL, - 'type' VARCHAR(40) DEFAULT NULL, - 'pos' INTEGER DEFAULT NULL, - 'lft' INTEGER DEFAULT NULL, - 'rgt' INTEGER DEFAULT NULL, - 'root_id' INTEGER DEFAULT NULL, - 'created_at' DATETIME DEFAULT NULL, - 'updated_at' DATETIME DEFAULT NULL -); - -CREATE TABLE 'people' ( - 'id' INTEGER NOT NULL PRIMARY KEY, - 'first_name' VARCHAR(40) DEFAULT NULL, - 'lock_version' INTEGER NOT NULL DEFAULT 0 -); - -CREATE TABLE 'binaries' ( - 'id' INTEGER NOT NULL PRIMARY KEY, - 'data' BLOB DEFAULT NULL -); - -CREATE TABLE 'computers' ( - 'id' INTEGER NOT NULL PRIMARY KEY, - 'developer' INTEGER NOT NULL, - 'extendedWarranty' INTEGER NOT NULL -); - -CREATE TABLE 'posts' ( - 'id' INTEGER NOT NULL PRIMARY KEY, - 'author_id' INTEGER, - 'title' VARCHAR(255) NOT NULL, - 'type' VARCHAR(255) NOT NULL, - 'body' TEXT NOT NULL -); - -CREATE TABLE 'comments' ( - 'id' INTEGER NOT NULL PRIMARY KEY, - 'post_id' INTEGER NOT NULL, - 'type' VARCHAR(255) NOT NULL, - 'body' TEXT NOT NULL -); - -CREATE TABLE 'authors' ( - 'id' INTEGER NOT NULL PRIMARY KEY, - 'name' VARCHAR(255) NOT NULL -); - -CREATE TABLE 'tasks' ( - 'id' INTEGER NOT NULL PRIMARY KEY, - 'starting' DATETIME DEFAULT NULL, - 'ending' DATETIME DEFAULT NULL -); - -CREATE TABLE 'categories' ( - 'id' INTEGER NOT NULL PRIMARY KEY, - 'name' VARCHAR(255) NOT NULL, - 'type' VARCHAR(255) DEFAULT NULL -); - -CREATE TABLE 'categories_posts' ( - 'category_id' INTEGER NOT NULL, - 'post_id' INTEGER NOT NULL -); - -CREATE TABLE 'fk_test_has_pk' ( - 'id' INTEGER NOT NULL PRIMARY KEY -); - -CREATE TABLE 'fk_test_has_fk' ( - 'id' INTEGER NOT NULL PRIMARY KEY, - 'fk_id' INTEGER NOT NULL, - - FOREIGN KEY ('fk_id') REFERENCES 'fk_test_has_pk'('id') -); - -CREATE TABLE 'keyboards' ( - 'key_number' INTEGER PRIMARY KEY NOT NULL, - 'name' VARCHAR(255) DEFAULT NULL -); diff --git a/tracks/vendor/rails/activerecord/test/fixtures/db_definitions/sqlite2.drop.sql b/tracks/vendor/rails/activerecord/test/fixtures/db_definitions/sqlite2.drop.sql deleted file mode 100644 index df00ffd7..00000000 --- a/tracks/vendor/rails/activerecord/test/fixtures/db_definitions/sqlite2.drop.sql +++ /dev/null @@ -1,2 +0,0 @@ -DROP TABLE courses; - diff --git a/tracks/vendor/rails/activerecord/test/fixtures/db_definitions/sqlite2.sql b/tracks/vendor/rails/activerecord/test/fixtures/db_definitions/sqlite2.sql deleted file mode 100644 index 5c0d231b..00000000 --- a/tracks/vendor/rails/activerecord/test/fixtures/db_definitions/sqlite2.sql +++ /dev/null @@ -1,5 +0,0 @@ -CREATE TABLE 'courses' ( - 'id' INTEGER NOT NULL PRIMARY KEY, - 'name' VARCHAR(255) NOT NULL -); - diff --git a/tracks/vendor/rails/activerecord/test/fixtures/db_definitions/sqlserver.drop.sql b/tracks/vendor/rails/activerecord/test/fixtures/db_definitions/sqlserver.drop.sql deleted file mode 100644 index edb9aa6e..00000000 --- a/tracks/vendor/rails/activerecord/test/fixtures/db_definitions/sqlserver.drop.sql +++ /dev/null @@ -1,27 +0,0 @@ -DROP TABLE accounts; -DROP TABLE companies; -DROP TABLE topics; -DROP TABLE developers; -DROP TABLE projects; -DROP TABLE developers_projects; -DROP TABLE customers; -DROP TABLE orders; -DROP TABLE movies; -DROP TABLE subscribers; -DROP TABLE booleantests; -DROP TABLE auto_id_tests; -DROP TABLE entrants; -DROP TABLE colnametests; -DROP TABLE mixins; -DROP TABLE people; -DROP TABLE binaries; -DROP TABLE computers; -DROP TABLE posts; -DROP TABLE comments; -DROP TABLE authors; -DROP TABLE tasks; -DROP TABLE categories; -DROP TABLE categories_posts; -DROP TABLE fk_test_has_fk; -DROP TABLE fk_test_has_pk; -DROP TABLE keyboards; diff --git a/tracks/vendor/rails/activerecord/test/fixtures/db_definitions/sqlserver.sql b/tracks/vendor/rails/activerecord/test/fixtures/db_definitions/sqlserver.sql deleted file mode 100644 index e2736409..00000000 --- a/tracks/vendor/rails/activerecord/test/fixtures/db_definitions/sqlserver.sql +++ /dev/null @@ -1,183 +0,0 @@ -CREATE TABLE accounts ( - id int NOT NULL IDENTITY(1, 1) PRIMARY KEY, - firm_id int default NULL, - credit_limit int default NULL -); - -CREATE TABLE companies ( - id int NOT NULL IDENTITY(1, 1) PRIMARY KEY, - type varchar(50) default NULL, - ruby_type varchar(50) default NULL, - firm_id int default NULL, - name varchar(50) default NULL, - client_of int default NULL, - rating int default 1 -); - -CREATE TABLE topics ( - id int NOT NULL IDENTITY(1, 1) PRIMARY KEY, - title varchar(255) default NULL, - author_name varchar(255) default NULL, - author_email_address varchar(255) default NULL, - written_on datetime default NULL, - bonus_time datetime default NULL, - last_read datetime default NULL, - content varchar(255) default NULL, - approved tinyint default 1, - replies_count int default 0, - parent_id int default NULL, - type varchar(50) default NULL -); - -CREATE TABLE developers ( - id int NOT NULL IDENTITY(1, 1) PRIMARY KEY, - name varchar(100) default NULL, - salary int default 70000, - created_at datetime default NULL, - updated_at datetime default NULL -); - -CREATE TABLE projects ( - id int NOT NULL IDENTITY(1, 1) PRIMARY KEY, - name varchar(100) default NULL, - type varchar(255) default NULL -); - -CREATE TABLE developers_projects ( - developer_id int NOT NULL, - project_id int NOT NULL, - joined_on datetime default NULL, - access_level int default 1 -); - -CREATE TABLE orders ( - id int NOT NULL IDENTITY(1, 1) PRIMARY KEY, - name varchar(100) default NULL, - billing_customer_id int default NULL, - shipping_customer_id int default NULL -); - - -CREATE TABLE customers ( - id int NOT NULL IDENTITY(1, 1) PRIMARY KEY, - name varchar(100) default NULL, - balance int default 0, - address_street varchar(100) default NULL, - address_city varchar(100) default NULL, - address_country varchar(100) default NULL, - gps_location varchar(100) default NULL -); - -CREATE TABLE movies ( - movieid int NOT NULL IDENTITY(1, 1) PRIMARY KEY, - name varchar(100) default NULL -); - -CREATE TABLE subscribers ( - nick varchar(100) NOT NULL PRIMARY KEY, - name varchar(100) default NULL -); - -CREATE TABLE booleantests ( - id int NOT NULL IDENTITY(1, 1) PRIMARY KEY, - value bit default NULL -); - -CREATE TABLE auto_id_tests ( - auto_id int NOT NULL IDENTITY(1, 1) PRIMARY KEY, - value int default NULL -); - -CREATE TABLE entrants ( - id int NOT NULL PRIMARY KEY, - name varchar(255) NOT NULL, - course_id int NOT NULL -); - -CREATE TABLE colnametests ( - id int NOT NULL IDENTITY(1, 1) PRIMARY KEY, - [references] int NOT NULL -); - -CREATE TABLE mixins ( - id int NOT NULL IDENTITY(1, 1) PRIMARY KEY, - parent_id int default NULL, - pos int default NULL, - created_at datetime default NULL, - updated_at datetime default NULL, - lft int default NULL, - rgt int default NULL, - root_id int default NULL, - type varchar(40) default NULL -); - -CREATE TABLE people ( - id int NOT NULL IDENTITY(1, 1), - first_name varchar(40) NULL, - lock_version int default 0, - PRIMARY KEY (id) -); - -CREATE TABLE binaries ( - id int NOT NULL IDENTITY(1, 1) PRIMARY KEY, - data image NULL -); - -CREATE TABLE computers ( - id int NOT NULL IDENTITY(1, 1) PRIMARY KEY, - developer int NOT NULL, - extendedWarranty int NOT NULL -); - -CREATE TABLE posts ( - id int NOT NULL IDENTITY(1, 1) PRIMARY KEY, - author_id int default NULL, - title varchar(255) default NULL, - type varchar(255) default NULL, - body text default NULL -); - -CREATE TABLE comments ( - id int NOT NULL IDENTITY(1, 1) PRIMARY KEY, - post_id int default NULL, - type varchar(255) default NULL, - body text default NULL -); - -CREATE TABLE authors ( - id int NOT NULL IDENTITY(1, 1) PRIMARY KEY, - name varchar(255) default NULL -); - -CREATE TABLE tasks ( - id int NOT NULL IDENTITY(1, 1) PRIMARY KEY, - starting datetime default NULL, - ending datetime default NULL -); - -CREATE TABLE categories ( - id int NOT NULL IDENTITY(1, 1) PRIMARY KEY, - name varchar(255), - type varchar(255) default NULL -); - -CREATE TABLE categories_posts ( - category_id int NOT NULL, - post_id int NOT NULL -); - -CREATE TABLE fk_test_has_pk ( - id INTEGER NOT NULL PRIMARY KEY -); - -CREATE TABLE fk_test_has_fk ( - id INTEGER NOT NULL PRIMARY KEY, - fk_id INTEGER NOT NULL, - - FOREIGN KEY (fk_id) REFERENCES fk_test_has_pk(id) -); - -CREATE TABLE keyboards ( - key_number int NOT NULL IDENTITY(1, 1) PRIMARY KEY, - name varchar(50) default NULL -); diff --git a/tracks/vendor/rails/activerecord/test/fixtures/db_definitions/sqlserver2.drop.sql b/tracks/vendor/rails/activerecord/test/fixtures/db_definitions/sqlserver2.drop.sql deleted file mode 100644 index df00ffd7..00000000 --- a/tracks/vendor/rails/activerecord/test/fixtures/db_definitions/sqlserver2.drop.sql +++ /dev/null @@ -1,2 +0,0 @@ -DROP TABLE courses; - diff --git a/tracks/vendor/rails/activerecord/test/fixtures/db_definitions/sqlserver2.sql b/tracks/vendor/rails/activerecord/test/fixtures/db_definitions/sqlserver2.sql deleted file mode 100644 index 9198cf5f..00000000 --- a/tracks/vendor/rails/activerecord/test/fixtures/db_definitions/sqlserver2.sql +++ /dev/null @@ -1,5 +0,0 @@ -CREATE TABLE courses ( - id int NOT NULL PRIMARY KEY, - name varchar(255) NOT NULL -); - diff --git a/tracks/vendor/rails/activerecord/test/fixtures/default.rb b/tracks/vendor/rails/activerecord/test/fixtures/default.rb deleted file mode 100644 index 887e9cc9..00000000 --- a/tracks/vendor/rails/activerecord/test/fixtures/default.rb +++ /dev/null @@ -1,2 +0,0 @@ -class Default < ActiveRecord::Base -end diff --git a/tracks/vendor/rails/activerecord/test/fixtures/developer.rb b/tracks/vendor/rails/activerecord/test/fixtures/developer.rb deleted file mode 100644 index 29555d92..00000000 --- a/tracks/vendor/rails/activerecord/test/fixtures/developer.rb +++ /dev/null @@ -1,40 +0,0 @@ -module DeveloperProjectsAssociationExtension - def find_most_recent - find(:first, :order => "id DESC") - end -end - -class Developer < ActiveRecord::Base - has_and_belongs_to_many :projects do - def find_most_recent - find(:first, :order => "id DESC") - end - end - - has_and_belongs_to_many :projects_extended_by_name, - :class_name => "Project", - :join_table => "developers_projects", - :association_foreign_key => "project_id", - :extend => DeveloperProjectsAssociationExtension - - has_and_belongs_to_many :special_projects, :join_table => 'developers_projects', :association_foreign_key => 'project_id' - - validates_inclusion_of :salary, :in => 50000..200000 - validates_length_of :name, :within => 3..20 -end - -DeveloperSalary = Struct.new(:amount) -class DeveloperWithAggregate < ActiveRecord::Base - self.table_name = 'developers' - composed_of :salary, :class_name => 'DeveloperSalary', :mapping => [%w(salary amount)] -end - -class DeveloperWithBeforeDestroyRaise < ActiveRecord::Base - self.table_name = 'developers' - has_and_belongs_to_many :projects, :join_table => 'developers_projects', :foreign_key => 'developer_id' - before_destroy :raise_if_projects_empty! - - def raise_if_projects_empty! - raise if projects.empty? - end -end diff --git a/tracks/vendor/rails/activerecord/test/fixtures/developers.yml b/tracks/vendor/rails/activerecord/test/fixtures/developers.yml deleted file mode 100644 index fc33af99..00000000 --- a/tracks/vendor/rails/activerecord/test/fixtures/developers.yml +++ /dev/null @@ -1,16 +0,0 @@ -david: - id: 1 - name: David - salary: 80000 - -jamis: - id: 2 - name: Jamis - salary: 150000 - -<% for digit in 3..10 %> -dev_<%= digit %>: - id: <%= digit %> - name: fixture_<%= digit %> - salary: 100000 -<% end %> \ No newline at end of file diff --git a/tracks/vendor/rails/activerecord/test/fixtures/developers_projects.yml b/tracks/vendor/rails/activerecord/test/fixtures/developers_projects.yml deleted file mode 100644 index b1194a6f..00000000 --- a/tracks/vendor/rails/activerecord/test/fixtures/developers_projects.yml +++ /dev/null @@ -1,13 +0,0 @@ -david_action_controller: - developer_id: 1 - project_id: 2 - joined_on: 2004-10-10 - -david_active_record: - developer_id: 1 - project_id: 1 - joined_on: 2004-10-10 - -jamis_active_record: - developer_id: 2 - project_id: 1 diff --git a/tracks/vendor/rails/activerecord/test/fixtures/developers_projects/david_action_controller b/tracks/vendor/rails/activerecord/test/fixtures/developers_projects/david_action_controller deleted file mode 100644 index e6e9d0e5..00000000 --- a/tracks/vendor/rails/activerecord/test/fixtures/developers_projects/david_action_controller +++ /dev/null @@ -1,3 +0,0 @@ -developer_id => 1 -project_id => 2 -joined_on => 2004-10-10 \ No newline at end of file diff --git a/tracks/vendor/rails/activerecord/test/fixtures/developers_projects/david_active_record b/tracks/vendor/rails/activerecord/test/fixtures/developers_projects/david_active_record deleted file mode 100644 index 2ef474c1..00000000 --- a/tracks/vendor/rails/activerecord/test/fixtures/developers_projects/david_active_record +++ /dev/null @@ -1,3 +0,0 @@ -developer_id => 1 -project_id => 1 -joined_on => 2004-10-10 \ No newline at end of file diff --git a/tracks/vendor/rails/activerecord/test/fixtures/developers_projects/jamis_active_record b/tracks/vendor/rails/activerecord/test/fixtures/developers_projects/jamis_active_record deleted file mode 100644 index 91beb807..00000000 --- a/tracks/vendor/rails/activerecord/test/fixtures/developers_projects/jamis_active_record +++ /dev/null @@ -1,2 +0,0 @@ -developer_id => 2 -project_id => 1 \ No newline at end of file diff --git a/tracks/vendor/rails/activerecord/test/fixtures/entrant.rb b/tracks/vendor/rails/activerecord/test/fixtures/entrant.rb deleted file mode 100644 index 4682ce48..00000000 --- a/tracks/vendor/rails/activerecord/test/fixtures/entrant.rb +++ /dev/null @@ -1,3 +0,0 @@ -class Entrant < ActiveRecord::Base - belongs_to :course -end diff --git a/tracks/vendor/rails/activerecord/test/fixtures/entrants.yml b/tracks/vendor/rails/activerecord/test/fixtures/entrants.yml deleted file mode 100644 index 86f0108e..00000000 --- a/tracks/vendor/rails/activerecord/test/fixtures/entrants.yml +++ /dev/null @@ -1,14 +0,0 @@ -first: - id: 1 - course_id: 1 - name: Ruby Developer - -second: - id: 2 - course_id: 1 - name: Ruby Guru - -third: - id: 3 - course_id: 2 - name: Java Lover diff --git a/tracks/vendor/rails/activerecord/test/fixtures/fixture_database.sqlite b/tracks/vendor/rails/activerecord/test/fixtures/fixture_database.sqlite deleted file mode 100644 index 67321a17..00000000 Binary files a/tracks/vendor/rails/activerecord/test/fixtures/fixture_database.sqlite and /dev/null differ diff --git a/tracks/vendor/rails/activerecord/test/fixtures/fixture_database.sqlite3 b/tracks/vendor/rails/activerecord/test/fixtures/fixture_database.sqlite3 deleted file mode 100644 index eefbb826..00000000 Binary files a/tracks/vendor/rails/activerecord/test/fixtures/fixture_database.sqlite3 and /dev/null differ diff --git a/tracks/vendor/rails/activerecord/test/fixtures/fixture_database_2.sqlite b/tracks/vendor/rails/activerecord/test/fixtures/fixture_database_2.sqlite deleted file mode 100644 index 450f5891..00000000 Binary files a/tracks/vendor/rails/activerecord/test/fixtures/fixture_database_2.sqlite and /dev/null differ diff --git a/tracks/vendor/rails/activerecord/test/fixtures/fixture_database_2.sqlite3 b/tracks/vendor/rails/activerecord/test/fixtures/fixture_database_2.sqlite3 deleted file mode 100644 index 1cbbd446..00000000 Binary files a/tracks/vendor/rails/activerecord/test/fixtures/fixture_database_2.sqlite3 and /dev/null differ diff --git a/tracks/vendor/rails/activerecord/test/fixtures/fk_test_has_fk.yml b/tracks/vendor/rails/activerecord/test/fixtures/fk_test_has_fk.yml deleted file mode 100644 index 67d914e1..00000000 --- a/tracks/vendor/rails/activerecord/test/fixtures/fk_test_has_fk.yml +++ /dev/null @@ -1,3 +0,0 @@ -first: - id: 1 - fk_id: 1 diff --git a/tracks/vendor/rails/activerecord/test/fixtures/fk_test_has_pk.yml b/tracks/vendor/rails/activerecord/test/fixtures/fk_test_has_pk.yml deleted file mode 100644 index c9395218..00000000 --- a/tracks/vendor/rails/activerecord/test/fixtures/fk_test_has_pk.yml +++ /dev/null @@ -1,2 +0,0 @@ -first: - id: 1 \ No newline at end of file diff --git a/tracks/vendor/rails/activerecord/test/fixtures/flowers.jpg b/tracks/vendor/rails/activerecord/test/fixtures/flowers.jpg deleted file mode 100644 index 3687b097..00000000 Binary files a/tracks/vendor/rails/activerecord/test/fixtures/flowers.jpg and /dev/null differ diff --git a/tracks/vendor/rails/activerecord/test/fixtures/keyboard.rb b/tracks/vendor/rails/activerecord/test/fixtures/keyboard.rb deleted file mode 100644 index 32a4a7fa..00000000 --- a/tracks/vendor/rails/activerecord/test/fixtures/keyboard.rb +++ /dev/null @@ -1,3 +0,0 @@ -class Keyboard < ActiveRecord::Base - set_primary_key 'key_number' -end diff --git a/tracks/vendor/rails/activerecord/test/fixtures/migrations/1_people_have_last_names.rb b/tracks/vendor/rails/activerecord/test/fixtures/migrations/1_people_have_last_names.rb deleted file mode 100644 index 009729b3..00000000 --- a/tracks/vendor/rails/activerecord/test/fixtures/migrations/1_people_have_last_names.rb +++ /dev/null @@ -1,9 +0,0 @@ -class PeopleHaveLastNames < ActiveRecord::Migration - def self.up - add_column "people", "last_name", :string - end - - def self.down - remove_column "people", "last_name" - end -end \ No newline at end of file diff --git a/tracks/vendor/rails/activerecord/test/fixtures/migrations/2_we_need_reminders.rb b/tracks/vendor/rails/activerecord/test/fixtures/migrations/2_we_need_reminders.rb deleted file mode 100644 index ac5918f0..00000000 --- a/tracks/vendor/rails/activerecord/test/fixtures/migrations/2_we_need_reminders.rb +++ /dev/null @@ -1,12 +0,0 @@ -class WeNeedReminders < ActiveRecord::Migration - def self.up - create_table("reminders") do |t| - t.column :content, :text - t.column :remind_at, :datetime - end - end - - def self.down - drop_table "reminders" - end -end \ No newline at end of file diff --git a/tracks/vendor/rails/activerecord/test/fixtures/migrations/3_innocent_jointable.rb b/tracks/vendor/rails/activerecord/test/fixtures/migrations/3_innocent_jointable.rb deleted file mode 100644 index 21c9ca53..00000000 --- a/tracks/vendor/rails/activerecord/test/fixtures/migrations/3_innocent_jointable.rb +++ /dev/null @@ -1,12 +0,0 @@ -class InnocentJointable < ActiveRecord::Migration - def self.up - create_table("people_reminders", :id => false) do |t| - t.column :reminder_id, :integer - t.column :person_id, :integer - end - end - - def self.down - drop_table "people_reminders" - end -end \ No newline at end of file diff --git a/tracks/vendor/rails/activerecord/test/fixtures/migrations_with_duplicate/1_people_have_last_names.rb b/tracks/vendor/rails/activerecord/test/fixtures/migrations_with_duplicate/1_people_have_last_names.rb deleted file mode 100644 index 009729b3..00000000 --- a/tracks/vendor/rails/activerecord/test/fixtures/migrations_with_duplicate/1_people_have_last_names.rb +++ /dev/null @@ -1,9 +0,0 @@ -class PeopleHaveLastNames < ActiveRecord::Migration - def self.up - add_column "people", "last_name", :string - end - - def self.down - remove_column "people", "last_name" - end -end \ No newline at end of file diff --git a/tracks/vendor/rails/activerecord/test/fixtures/migrations_with_duplicate/2_we_need_reminders.rb b/tracks/vendor/rails/activerecord/test/fixtures/migrations_with_duplicate/2_we_need_reminders.rb deleted file mode 100644 index ac5918f0..00000000 --- a/tracks/vendor/rails/activerecord/test/fixtures/migrations_with_duplicate/2_we_need_reminders.rb +++ /dev/null @@ -1,12 +0,0 @@ -class WeNeedReminders < ActiveRecord::Migration - def self.up - create_table("reminders") do |t| - t.column :content, :text - t.column :remind_at, :datetime - end - end - - def self.down - drop_table "reminders" - end -end \ No newline at end of file diff --git a/tracks/vendor/rails/activerecord/test/fixtures/migrations_with_duplicate/3_foo.rb b/tracks/vendor/rails/activerecord/test/fixtures/migrations_with_duplicate/3_foo.rb deleted file mode 100644 index 916fe580..00000000 --- a/tracks/vendor/rails/activerecord/test/fixtures/migrations_with_duplicate/3_foo.rb +++ /dev/null @@ -1,7 +0,0 @@ -class Foo < ActiveRecord::Migration - def self.up - end - - def self.down - end -end \ No newline at end of file diff --git a/tracks/vendor/rails/activerecord/test/fixtures/migrations_with_duplicate/3_innocent_jointable.rb b/tracks/vendor/rails/activerecord/test/fixtures/migrations_with_duplicate/3_innocent_jointable.rb deleted file mode 100644 index 21c9ca53..00000000 --- a/tracks/vendor/rails/activerecord/test/fixtures/migrations_with_duplicate/3_innocent_jointable.rb +++ /dev/null @@ -1,12 +0,0 @@ -class InnocentJointable < ActiveRecord::Migration - def self.up - create_table("people_reminders", :id => false) do |t| - t.column :reminder_id, :integer - t.column :person_id, :integer - end - end - - def self.down - drop_table "people_reminders" - end -end \ No newline at end of file diff --git a/tracks/vendor/rails/activerecord/test/fixtures/mixin.rb b/tracks/vendor/rails/activerecord/test/fixtures/mixin.rb deleted file mode 100644 index 0411c0d8..00000000 --- a/tracks/vendor/rails/activerecord/test/fixtures/mixin.rb +++ /dev/null @@ -1,48 +0,0 @@ -class Mixin < ActiveRecord::Base - -end - -class TreeMixin < Mixin - acts_as_tree :foreign_key => "parent_id", :order => "id" -end - -class TreeMixinWithoutOrder < Mixin - acts_as_tree :foreign_key => "parent_id" -end - -class ListMixin < Mixin - acts_as_list :column => "pos", :scope => :parent - - def self.table_name() "mixins" end -end - -class ListMixinSub1 < ListMixin -end - -class ListMixinSub2 < ListMixin -end - - -class ListWithStringScopeMixin < ActiveRecord::Base - acts_as_list :column => "pos", :scope => 'parent_id = #{parent_id}' - - def self.table_name() "mixins" end -end - -class NestedSet < Mixin - acts_as_nested_set :scope => "ROOT_ID IS NULL" - - def self.table_name() "mixins" end -end - -class NestedSetWithStringScope < Mixin - acts_as_nested_set :scope => 'root_id = #{root_id}' - - def self.table_name() "mixins" end -end - -class NestedSetWithSymbolScope < Mixin - acts_as_nested_set :scope => :root - - def self.table_name() "mixins" end -end diff --git a/tracks/vendor/rails/activerecord/test/fixtures/mixins.yml b/tracks/vendor/rails/activerecord/test/fixtures/mixins.yml deleted file mode 100644 index cb21349c..00000000 --- a/tracks/vendor/rails/activerecord/test/fixtures/mixins.yml +++ /dev/null @@ -1,89 +0,0 @@ -# tree mixins -tree_1: - id: 1001 - type: TreeMixin - parent_id: - -tree_2: - id: 1002 - type: TreeMixin - parent_id: 1001 - -tree_3: - id: 1003 - type: TreeMixin - parent_id: 1002 - -tree_4: - id: 1004 - type: TreeMixin - parent_id: 1001 - -tree2_1: - id: 1005 - type: TreeMixin - parent_id: - -tree3_1: - id: 1006 - type: TreeMixin - parent_id: - -tree_without_order_1: - id: 1101 - type: TreeMixinWithoutOrder - parent_id: - -tree_without_order_2: - id: 1100 - type: TreeMixinWithoutOrder - parent_id: - -# List mixins - -<% (1..4).each do |counter| %> -list_<%= counter %>: - id: <%= counter+1006 %> - pos: <%= counter %> - type: ListMixin - parent_id: 5 -<% end %> - -# Nested set mixins - -<% (1..10).each do |counter| %> -set_<%= counter %>: - id: <%= counter+3000 %> - type: NestedSet -<% end %> - -# Big old set -<% -[[4001, 0, 1, 20], - [4002, 4001, 2, 7], - [4003, 4002, 3, 4], - [4004, 4002, 5, 6], - [4005, 4001, 8, 13], - [4006, 4005, 9, 10], - [4007, 4005, 11, 12], - [4008, 4001, 14, 19], - [4009, 4008, 15, 16], - [4010, 4008, 17, 18]].each do |set| %> -tree_<%= set[0] %>: - id: <%= set[0]%> - parent_id: <%= set[1]%> - type: NestedSetWithStringScope - lft: <%= set[2]%> - rgt: <%= set[3]%> - root_id: 42 - -<% end %> - -# subclasses of list items -<% (1..4).each do |i| %> -list_sub_<%= i %>: - id: <%= i + 5000 %> - pos: <%= i %> - parent_id: 5000 - type: <%= (i % 2 == 1) ? ListMixinSub1 : ListMixinSub2 %> -<% end %> diff --git a/tracks/vendor/rails/activerecord/test/fixtures/movie.rb b/tracks/vendor/rails/activerecord/test/fixtures/movie.rb deleted file mode 100644 index 6384b4c8..00000000 --- a/tracks/vendor/rails/activerecord/test/fixtures/movie.rb +++ /dev/null @@ -1,5 +0,0 @@ -class Movie < ActiveRecord::Base - def self.primary_key - "movieid" - end -end diff --git a/tracks/vendor/rails/activerecord/test/fixtures/movies.yml b/tracks/vendor/rails/activerecord/test/fixtures/movies.yml deleted file mode 100644 index 2e9154fd..00000000 --- a/tracks/vendor/rails/activerecord/test/fixtures/movies.yml +++ /dev/null @@ -1,7 +0,0 @@ -first: - movieid: 1 - name: Terminator - -second: - movieid: 2 - name: Gladiator diff --git a/tracks/vendor/rails/activerecord/test/fixtures/naked/csv/accounts.csv b/tracks/vendor/rails/activerecord/test/fixtures/naked/csv/accounts.csv deleted file mode 100644 index 8b137891..00000000 --- a/tracks/vendor/rails/activerecord/test/fixtures/naked/csv/accounts.csv +++ /dev/null @@ -1 +0,0 @@ - diff --git a/tracks/vendor/rails/activerecord/test/fixtures/naked/yml/accounts.yml b/tracks/vendor/rails/activerecord/test/fixtures/naked/yml/accounts.yml deleted file mode 100644 index 8b137891..00000000 --- a/tracks/vendor/rails/activerecord/test/fixtures/naked/yml/accounts.yml +++ /dev/null @@ -1 +0,0 @@ - diff --git a/tracks/vendor/rails/activerecord/test/fixtures/naked/yml/companies.yml b/tracks/vendor/rails/activerecord/test/fixtures/naked/yml/companies.yml deleted file mode 100644 index 2c151c20..00000000 --- a/tracks/vendor/rails/activerecord/test/fixtures/naked/yml/companies.yml +++ /dev/null @@ -1 +0,0 @@ -# i wonder what will happen here diff --git a/tracks/vendor/rails/activerecord/test/fixtures/naked/yml/courses.yml b/tracks/vendor/rails/activerecord/test/fixtures/naked/yml/courses.yml deleted file mode 100644 index 19f0805d..00000000 --- a/tracks/vendor/rails/activerecord/test/fixtures/naked/yml/courses.yml +++ /dev/null @@ -1 +0,0 @@ -qwerty diff --git a/tracks/vendor/rails/activerecord/test/fixtures/order.rb b/tracks/vendor/rails/activerecord/test/fixtures/order.rb deleted file mode 100644 index ba114f22..00000000 --- a/tracks/vendor/rails/activerecord/test/fixtures/order.rb +++ /dev/null @@ -1,4 +0,0 @@ -class Order < ActiveRecord::Base - belongs_to :billing, :class_name => 'Customer', :foreign_key => 'billing_customer_id' - belongs_to :shipping, :class_name => 'Customer', :foreign_key => 'shipping_customer_id' -end diff --git a/tracks/vendor/rails/activerecord/test/fixtures/people.yml b/tracks/vendor/rails/activerecord/test/fixtures/people.yml deleted file mode 100644 index 22c64afb..00000000 --- a/tracks/vendor/rails/activerecord/test/fixtures/people.yml +++ /dev/null @@ -1,3 +0,0 @@ -michael: - id: 1 - first_name: Michael \ No newline at end of file diff --git a/tracks/vendor/rails/activerecord/test/fixtures/person.rb b/tracks/vendor/rails/activerecord/test/fixtures/person.rb deleted file mode 100644 index 4fa5811c..00000000 --- a/tracks/vendor/rails/activerecord/test/fixtures/person.rb +++ /dev/null @@ -1 +0,0 @@ -class Person < ActiveRecord::Base; end diff --git a/tracks/vendor/rails/activerecord/test/fixtures/post.rb b/tracks/vendor/rails/activerecord/test/fixtures/post.rb deleted file mode 100644 index bf44d8a0..00000000 --- a/tracks/vendor/rails/activerecord/test/fixtures/post.rb +++ /dev/null @@ -1,32 +0,0 @@ -class Post < ActiveRecord::Base - belongs_to :author do - def greeting - "hello" - end - end - - belongs_to :author_with_posts, :class_name => "Author", :include => :posts - - has_many :comments, :order => "body" do - def find_most_recent - find(:first, :order => "id DESC") - end - end - - has_one :very_special_comment - has_one :very_special_comment_with_post, :class_name => "VerySpecialComment", :include => :post - has_many :special_comments - - has_and_belongs_to_many :categories - has_and_belongs_to_many :special_categories, :join_table => "categories_posts" - - def self.what_are_you - 'a post...' - end -end - -class SpecialPost < Post; end; - -class StiPost < Post - has_one :special_comment, :class_name => "SpecialComment" -end diff --git a/tracks/vendor/rails/activerecord/test/fixtures/posts.yml b/tracks/vendor/rails/activerecord/test/fixtures/posts.yml deleted file mode 100644 index 0f1445b6..00000000 --- a/tracks/vendor/rails/activerecord/test/fixtures/posts.yml +++ /dev/null @@ -1,48 +0,0 @@ -welcome: - id: 1 - author_id: 1 - title: Welcome to the weblog - body: Such a lovely day - type: Post - -thinking: - id: 2 - author_id: 1 - title: So I was thinking - body: Like I hopefully always am - type: SpecialPost - -authorless: - id: 3 - author_id: 0 - title: I don't have any comments - body: I just don't want to - type: Post - -sti_comments: - id: 4 - author_id: 1 - title: sti comments - body: hello - type: Post - -sti_post_and_comments: - id: 5 - author_id: 1 - title: sti me - body: hello - type: StiPost - -sti_habtm: - id: 6 - author_id: 1 - title: habtm sti test - body: hello - type: Post - -eager_other: - id: 7 - author_id: 2 - title: eager loading with OR'd conditions - body: hello - type: Post diff --git a/tracks/vendor/rails/activerecord/test/fixtures/project.rb b/tracks/vendor/rails/activerecord/test/fixtures/project.rb deleted file mode 100644 index f8519f1b..00000000 --- a/tracks/vendor/rails/activerecord/test/fixtures/project.rb +++ /dev/null @@ -1,24 +0,0 @@ -class Project < ActiveRecord::Base - has_and_belongs_to_many :developers, :uniq => true - has_and_belongs_to_many :developers_named_david, :class_name => "Developer", :conditions => "name = 'David'", :uniq => true - has_and_belongs_to_many :salaried_developers, :class_name => "Developer", :conditions => "salary > 0" - has_and_belongs_to_many :developers_with_finder_sql, :class_name => "Developer", :finder_sql => 'SELECT t.*, j.* FROM developers_projects j, developers t WHERE t.id = j.developer_id AND j.project_id = #{id}' - has_and_belongs_to_many :developers_by_sql, :class_name => "Developer", :delete_sql => "DELETE FROM developers_projects WHERE project_id = \#{id} AND developer_id = \#{record.id}" - has_and_belongs_to_many :developers_with_callbacks, :class_name => "Developer", :before_add => Proc.new {|o, r| o.developers_log << "before_adding#{r.id}"}, - :after_add => Proc.new {|o, r| o.developers_log << "after_adding#{r.id}"}, - :before_remove => Proc.new {|o, r| o.developers_log << "before_removing#{r.id}"}, - :after_remove => Proc.new {|o, r| o.developers_log << "after_removing#{r.id}"} - - attr_accessor :developers_log - - def after_initialize - @developers_log = [] - end - -end - -class SpecialProject < Project - def hello_world - "hello there!" - end -end diff --git a/tracks/vendor/rails/activerecord/test/fixtures/projects.yml b/tracks/vendor/rails/activerecord/test/fixtures/projects.yml deleted file mode 100644 index 02800c78..00000000 --- a/tracks/vendor/rails/activerecord/test/fixtures/projects.yml +++ /dev/null @@ -1,7 +0,0 @@ -action_controller: - id: 2 - name: Active Controller - -active_record: - id: 1 - name: Active Record diff --git a/tracks/vendor/rails/activerecord/test/fixtures/reply.rb b/tracks/vendor/rails/activerecord/test/fixtures/reply.rb deleted file mode 100644 index ed22deaa..00000000 --- a/tracks/vendor/rails/activerecord/test/fixtures/reply.rb +++ /dev/null @@ -1,36 +0,0 @@ -require 'fixtures/topic' - -class Reply < Topic - belongs_to :topic, :foreign_key => "parent_id", :counter_cache => true - has_many :silly_replies, :dependent => true, :foreign_key => "parent_id" - - validate :errors_on_empty_content - validate_on_create :title_is_wrong_create - - attr_accessible :title, :author_name, :author_email_address, :written_on, :content, :last_read - - def validate - errors.add("title", "Empty") unless attribute_present? "title" - end - - def errors_on_empty_content - errors.add("content", "Empty") unless attribute_present? "content" - end - - def validate_on_create - if attribute_present?("title") && attribute_present?("content") && content == "Mismatch" - errors.add("title", "is Content Mismatch") - end - end - - def title_is_wrong_create - errors.add("title", "is Wrong Create") if attribute_present?("title") && title == "Wrong Create" - end - - def validate_on_update - errors.add("title", "is Wrong Update") if attribute_present?("title") && title == "Wrong Update" - end -end - -class SillyReply < Reply -end diff --git a/tracks/vendor/rails/activerecord/test/fixtures/subject.rb b/tracks/vendor/rails/activerecord/test/fixtures/subject.rb deleted file mode 100644 index 3502943f..00000000 --- a/tracks/vendor/rails/activerecord/test/fixtures/subject.rb +++ /dev/null @@ -1,4 +0,0 @@ -# used for OracleSynonymTest, see test/synonym_test_oci.rb -# -class Subject < ActiveRecord::Base -end diff --git a/tracks/vendor/rails/activerecord/test/fixtures/subscriber.rb b/tracks/vendor/rails/activerecord/test/fixtures/subscriber.rb deleted file mode 100644 index 51335a8f..00000000 --- a/tracks/vendor/rails/activerecord/test/fixtures/subscriber.rb +++ /dev/null @@ -1,6 +0,0 @@ -class Subscriber < ActiveRecord::Base - set_primary_key 'nick' -end - -class SpecialSubscriber < Subscriber -end diff --git a/tracks/vendor/rails/activerecord/test/fixtures/subscribers/first b/tracks/vendor/rails/activerecord/test/fixtures/subscribers/first deleted file mode 100644 index 5287e26e..00000000 --- a/tracks/vendor/rails/activerecord/test/fixtures/subscribers/first +++ /dev/null @@ -1,2 +0,0 @@ -nick => alterself -name => Luke Holden diff --git a/tracks/vendor/rails/activerecord/test/fixtures/subscribers/second b/tracks/vendor/rails/activerecord/test/fixtures/subscribers/second deleted file mode 100644 index 2345e447..00000000 --- a/tracks/vendor/rails/activerecord/test/fixtures/subscribers/second +++ /dev/null @@ -1,2 +0,0 @@ -nick => webster132 -name => David Heinemeier Hansson diff --git a/tracks/vendor/rails/activerecord/test/fixtures/task.rb b/tracks/vendor/rails/activerecord/test/fixtures/task.rb deleted file mode 100644 index ee0282c7..00000000 --- a/tracks/vendor/rails/activerecord/test/fixtures/task.rb +++ /dev/null @@ -1,3 +0,0 @@ -class Task < ActiveRecord::Base - -end diff --git a/tracks/vendor/rails/activerecord/test/fixtures/tasks.yml b/tracks/vendor/rails/activerecord/test/fixtures/tasks.yml deleted file mode 100644 index c8b158dc..00000000 --- a/tracks/vendor/rails/activerecord/test/fixtures/tasks.yml +++ /dev/null @@ -1,7 +0,0 @@ -# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html -first_task: - id: 1 - starting: "2005-03-30 06:30:00" - ending: "2005-03-30 08:30:00" -another_task: - id: 2 diff --git a/tracks/vendor/rails/activerecord/test/fixtures/topic.rb b/tracks/vendor/rails/activerecord/test/fixtures/topic.rb deleted file mode 100644 index 4c461224..00000000 --- a/tracks/vendor/rails/activerecord/test/fixtures/topic.rb +++ /dev/null @@ -1,20 +0,0 @@ -class Topic < ActiveRecord::Base - has_many :replies, :dependent => true, :foreign_key => "parent_id" - serialize :content - - before_create :default_written_on - before_destroy :destroy_children - - def parent - self.class.find(parent_id) - end - - protected - def default_written_on - self.written_on = Time.now unless attribute_present?("written_on") - end - - def destroy_children - self.class.delete_all "parent_id = #{id}" - end -end \ No newline at end of file diff --git a/tracks/vendor/rails/activerecord/test/fixtures/topics.yml b/tracks/vendor/rails/activerecord/test/fixtures/topics.yml deleted file mode 100644 index 6d4f5d80..00000000 --- a/tracks/vendor/rails/activerecord/test/fixtures/topics.yml +++ /dev/null @@ -1,21 +0,0 @@ -first: - id: 1 - title: The First Topic - author_name: David - author_email_address: david@loudthinking.com - written_on: 2003-07-16t15:28:00.00+01:00 - last_read: 2004-04-15 - bonus_time: 2005-01-30t15:28:00.00+01:00 - content: Have a nice day - approved: false - replies_count: 0 - -second: - id: 2 - title: The Second Topic's of the day - author_name: Mary - written_on: 2003-07-15t15:28:00.00+01:00 - content: Have a nice day - approved: true - replies_count: 2 - parent_id: 1 diff --git a/tracks/vendor/rails/activerecord/test/fixtures_test.rb b/tracks/vendor/rails/activerecord/test/fixtures_test.rb deleted file mode 100644 index 813291aa..00000000 --- a/tracks/vendor/rails/activerecord/test/fixtures_test.rb +++ /dev/null @@ -1,311 +0,0 @@ -require 'abstract_unit' -require 'fixtures/topic' -require 'fixtures/developer' -require 'fixtures/company' -require 'fixtures/task' -require 'fixtures/reply' - -class FixturesTest < Test::Unit::TestCase - self.use_instantiated_fixtures = true - self.use_transactional_fixtures = false - - fixtures :topics, :developers, :accounts, :tasks - - FIXTURES = %w( accounts companies customers - developers developers_projects entrants - movies projects subscribers topics tasks ) - MATCH_ATTRIBUTE_NAME = /[a-zA-Z][-_\w]*/ - - def test_clean_fixtures - FIXTURES.each do |name| - fixtures = nil - assert_nothing_raised { fixtures = create_fixtures(name) } - assert_kind_of(Fixtures, fixtures) - fixtures.each { |name, fixture| - fixture.each { |key, value| - assert_match(MATCH_ATTRIBUTE_NAME, key) - } - } - end - end - - def test_multiple_clean_fixtures - fixtures_array = nil - assert_nothing_raised { fixtures_array = create_fixtures(*FIXTURES) } - assert_kind_of(Array, fixtures_array) - fixtures_array.each { |fixtures| assert_kind_of(Fixtures, fixtures) } - end - - def test_attributes - topics = create_fixtures("topics") - assert_equal("The First Topic", topics["first"]["title"]) - assert_nil(topics["second"]["author_email_address"]) - end - - def test_inserts - topics = create_fixtures("topics") - firstRow = ActiveRecord::Base.connection.select_one("SELECT * FROM topics WHERE author_name = 'David'") - assert_equal("The First Topic", firstRow["title"]) - - secondRow = ActiveRecord::Base.connection.select_one("SELECT * FROM topics WHERE author_name = 'Mary'") - assert_nil(secondRow["author_email_address"]) - end - - if ActiveRecord::Base.connection.supports_migrations? - def test_inserts_with_pre_and_suffix - ActiveRecord::Base.connection.create_table :prefix_topics_suffix do |t| - t.column :title, :string - t.column :author_name, :string - t.column :author_email_address, :string - t.column :written_on, :datetime - t.column :bonus_time, :time - t.column :last_read, :date - t.column :content, :text - t.column :approved, :boolean, :default => true - t.column :replies_count, :integer, :default => 0 - t.column :parent_id, :integer - t.column :type, :string, :limit => 50 - end - - # Store existing prefix/suffix - old_prefix = ActiveRecord::Base.table_name_prefix - old_suffix = ActiveRecord::Base.table_name_suffix - - # Set a prefix/suffix we can test against - ActiveRecord::Base.table_name_prefix = 'prefix_' - ActiveRecord::Base.table_name_suffix = '_suffix' - - topics = create_fixtures("topics") - - # Restore prefix/suffix to its previous values - ActiveRecord::Base.table_name_prefix = old_prefix - ActiveRecord::Base.table_name_suffix = old_suffix - - firstRow = ActiveRecord::Base.connection.select_one("SELECT * FROM prefix_topics_suffix WHERE author_name = 'David'") - assert_equal("The First Topic", firstRow["title"]) - - secondRow = ActiveRecord::Base.connection.select_one("SELECT * FROM prefix_topics_suffix WHERE author_name = 'Mary'") - assert_nil(secondRow["author_email_address"]) - ensure - ActiveRecord::Base.connection.drop_table :prefix_topics_suffix rescue nil - end - end - - def test_insert_with_datetime - topics = create_fixtures("tasks") - first = Task.find(1) - assert first - end - - - def test_bad_format - path = File.join(File.dirname(__FILE__), 'fixtures', 'bad_fixtures') - Dir.entries(path).each do |file| - next unless File.file?(file) and file !~ Fixtures::DEFAULT_FILTER_RE - assert_raise(Fixture::FormatError) { - Fixture.new(bad_fixtures_path, file) - } - end - end - - def test_deprecated_yaml_extension - assert_raise(Fixture::FormatError) { - Fixtures.new(nil, 'bad_extension', File.join(File.dirname(__FILE__), 'fixtures')) - } - end - - def test_logger_level_invariant - level = ActiveRecord::Base.logger.level - create_fixtures('topics') - assert_equal level, ActiveRecord::Base.logger.level - end - - def test_instantiation - topics = create_fixtures("topics") - assert_kind_of Topic, topics["first"].find - end - - def test_complete_instantiation - assert_equal 2, @topics.size - assert_equal "The First Topic", @first.title - end - - def test_fixtures_from_root_yml_with_instantiation - # assert_equal 2, @accounts.size - assert_equal 50, @unknown.credit_limit - end - - def test_erb_in_fixtures - assert_equal 10, @developers.size - assert_equal "fixture_5", @dev_5.name - end - - def test_empty_yaml_fixture - assert_not_nil Fixtures.new( Account.connection, "accounts", File.dirname(__FILE__) + "/fixtures/naked/yml/accounts") - end - - def test_empty_yaml_fixture_with_a_comment_in_it - assert_not_nil Fixtures.new( Account.connection, "companies", File.dirname(__FILE__) + "/fixtures/naked/yml/companies") - end - - def test_dirty_dirty_yaml_file - assert_raises(Fixture::FormatError) do - Fixtures.new( Account.connection, "courses", File.dirname(__FILE__) + "/fixtures/naked/yml/courses") - end - end - - def test_empty_csv_fixtures - assert_not_nil Fixtures.new( Account.connection, "accounts", File.dirname(__FILE__) + "/fixtures/naked/csv/accounts") - end - - def test_omap_fixtures - assert_nothing_raised do - fixtures = Fixtures.new(Account.connection, 'categories', File.dirname(__FILE__) + '/fixtures/categories_ordered') - - i = 0 - fixtures.each do |name, fixture| - assert_equal "fixture_no_#{i}", name - assert_equal "Category #{i}", fixture['name'] - i += 1 - end - end - end -end - -if Account.connection.respond_to?(:reset_pk_sequence!) - class FixturesResetPkSequenceTest < Test::Unit::TestCase - fixtures :accounts - fixtures :companies - - def setup - @instances = [Account.new(:credit_limit => 50), Company.new(:name => 'RoR Consulting')] - end - - def test_resets_to_min_pk_with_specified_pk_and_sequence - @instances.each do |instance| - model = instance.class - model.delete_all - model.connection.reset_pk_sequence!(model.table_name, model.primary_key, model.sequence_name) - - instance.save! - assert_equal 1, instance.id, "Sequence reset for #{model.table_name} failed." - end - end - - def test_resets_to_min_pk_with_default_pk_and_sequence - @instances.each do |instance| - model = instance.class - model.delete_all - model.connection.reset_pk_sequence!(model.table_name) - - instance.save! - assert_equal 1, instance.id, "Sequence reset for #{model.table_name} failed." - end - end - - def test_create_fixtures_resets_sequences - @instances.each do |instance| - max_id = create_fixtures(instance.class.table_name).inject(0) do |max_id, (name, fixture)| - fixture_id = fixture['id'].to_i - fixture_id > max_id ? fixture_id : max_id - end - - # Clone the last fixture to check that it gets the next greatest id. - instance.save! - assert_equal max_id + 1, instance.id, "Sequence reset for #{instance.class.table_name} failed." - end - end - end -end - - -class FixturesWithoutInstantiationTest < Test::Unit::TestCase - self.use_instantiated_fixtures = false - fixtures :topics, :developers, :accounts - - def test_without_complete_instantiation - assert_nil @first - assert_nil @topics - assert_nil @developers - assert_nil @accounts - end - - def test_fixtures_from_root_yml_without_instantiation - assert_nil @unknown - end - - def test_accessor_methods - assert_equal "The First Topic", topics(:first).title - assert_equal "Jamis", developers(:jamis).name - assert_equal 50, accounts(:signals37).credit_limit - end -end - - -class FixturesWithoutInstanceInstantiationTest < Test::Unit::TestCase - self.use_instantiated_fixtures = true - self.use_instantiated_fixtures = :no_instances - - fixtures :topics, :developers, :accounts - - def test_without_instance_instantiation - assert_nil @first - assert_not_nil @topics - assert_not_nil @developers - assert_not_nil @accounts - end -end - - -class TransactionalFixturesTest < Test::Unit::TestCase - self.use_instantiated_fixtures = true - self.use_transactional_fixtures = true - - fixtures :topics - - def test_destroy - assert_not_nil @first - @first.destroy - end - - def test_destroy_just_kidding - assert_not_nil @first - end -end - - -class MultipleFixturesTest < Test::Unit::TestCase - fixtures :topics - fixtures :developers, :accounts - - def test_fixture_table_names - assert_equal %w(topics developers accounts), fixture_table_names - end -end - - -class OverlappingFixturesTest < Test::Unit::TestCase - fixtures :topics, :developers - fixtures :developers, :accounts - - def test_fixture_table_names - assert_equal %w(topics developers accounts), fixture_table_names - end -end - - -class ForeignKeyFixturesTest < Test::Unit::TestCase - fixtures :fk_test_has_pk, :fk_test_has_fk - - # if foreign keys are implemented and fixtures - # are not deleted in reverse order then this test - # case will raise StatementInvalid - - def test_number1 - assert true - end - - def test_number2 - assert true - end -end diff --git a/tracks/vendor/rails/activerecord/test/inheritance_test.rb b/tracks/vendor/rails/activerecord/test/inheritance_test.rb deleted file mode 100644 index d7265831..00000000 --- a/tracks/vendor/rails/activerecord/test/inheritance_test.rb +++ /dev/null @@ -1,144 +0,0 @@ -require 'abstract_unit' -require 'fixtures/company' -require 'fixtures/project' -require 'fixtures/subscriber' - -class InheritanceTest < Test::Unit::TestCase - fixtures :companies, :projects, :subscribers - - def test_a_bad_type_column - #SQLServer need to turn Identity Insert On before manually inserting into the Identity column - if current_adapter?(:SQLServerAdapter) - Company.connection.execute "SET IDENTITY_INSERT companies ON" - end - Company.connection.insert "INSERT INTO companies (id, #{QUOTED_TYPE}, name) VALUES(100, 'bad_class!', 'Not happening')" - - #We then need to turn it back Off before continuing. - if current_adapter?(:SQLServerAdapter) - Company.connection.execute "SET IDENTITY_INSERT companies OFF" - end - assert_raises(ActiveRecord::SubclassNotFound) { Company.find(100) } - end - - def test_inheritance_find - assert Company.find(1).kind_of?(Firm), "37signals should be a firm" - assert Firm.find(1).kind_of?(Firm), "37signals should be a firm" - assert Company.find(2).kind_of?(Client), "Summit should be a client" - assert Client.find(2).kind_of?(Client), "Summit should be a client" - end - - def test_alt_inheritance_find - switch_to_alt_inheritance_column - test_inheritance_find - end - - def test_inheritance_find_all - companies = Company.find(:all, :order => 'id') - assert companies[0].kind_of?(Firm), "37signals should be a firm" - assert companies[1].kind_of?(Client), "Summit should be a client" - end - - def test_alt_inheritance_find_all - switch_to_alt_inheritance_column - test_inheritance_find_all - end - - def test_inheritance_save - firm = Firm.new - firm.name = "Next Angle" - firm.save - - next_angle = Company.find(firm.id) - assert next_angle.kind_of?(Firm), "Next Angle should be a firm" - end - - def test_alt_inheritance_save - switch_to_alt_inheritance_column - test_inheritance_save - end - - def test_inheritance_condition - assert_equal 8, Company.count - assert_equal 2, Firm.count - assert_equal 3, Client.count - end - - def test_alt_inheritance_condition - switch_to_alt_inheritance_column - test_inheritance_condition - end - - def test_finding_incorrect_type_data - assert_raises(ActiveRecord::RecordNotFound) { Firm.find(2) } - assert_nothing_raised { Firm.find(1) } - end - - def test_alt_finding_incorrect_type_data - switch_to_alt_inheritance_column - test_finding_incorrect_type_data - end - - def test_update_all_within_inheritance - Client.update_all "name = 'I am a client'" - assert_equal "I am a client", Client.find(:all).first.name - assert_equal "37signals", Firm.find(:all).first.name - end - - def test_alt_update_all_within_inheritance - switch_to_alt_inheritance_column - test_update_all_within_inheritance - end - - def test_destroy_all_within_inheritance - Client.destroy_all - assert_equal 0, Client.count - assert_equal 2, Firm.count - end - - def test_alt_destroy_all_within_inheritance - switch_to_alt_inheritance_column - test_destroy_all_within_inheritance - end - - def test_find_first_within_inheritance - assert_kind_of Firm, Company.find(:first, :conditions => "name = '37signals'") - assert_kind_of Firm, Firm.find(:first, :conditions => "name = '37signals'") - assert_nil Client.find(:first, :conditions => "name = '37signals'") - end - - def test_alt_find_first_within_inheritance - switch_to_alt_inheritance_column - test_find_first_within_inheritance - end - - def test_complex_inheritance - very_special_client = VerySpecialClient.create("name" => "veryspecial") - assert_equal very_special_client, VerySpecialClient.find(:first, :conditions => "name = 'veryspecial'") - assert_equal very_special_client, SpecialClient.find(:first, :conditions => "name = 'veryspecial'") - assert_equal very_special_client, Company.find(:first, :conditions => "name = 'veryspecial'") - assert_equal very_special_client, Client.find(:first, :conditions => "name = 'veryspecial'") - assert_equal 1, Client.find(:all, :conditions => "name = 'Summit'").size - assert_equal very_special_client, Client.find(very_special_client.id) - end - - def test_alt_complex_inheritance - switch_to_alt_inheritance_column - test_complex_inheritance - end - - def test_inheritance_without_mapping - assert_kind_of SpecialSubscriber, SpecialSubscriber.find("webster132") - assert_nothing_raised { s = SpecialSubscriber.new("name" => "And breaaaaathe!"); s.id = 'roger'; s.save } - end - - private - def switch_to_alt_inheritance_column - # we don't want misleading test results, so get rid of the values in the type column - Company.find(:all, :order => 'id').each do |c| - c['type'] = nil - c.save - end - - def Company.inheritance_column() "ruby_type" end - end -end diff --git a/tracks/vendor/rails/activerecord/test/lifecycle_test.rb b/tracks/vendor/rails/activerecord/test/lifecycle_test.rb deleted file mode 100644 index ddac6f7c..00000000 --- a/tracks/vendor/rails/activerecord/test/lifecycle_test.rb +++ /dev/null @@ -1,116 +0,0 @@ -require 'abstract_unit' -require 'fixtures/topic' -require 'fixtures/developer' -require 'fixtures/reply' - -class Topic; def after_find() end end -class Developer; def after_find() end end -class SpecialDeveloper < Developer; end - -class TopicManualObserver - include Singleton - - attr_reader :action, :object, :callbacks - - def initialize - Topic.add_observer(self) - @callbacks = [] - end - - def update(callback_method, object) - @callbacks << { "callback_method" => callback_method, "object" => object } - end - - def has_been_notified? - !@callbacks.empty? - end -end - -class TopicaObserver < ActiveRecord::Observer - def self.observed_class() Topic end - - attr_reader :topic - - def after_find(topic) - @topic = topic - end -end - -class TopicObserver < ActiveRecord::Observer - attr_reader :topic - - def after_find(topic) - @topic = topic - end -end - -class MultiObserver < ActiveRecord::Observer - attr_reader :record - - def self.observed_class() [ Topic, Developer ] end - - def after_find(record) - @record = record - end - -end - -class LifecycleTest < Test::Unit::TestCase - fixtures :topics, :developers - - def test_before_destroy - assert_equal 2, Topic.count - Topic.find(1).destroy - assert_equal 0, Topic.count - end - - def test_after_save - ActiveRecord::Base.observers = :topic_manual_observer - - topic = Topic.find(1) - topic.title = "hello" - topic.save - - assert TopicManualObserver.instance.has_been_notified? - assert_equal :after_save, TopicManualObserver.instance.callbacks.last["callback_method"] - end - - def test_observer_update_on_save - ActiveRecord::Base.observers = TopicManualObserver - - topic = Topic.find(1) - assert TopicManualObserver.instance.has_been_notified? - assert_equal :after_find, TopicManualObserver.instance.callbacks.first["callback_method"] - end - - def test_auto_observer - topic_observer = TopicaObserver.instance - - topic = Topic.find(1) - assert_equal topic_observer.topic.title, topic.title - end - - def test_infered_auto_observer - topic_observer = TopicObserver.instance - - topic = Topic.find(1) - assert_equal topic_observer.topic.title, topic.title - end - - def test_observing_two_classes - multi_observer = MultiObserver.instance - - topic = Topic.find(1) - assert_equal multi_observer.record.title, topic.title - - developer = Developer.find(1) - assert_equal multi_observer.record.name, developer.name - end - - def test_observing_subclasses - multi_observer = MultiObserver.instance - - developer = SpecialDeveloper.find(1) - assert_equal multi_observer.record.name, developer.name - end -end diff --git a/tracks/vendor/rails/activerecord/test/locking_test.rb b/tracks/vendor/rails/activerecord/test/locking_test.rb deleted file mode 100644 index a88abc82..00000000 --- a/tracks/vendor/rails/activerecord/test/locking_test.rb +++ /dev/null @@ -1,32 +0,0 @@ -require 'abstract_unit' -require 'fixtures/person' - -class LockingTest < Test::Unit::TestCase - fixtures :people - - def test_lock_existing - p1 = Person.find(1) - p2 = Person.find(1) - - p1.first_name = "Michael" - p1.save - - assert_raises(ActiveRecord::StaleObjectError) { - p2.first_name = "should fail" - p2.save - } - end - - def test_lock_new - p1 = Person.create({ "first_name"=>"anika"}) - p2 = Person.find(p1.id) - assert_equal p1.id, p2.id - p1.first_name = "Anika" - p1.save - - assert_raises(ActiveRecord::StaleObjectError) { - p2.first_name = "should fail" - p2.save - } - end -end diff --git a/tracks/vendor/rails/activerecord/test/method_scoping_test.rb b/tracks/vendor/rails/activerecord/test/method_scoping_test.rb deleted file mode 100644 index 5c62dc39..00000000 --- a/tracks/vendor/rails/activerecord/test/method_scoping_test.rb +++ /dev/null @@ -1,181 +0,0 @@ -require 'abstract_unit' -require 'fixtures/developer' -require 'fixtures/comment' -require 'fixtures/post' -require 'fixtures/category' - -class MethodScopingTest < Test::Unit::TestCase - fixtures :developers, :comments, :posts - - def test_set_conditions - Developer.with_scope(:find => { :conditions => 'just a test...' }) do - assert_equal 'just a test...', Thread.current[:scoped_methods][Developer][:find][:conditions] - end - end - - def test_scoped_find - Developer.with_scope(:find => { :conditions => "name = 'David'" }) do - assert_nothing_raised { Developer.find(1) } - end - end - - def test_scoped_find_first - Developer.with_scope(:find => { :conditions => "salary = 100000" }) do - assert_equal Developer.find(10), Developer.find(:first, :order => 'name') - end - end - - def test_scoped_find_all - Developer.with_scope(:find => { :conditions => "name = 'David'" }) do - assert_equal [Developer.find(1)], Developer.find(:all) - end - end - - def test_scoped_count - Developer.with_scope(:find => { :conditions => "name = 'David'" }) do - assert_equal 1, Developer.count - end - - Developer.with_scope(:find => { :conditions => 'salary = 100000' }) do - assert_equal 8, Developer.count - assert_equal 1, Developer.count("name LIKE 'fixture_1%'") - end - end - - def test_scoped_create - new_comment = nil - - VerySpecialComment.with_scope(:create => { :post_id => 1 }) do - assert_equal({ :post_id => 1 }, Thread.current[:scoped_methods][VerySpecialComment][:create]) - new_comment = VerySpecialComment.create :body => "Wonderful world" - end - - assert Post.find(1).comments.include?(new_comment) - end - - def test_immutable_scope - options = { :conditions => "name = 'David'" } - Developer.with_scope(:find => options) do - assert_equal %w(David), Developer.find(:all).map { |d| d.name } - options[:conditions] = "name != 'David'" - assert_equal %w(David), Developer.find(:all).map { |d| d.name } - end - - scope = { :find => { :conditions => "name = 'David'" }} - Developer.with_scope(scope) do - assert_equal %w(David), Developer.find(:all).map { |d| d.name } - scope[:find][:conditions] = "name != 'David'" - assert_equal %w(David), Developer.find(:all).map { |d| d.name } - end - end - - def test_raise_on_nested_scope - Developer.with_scope(:find => { :conditions => '1=1' }) do - assert_raise(ArgumentError) do - Developer.with_scope(:find => { :conditions => '2=2' }) { } - end - end - end -end - -class HasManyScopingTest< Test::Unit::TestCase - fixtures :comments, :posts - - def setup - @welcome = Post.find(1) - end - - def test_forwarding_of_static_methods - assert_equal 'a comment...', Comment.what_are_you - assert_equal 'a comment...', @welcome.comments.what_are_you - end - - def test_forwarding_to_scoped - assert_equal 4, Comment.search_by_type('Comment').size - assert_equal 2, @welcome.comments.search_by_type('Comment').size - end - - def test_forwarding_to_dynamic_finders - assert_equal 4, Comment.find_all_by_type('Comment').size - assert_equal 2, @welcome.comments.find_all_by_type('Comment').size - end - - def test_raise_on_nested_scope - Comment.with_scope(:find => { :conditions => '1=1' }) do - assert_raise(ArgumentError) { @welcome.comments.what_are_you } - end - end -end - - -class HasAndBelongsToManyScopingTest< Test::Unit::TestCase - fixtures :posts, :categories, :categories_posts - - def setup - @welcome = Post.find(1) - end - - def test_forwarding_of_static_methods - assert_equal 'a category...', Category.what_are_you - assert_equal 'a category...', @welcome.categories.what_are_you - end - - def test_forwarding_to_dynamic_finders - assert_equal 1, Category.find_all_by_type('SpecialCategory').size - assert_equal 0, @welcome.categories.find_all_by_type('SpecialCategory').size - assert_equal 2, @welcome.categories.find_all_by_type('Category').size - end - - def test_raise_on_nested_scope - Category.with_scope(:find => { :conditions => '1=1' }) do - assert_raise(ArgumentError) { @welcome.categories.what_are_you } - end - end -end - - -=begin -# We disabled the scoping for has_one and belongs_to as we can't think of a proper use case - - -class BelongsToScopingTest< Test::Unit::TestCase - fixtures :comments, :posts - - def setup - @greetings = Comment.find(1) - end - - def test_forwarding_of_static_method - assert_equal 'a post...', Post.what_are_you - assert_equal 'a post...', @greetings.post.what_are_you - end - - def test_forwarding_to_dynamic_finders - assert_equal 4, Post.find_all_by_type('Post').size - assert_equal 1, @greetings.post.find_all_by_type('Post').size - end - -end - - -class HasOneScopingTest< Test::Unit::TestCase - fixtures :comments, :posts - - def setup - @sti_comments = Post.find(4) - end - - def test_forwarding_of_static_methods - assert_equal 'a comment...', Comment.what_are_you - assert_equal 'a very special comment...', @sti_comments.very_special_comment.what_are_you - end - - def test_forwarding_to_dynamic_finders - assert_equal 1, Comment.find_all_by_type('VerySpecialComment').size - assert_equal 1, @sti_comments.very_special_comment.find_all_by_type('VerySpecialComment').size - assert_equal 0, @sti_comments.very_special_comment.find_all_by_type('Comment').size - end - -end - -=end diff --git a/tracks/vendor/rails/activerecord/test/migration_test.rb b/tracks/vendor/rails/activerecord/test/migration_test.rb deleted file mode 100644 index 3fa680b9..00000000 --- a/tracks/vendor/rails/activerecord/test/migration_test.rb +++ /dev/null @@ -1,424 +0,0 @@ -require 'abstract_unit' -require 'fixtures/person' -require File.dirname(__FILE__) + '/fixtures/migrations/1_people_have_last_names' -require File.dirname(__FILE__) + '/fixtures/migrations/2_we_need_reminders' - -if ActiveRecord::Base.connection.supports_migrations? - class Reminder < ActiveRecord::Base; end - - class MigrationTest < Test::Unit::TestCase - self.use_transactional_fixtures = false - - def setup - end - - def teardown - ActiveRecord::Base.connection.initialize_schema_information - ActiveRecord::Base.connection.update "UPDATE #{ActiveRecord::Migrator.schema_info_table_name} SET version = 0" - - Reminder.connection.drop_table("reminders") rescue nil - Reminder.connection.drop_table("people_reminders") rescue nil - Reminder.connection.drop_table("prefix_reminders_suffix") rescue nil - Reminder.reset_column_information - - Person.connection.remove_column("people", "last_name") rescue nil - Person.connection.remove_column("people", "bio") rescue nil - Person.connection.remove_column("people", "age") rescue nil - Person.connection.remove_column("people", "height") rescue nil - Person.connection.remove_column("people", "birthday") rescue nil - Person.connection.remove_column("people", "favorite_day") rescue nil - Person.connection.remove_column("people", "male") rescue nil - Person.connection.remove_column("people", "administrator") rescue nil - Person.reset_column_information - end - - def test_add_index - Person.connection.add_column "people", "last_name", :string - Person.connection.add_column "people", "administrator", :boolean - - assert_nothing_raised { Person.connection.add_index("people", "last_name") } - assert_nothing_raised { Person.connection.remove_index("people", "last_name") } - - assert_nothing_raised { Person.connection.add_index("people", ["last_name", "first_name"]) } - assert_nothing_raised { Person.connection.remove_index("people", "last_name") } - - assert_nothing_raised { Person.connection.add_index("people", %w(last_name first_name administrator), :name => "named_admin") } - assert_nothing_raised { Person.connection.remove_index("people", :name => "named_admin") } - end - - def test_create_table_adds_id - Person.connection.create_table :testings do |t| - t.column :foo, :string - end - - assert_equal %w(foo id), - Person.connection.columns(:testings).map { |c| c.name }.sort - ensure - Person.connection.drop_table :testings rescue nil - end - - def test_create_table_with_not_null_column - Person.connection.create_table :testings do |t| - t.column :foo, :string, :null => false - end - - assert_raises(ActiveRecord::StatementInvalid) do - Person.connection.execute "insert into testings (foo) values (NULL)" - end - ensure - Person.connection.drop_table :testings rescue nil - end - - def test_create_table_with_defaults - Person.connection.create_table :testings do |t| - t.column :one, :string, :default => "hello" - t.column :two, :boolean, :default => true - t.column :three, :boolean, :default => false - t.column :four, :integer, :default => 1 - end - - columns = Person.connection.columns(:testings) - one = columns.detect { |c| c.name == "one" } - two = columns.detect { |c| c.name == "two" } - three = columns.detect { |c| c.name == "three" } - four = columns.detect { |c| c.name == "four" } - - assert_equal "hello", one.default - if current_adapter?(:OCIAdapter) - # Oracle doesn't support native booleans - assert_equal true, two.default == 1 - assert_equal false, three.default != 0 - else - assert_equal true, two.default - assert_equal false, three.default - end - assert_equal 1, four.default - - ensure - Person.connection.drop_table :testings rescue nil - end - - # SQL Server will not allow you to add a NOT NULL column - # to a table without specifying a default value, so the - # following test must be skipped - unless current_adapter?(:SQLServerAdapter) - def test_add_column_not_null_without_default - Person.connection.create_table :testings do |t| - t.column :foo, :string - end - Person.connection.add_column :testings, :bar, :string, :null => false - - assert_raises(ActiveRecord::StatementInvalid) do - Person.connection.execute "insert into testings (foo, bar) values ('hello', NULL)" - end - ensure - Person.connection.drop_table :testings rescue nil - end - end - - def test_add_column_not_null_with_default - Person.connection.create_table :testings do |t| - t.column :foo, :string - end - Person.connection.add_column :testings, :bar, :string, :null => false, :default => "default" - - assert_raises(ActiveRecord::StatementInvalid) do - Person.connection.execute "insert into testings (foo, bar) values ('hello', NULL)" - end - ensure - Person.connection.drop_table :testings rescue nil - end - - def test_native_types - Person.delete_all - Person.connection.add_column "people", "last_name", :string - Person.connection.add_column "people", "bio", :text - Person.connection.add_column "people", "age", :integer - Person.connection.add_column "people", "height", :float - Person.connection.add_column "people", "birthday", :datetime - Person.connection.add_column "people", "favorite_day", :date - Person.connection.add_column "people", "male", :boolean - assert_nothing_raised { Person.create :first_name => 'bob', :last_name => 'bobsen', :bio => "I was born ....", :age => 18, :height => 1.78, :birthday => 18.years.ago, :favorite_day => 10.days.ago, :male => true } - bob = Person.find(:first) - - assert_equal bob.first_name, 'bob' - assert_equal bob.last_name, 'bobsen' - assert_equal bob.bio, "I was born ...." - assert_equal bob.age, 18 - assert_equal bob.male?, true - - assert_equal String, bob.first_name.class - assert_equal String, bob.last_name.class - assert_equal String, bob.bio.class - assert_equal Fixnum, bob.age.class - assert_equal Time, bob.birthday.class - - if current_adapter?(:SQLServerAdapter) or current_adapter?(:OCIAdapter) - # SQL Server and Oracle don't differentiate between date/time - assert_equal Time, bob.favorite_day.class - else - assert_equal Date, bob.favorite_day.class - end - - assert_equal TrueClass, bob.male?.class - end - - def test_add_remove_single_field_using_string_arguments - assert !Person.column_methods_hash.include?(:last_name) - - ActiveRecord::Migration.add_column 'people', 'last_name', :string - - Person.reset_column_information - assert Person.column_methods_hash.include?(:last_name) - - ActiveRecord::Migration.remove_column 'people', 'last_name' - - Person.reset_column_information - assert !Person.column_methods_hash.include?(:last_name) - end - - def test_add_remove_single_field_using_symbol_arguments - assert !Person.column_methods_hash.include?(:last_name) - - ActiveRecord::Migration.add_column :people, :last_name, :string - - Person.reset_column_information - assert Person.column_methods_hash.include?(:last_name) - - ActiveRecord::Migration.remove_column :people, :last_name - - Person.reset_column_information - assert !Person.column_methods_hash.include?(:last_name) - end - - def test_add_rename - Person.delete_all - - begin - Person.connection.add_column "people", "girlfriend", :string - Person.create :girlfriend => 'bobette' - - Person.connection.rename_column "people", "girlfriend", "exgirlfriend" - - Person.reset_column_information - bob = Person.find(:first) - - assert_equal "bobette", bob.exgirlfriend - ensure - Person.connection.remove_column("people", "girlfriend") rescue nil - Person.connection.remove_column("people", "exgirlfriend") rescue nil - end - - end - - def test_rename_column_using_symbol_arguments - begin - Person.connection.rename_column :people, :first_name, :nick_name - Person.reset_column_information - assert Person.column_names.include?("nick_name") - ensure - Person.connection.remove_column("people","nick_name") - Person.connection.add_column("people","first_name", :string) - end - end - - def test_rename_column - begin - Person.connection.rename_column "people", "first_name", "nick_name" - Person.reset_column_information - assert Person.column_names.include?("nick_name") - ensure - Person.connection.remove_column("people","nick_name") - Person.connection.add_column("people","first_name", :string) - end - end - - def test_rename_table - begin - ActiveRecord::Base.connection.create_table :octopuses do |t| - t.column :url, :string - end - ActiveRecord::Base.connection.rename_table :octopuses, :octopi - - assert_nothing_raised do - if current_adapter?(:OCIAdapter) - # Oracle requires the explicit sequence for the pk - ActiveRecord::Base.connection.execute "INSERT INTO octopi (id, url) VALUES (octopi_seq.nextval, 'http://www.foreverflying.com/octopus-black7.jpg')" - else - ActiveRecord::Base.connection.execute "INSERT INTO octopi (url) VALUES ('http://www.foreverflying.com/octopus-black7.jpg')" - end - end - - assert_equal 'http://www.foreverflying.com/octopus-black7.jpg', ActiveRecord::Base.connection.select_value("SELECT url FROM octopi WHERE id=1") - - ensure - ActiveRecord::Base.connection.drop_table :octopuses rescue nil - ActiveRecord::Base.connection.drop_table :octopi rescue nil - end - end - - def test_change_column - Person.connection.add_column "people", "bio", :string - assert_nothing_raised { Person.connection.change_column "people", "bio", :text } - end - - def test_change_column_with_new_default - Person.connection.add_column "people", "administrator", :boolean, :default => 1 - Person.reset_column_information - assert Person.new.administrator? - - assert_nothing_raised { Person.connection.change_column "people", "administrator", :boolean, :default => 0 } - Person.reset_column_information - assert !Person.new.administrator? - end - - def test_add_table - assert !Reminder.table_exists? - - WeNeedReminders.up - - assert Reminder.create("content" => "hello world", "remind_at" => Time.now) - assert_equal "hello world", Reminder.find(:first).content - - WeNeedReminders.down - assert_raises(ActiveRecord::StatementInvalid) { Reminder.find(:first) } - end - - def test_migrator - assert !Person.column_methods_hash.include?(:last_name) - assert !Reminder.table_exists? - - ActiveRecord::Migrator.up(File.dirname(__FILE__) + '/fixtures/migrations/') - - assert_equal 3, ActiveRecord::Migrator.current_version - Person.reset_column_information - assert Person.column_methods_hash.include?(:last_name) - assert Reminder.create("content" => "hello world", "remind_at" => Time.now) - assert_equal "hello world", Reminder.find(:first).content - - ActiveRecord::Migrator.down(File.dirname(__FILE__) + '/fixtures/migrations/') - - assert_equal 0, ActiveRecord::Migrator.current_version - Person.reset_column_information - assert !Person.column_methods_hash.include?(:last_name) - assert_raises(ActiveRecord::StatementInvalid) { Reminder.find(:first) } - end - - def test_migrator_one_up - assert !Person.column_methods_hash.include?(:last_name) - assert !Reminder.table_exists? - - ActiveRecord::Migrator.up(File.dirname(__FILE__) + '/fixtures/migrations/', 1) - - Person.reset_column_information - assert Person.column_methods_hash.include?(:last_name) - assert !Reminder.table_exists? - - ActiveRecord::Migrator.up(File.dirname(__FILE__) + '/fixtures/migrations/', 2) - - assert Reminder.create("content" => "hello world", "remind_at" => Time.now) - assert_equal "hello world", Reminder.find(:first).content - end - - def test_migrator_one_down - ActiveRecord::Migrator.up(File.dirname(__FILE__) + '/fixtures/migrations/') - - ActiveRecord::Migrator.down(File.dirname(__FILE__) + '/fixtures/migrations/', 1) - - Person.reset_column_information - assert Person.column_methods_hash.include?(:last_name) - assert !Reminder.table_exists? - end - - def test_migrator_one_up_one_down - ActiveRecord::Migrator.up(File.dirname(__FILE__) + '/fixtures/migrations/', 1) - ActiveRecord::Migrator.down(File.dirname(__FILE__) + '/fixtures/migrations/', 0) - - assert !Person.column_methods_hash.include?(:last_name) - assert !Reminder.table_exists? - end - - def test_migrator_going_down_due_to_version_target - ActiveRecord::Migrator.up(File.dirname(__FILE__) + '/fixtures/migrations/', 1) - ActiveRecord::Migrator.migrate(File.dirname(__FILE__) + '/fixtures/migrations/', 0) - - assert !Person.column_methods_hash.include?(:last_name) - assert !Reminder.table_exists? - - ActiveRecord::Migrator.migrate(File.dirname(__FILE__) + '/fixtures/migrations/') - - Person.reset_column_information - assert Person.column_methods_hash.include?(:last_name) - assert Reminder.create("content" => "hello world", "remind_at" => Time.now) - assert_equal "hello world", Reminder.find(:first).content - end - - def test_schema_info_table_name - ActiveRecord::Base.table_name_prefix = "prefix_" - ActiveRecord::Base.table_name_suffix = "_suffix" - Reminder.reset_table_name - assert_equal "prefix_schema_info_suffix", ActiveRecord::Migrator.schema_info_table_name - ActiveRecord::Base.table_name_prefix = "" - ActiveRecord::Base.table_name_suffix = "" - Reminder.reset_table_name - assert_equal "schema_info", ActiveRecord::Migrator.schema_info_table_name - ensure - ActiveRecord::Base.table_name_prefix = "" - ActiveRecord::Base.table_name_suffix = "" - end - - def test_proper_table_name - assert_equal "table", ActiveRecord::Migrator.proper_table_name('table') - assert_equal "table", ActiveRecord::Migrator.proper_table_name(:table) - assert_equal "reminders", ActiveRecord::Migrator.proper_table_name(Reminder) - Reminder.reset_table_name - assert_equal Reminder.table_name, ActiveRecord::Migrator.proper_table_name(Reminder) - - # Use the model's own prefix/suffix if a model is given - ActiveRecord::Base.table_name_prefix = "ARprefix_" - ActiveRecord::Base.table_name_suffix = "_ARsuffix" - Reminder.table_name_prefix = 'prefix_' - Reminder.table_name_suffix = '_suffix' - Reminder.reset_table_name - assert_equal "prefix_reminders_suffix", ActiveRecord::Migrator.proper_table_name(Reminder) - Reminder.table_name_prefix = '' - Reminder.table_name_suffix = '' - Reminder.reset_table_name - - # Use AR::Base's prefix/suffix if string or symbol is given - ActiveRecord::Base.table_name_prefix = "prefix_" - ActiveRecord::Base.table_name_suffix = "_suffix" - Reminder.reset_table_name - assert_equal "prefix_table_suffix", ActiveRecord::Migrator.proper_table_name('table') - assert_equal "prefix_table_suffix", ActiveRecord::Migrator.proper_table_name(:table) - ActiveRecord::Base.table_name_prefix = "" - ActiveRecord::Base.table_name_suffix = "" - Reminder.reset_table_name - end - - def test_add_drop_table_with_prefix_and_suffix - assert !Reminder.table_exists? - ActiveRecord::Base.table_name_prefix = 'prefix_' - ActiveRecord::Base.table_name_suffix = '_suffix' - Reminder.reset_table_name - Reminder.reset_sequence_name - WeNeedReminders.up - assert Reminder.create("content" => "hello world", "remind_at" => Time.now) - assert_equal "hello world", Reminder.find(:first).content - - WeNeedReminders.down - assert_raises(ActiveRecord::StatementInvalid) { Reminder.find(:first) } - ensure - ActiveRecord::Base.table_name_prefix = '' - ActiveRecord::Base.table_name_suffix = '' - Reminder.reset_table_name - Reminder.reset_sequence_name - end - - def test_migrator_with_duplicates - assert_raises(ActiveRecord::DuplicateMigrationVersionError) do - ActiveRecord::Migrator.migrate(File.dirname(__FILE__) + '/fixtures/migrations_with_duplicate/', nil) - end - end - end -end diff --git a/tracks/vendor/rails/activerecord/test/mixin_nested_set_test.rb b/tracks/vendor/rails/activerecord/test/mixin_nested_set_test.rb deleted file mode 100644 index c52dabd6..00000000 --- a/tracks/vendor/rails/activerecord/test/mixin_nested_set_test.rb +++ /dev/null @@ -1,184 +0,0 @@ -require 'abstract_unit' -require 'active_record/acts/nested_set' -require 'fixtures/mixin' -require 'pp' - -class MixinNestedSetTest < Test::Unit::TestCase - fixtures :mixins - - def test_mixing_in_methods - ns = NestedSet.new - assert( ns.respond_to?( :all_children ) ) - assert_equal( ns.scope_condition, "ROOT_ID IS NULL" ) - - check_method_mixins ns - end - - def test_string_scope - ns = NestedSetWithStringScope.new - - ns.root_id = 1 - assert_equal( ns.scope_condition, "root_id = 1" ) - ns.root_id = 42 - assert_equal( ns.scope_condition, "root_id = 42" ) - check_method_mixins ns - end - - def test_symbol_scope - ns = NestedSetWithSymbolScope.new - ns.root_id = 1 - assert_equal( ns.scope_condition, "root_id = 1" ) - ns.root_id = 42 - assert_equal( ns.scope_condition, "root_id = 42" ) - check_method_mixins ns - end - - def check_method_mixins( obj ) - [:scope_condition, :left_col_name, :right_col_name, :parent_column, :root?, :add_child, - :children_count, :full_set, :all_children, :direct_children].each { |symbol| assert( obj.respond_to?(symbol)) } - end - - def set( id ) - NestedSet.find( 3000 + id ) - end - - def test_adding_children - assert( set(1).unknown? ) - assert( set(2).unknown? ) - set(1).add_child set(2) - - # Did we maintain adding the parent_ids? - assert( set(1).root? ) - assert( set(2).child? ) - assert( set(2).parent_id == set(1).id ) - - # Check boundies - assert_equal( set(1).lft, 1 ) - assert_equal( set(2).lft, 2 ) - assert_equal( set(2).rgt, 3 ) - assert_equal( set(1).rgt, 4 ) - - # Check children cound - assert_equal( set(1).children_count, 1 ) - - set(1).add_child set(3) - - #check boundries - assert_equal( set(1).lft, 1 ) - assert_equal( set(2).lft, 2 ) - assert_equal( set(2).rgt, 3 ) - assert_equal( set(3).lft, 4 ) - assert_equal( set(3).rgt, 5 ) - assert_equal( set(1).rgt, 6 ) - - # How is the count looking? - assert_equal( set(1).children_count, 2 ) - - set(2).add_child set(4) - - # boundries - assert_equal( set(1).lft, 1 ) - assert_equal( set(2).lft, 2 ) - assert_equal( set(4).lft, 3 ) - assert_equal( set(4).rgt, 4 ) - assert_equal( set(2).rgt, 5 ) - assert_equal( set(3).lft, 6 ) - assert_equal( set(3).rgt, 7 ) - assert_equal( set(1).rgt, 8 ) - - # Children count - assert_equal( set(1).children_count, 3 ) - assert_equal( set(2).children_count, 1 ) - assert_equal( set(3).children_count, 0 ) - assert_equal( set(4).children_count, 0 ) - - set(2).add_child set(5) - set(4).add_child set(6) - - assert_equal( set(2).children_count, 3 ) - - - # Children accessors - assert_equal( set(1).full_set.length, 6 ) - assert_equal( set(2).full_set.length, 4 ) - assert_equal( set(4).full_set.length, 2 ) - - assert_equal( set(1).all_children.length, 5 ) - assert_equal( set(6).all_children.length, 0 ) - - assert_equal( set(1).direct_children.length, 2 ) - - end - - def test_snipping_tree - big_tree = NestedSetWithStringScope.find( 4001 ) - - # Make sure we have the right one - assert_equal( 3, big_tree.direct_children.length ) - assert_equal( 10, big_tree.full_set.length ) - - NestedSetWithStringScope.find( 4005 ).destroy - - big_tree = NestedSetWithStringScope.find( 4001 ) - - assert_equal( 7, big_tree.full_set.length ) - assert_equal( 2, big_tree.direct_children.length ) - - assert_equal( 1, NestedSetWithStringScope.find(4001).lft ) - assert_equal( 2, NestedSetWithStringScope.find(4002).lft ) - assert_equal( 3, NestedSetWithStringScope.find(4003).lft ) - assert_equal( 4, NestedSetWithStringScope.find(4003).rgt ) - assert_equal( 5, NestedSetWithStringScope.find(4004).lft ) - assert_equal( 6, NestedSetWithStringScope.find(4004).rgt ) - assert_equal( 7, NestedSetWithStringScope.find(4002).rgt ) - assert_equal( 8, NestedSetWithStringScope.find(4008).lft ) - assert_equal( 9, NestedSetWithStringScope.find(4009).lft ) - assert_equal(10, NestedSetWithStringScope.find(4009).rgt ) - assert_equal(11, NestedSetWithStringScope.find(4010).lft ) - assert_equal(12, NestedSetWithStringScope.find(4010).rgt ) - assert_equal(13, NestedSetWithStringScope.find(4008).rgt ) - assert_equal(14, NestedSetWithStringScope.find(4001).rgt ) - end - - def test_deleting_root - NestedSetWithStringScope.find(4001).destroy - - assert( NestedSetWithStringScope.count == 0 ) - end - - def test_common_usage - mixins(:set_1).add_child( mixins(:set_2) ) - assert_equal( 1, mixins(:set_1).direct_children.length ) - - mixins(:set_2).add_child( mixins(:set_3) ) - assert_equal( 1, mixins(:set_1).direct_children.length ) - - # Local cache is now out of date! - # Problem: the update_alls update all objects up the tree - mixins(:set_1).reload - assert_equal( 2, mixins(:set_1).all_children.length ) - - assert_equal( 1, mixins(:set_1).lft ) - assert_equal( 2, mixins(:set_2).lft ) - assert_equal( 3, mixins(:set_3).lft ) - assert_equal( 4, mixins(:set_3).rgt ) - assert_equal( 5, mixins(:set_2).rgt ) - assert_equal( 6, mixins(:set_1).rgt ) - - assert( mixins(:set_1).root? ) - - begin - mixins(:set_4).add_child( mixins(:set_1) ) - fail - rescue - end - - assert_equal( 2, mixins(:set_1).all_children.length ) - - mixins(:set_1).add_child mixins(:set_4) - - assert_equal( 3, mixins(:set_1).all_children.length ) - - - end -end diff --git a/tracks/vendor/rails/activerecord/test/mixin_test.rb b/tracks/vendor/rails/activerecord/test/mixin_test.rb deleted file mode 100644 index 8ab73cfe..00000000 --- a/tracks/vendor/rails/activerecord/test/mixin_test.rb +++ /dev/null @@ -1,512 +0,0 @@ -require 'abstract_unit' -require 'active_record/acts/tree' -require 'active_record/acts/list' -require 'active_record/acts/nested_set' -require 'fixtures/mixin' - -class ListTest < Test::Unit::TestCase - fixtures :mixins - - def test_reordering - assert_equal [mixins(:list_1), - mixins(:list_2), - mixins(:list_3), - mixins(:list_4)], - ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos') - - mixins(:list_2).move_lower - - assert_equal [mixins(:list_1), - mixins(:list_3), - mixins(:list_2), - mixins(:list_4)], - ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos') - - mixins(:list_2).move_higher - - assert_equal [mixins(:list_1), - mixins(:list_2), - mixins(:list_3), - mixins(:list_4)], - ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos') - - mixins(:list_1).move_to_bottom - - assert_equal [mixins(:list_2), - mixins(:list_3), - mixins(:list_4), - mixins(:list_1)], - ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos') - - mixins(:list_1).move_to_top - - assert_equal [mixins(:list_1), - mixins(:list_2), - mixins(:list_3), - mixins(:list_4)], - ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos') - - - mixins(:list_2).move_to_bottom - - assert_equal [mixins(:list_1), - mixins(:list_3), - mixins(:list_4), - mixins(:list_2)], - ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos') - - mixins(:list_4).move_to_top - - assert_equal [mixins(:list_4), - mixins(:list_1), - mixins(:list_3), - mixins(:list_2)], - ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos') - - end - - def test_move_to_bottom_with_next_to_last_item - assert_equal [mixins(:list_1), - mixins(:list_2), - mixins(:list_3), - mixins(:list_4)], - ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos') - - mixins(:list_3).move_to_bottom - - assert_equal [mixins(:list_1), - mixins(:list_2), - mixins(:list_4), - mixins(:list_3)], - ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos') - end - - def test_next_prev - assert_equal mixins(:list_2), mixins(:list_1).lower_item - assert_nil mixins(:list_1).higher_item - assert_equal mixins(:list_3), mixins(:list_4).higher_item - assert_nil mixins(:list_4).lower_item - end - - - def test_injection - item = ListMixin.new("parent_id"=>1) - assert_equal "parent_id = 1", item.scope_condition - assert_equal "pos", item.position_column - end - - def test_insert - new = ListMixin.create("parent_id"=>20) - assert_equal 1, new.pos - assert new.first? - assert new.last? - - new = ListMixin.create("parent_id"=>20) - assert_equal 2, new.pos - assert !new.first? - assert new.last? - - new = ListMixin.create("parent_id"=>20) - assert_equal 3, new.pos - assert !new.first? - assert new.last? - - new = ListMixin.create("parent_id"=>0) - assert_equal 1, new.pos - assert new.first? - assert new.last? - end - - def test_insert_at - new = ListMixin.create("parent_id" => 20) - assert_equal 1, new.pos - - new = ListMixin.create("parent_id" => 20) - assert_equal 2, new.pos - - new = ListMixin.create("parent_id" => 20) - assert_equal 3, new.pos - - new4 = ListMixin.create("parent_id" => 20) - assert_equal 4, new4.pos - - new4.insert_at(3) - assert_equal 3, new4.pos - - new.reload - assert_equal 4, new.pos - - new.insert_at(2) - assert_equal 2, new.pos - - new4.reload - assert_equal 4, new4.pos - - new5 = ListMixin.create("parent_id" => 20) - assert_equal 5, new5.pos - - new5.insert_at(1) - assert_equal 1, new5.pos - - new4.reload - assert_equal 5, new4.pos - end - - def test_delete_middle - assert_equal [mixins(:list_1), - mixins(:list_2), - mixins(:list_3), - mixins(:list_4)], - ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos') - - mixins(:list_2).destroy - - assert_equal [mixins(:list_1, :reload), - mixins(:list_3, :reload), - mixins(:list_4, :reload)], - ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos') - - assert_equal 1, mixins(:list_1).pos - assert_equal 2, mixins(:list_3).pos - assert_equal 3, mixins(:list_4).pos - - mixins(:list_1).destroy - - assert_equal [mixins(:list_3, :reload), - mixins(:list_4, :reload)], - ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos') - - assert_equal 1, mixins(:list_3).pos - assert_equal 2, mixins(:list_4).pos - - end - - def test_with_string_based_scope - new = ListWithStringScopeMixin.create("parent_id"=>500) - assert_equal 1, new.pos - assert new.first? - assert new.last? - end - - def test_nil_scope - new1, new2, new3 = ListMixin.create, ListMixin.create, ListMixin.create - new2.move_higher - assert_equal [new2, new1, new3], ListMixin.find(:all, :conditions => 'parent_id IS NULL', :order => 'pos') - end - -end - -class TreeTest < Test::Unit::TestCase - fixtures :mixins - - def test_has_child - assert_equal true, mixins(:tree_1).has_children? - assert_equal true, mixins(:tree_2).has_children? - assert_equal false, mixins(:tree_3).has_children? - assert_equal false, mixins(:tree_4).has_children? - end - - def test_children - assert_equal mixins(:tree_1).children, [mixins(:tree_2), mixins(:tree_4)] - assert_equal mixins(:tree_2).children, [mixins(:tree_3)] - assert_equal mixins(:tree_3).children, [] - assert_equal mixins(:tree_4).children, [] - end - - def test_has_parent - assert_equal false, mixins(:tree_1).has_parent? - assert_equal true, mixins(:tree_2).has_parent? - assert_equal true, mixins(:tree_3).has_parent? - assert_equal true, mixins(:tree_4).has_parent? - end - - def test_parent - assert_equal mixins(:tree_2).parent, mixins(:tree_1) - assert_equal mixins(:tree_2).parent, mixins(:tree_4).parent - assert_nil mixins(:tree_1).parent - end - - def test_delete - assert_equal 6, TreeMixin.count - mixins(:tree_1).destroy - assert_equal 2, TreeMixin.count - mixins(:tree2_1).destroy - mixins(:tree3_1).destroy - assert_equal 0, TreeMixin.count - end - - def test_insert - @extra = mixins(:tree_1).children.create - - assert @extra - - assert_equal @extra.parent, mixins(:tree_1) - - assert_equal 3, mixins(:tree_1).children.size - assert mixins(:tree_1).children.include?(@extra) - assert mixins(:tree_1).children.include?(mixins(:tree_2)) - assert mixins(:tree_1).children.include?(mixins(:tree_4)) - end - - def test_ancestors - assert_equal [], mixins(:tree_1).ancestors - assert_equal [mixins(:tree_1)], mixins(:tree_2).ancestors - assert_equal [mixins(:tree_2), mixins(:tree_1)], mixins(:tree_3).ancestors - assert_equal [mixins(:tree_1)], mixins(:tree_4).ancestors - assert_equal [], mixins(:tree2_1).ancestors - assert_equal [], mixins(:tree3_1).ancestors - end - - def test_root - assert_equal mixins(:tree_1), TreeMixin.root - assert_equal mixins(:tree_1), mixins(:tree_1).root - assert_equal mixins(:tree_1), mixins(:tree_2).root - assert_equal mixins(:tree_1), mixins(:tree_3).root - assert_equal mixins(:tree_1), mixins(:tree_4).root - assert_equal mixins(:tree2_1), mixins(:tree2_1).root - assert_equal mixins(:tree3_1), mixins(:tree3_1).root - end - - def test_roots - assert_equal [mixins(:tree_1), mixins(:tree2_1), mixins(:tree3_1)], TreeMixin.roots - end - - def test_siblings - assert_equal [mixins(:tree2_1), mixins(:tree3_1)], mixins(:tree_1).siblings - assert_equal [mixins(:tree_4)], mixins(:tree_2).siblings - assert_equal [], mixins(:tree_3).siblings - assert_equal [mixins(:tree_2)], mixins(:tree_4).siblings - assert_equal [mixins(:tree_1), mixins(:tree3_1)], mixins(:tree2_1).siblings - assert_equal [mixins(:tree_1), mixins(:tree2_1)], mixins(:tree3_1).siblings - end - - def test_self_and_siblings - assert_equal [mixins(:tree_1), mixins(:tree2_1), mixins(:tree3_1)], mixins(:tree_1).self_and_siblings - assert_equal [mixins(:tree_2), mixins(:tree_4)], mixins(:tree_2).self_and_siblings - assert_equal [mixins(:tree_3)], mixins(:tree_3).self_and_siblings - assert_equal [mixins(:tree_2), mixins(:tree_4)], mixins(:tree_4).self_and_siblings - assert_equal [mixins(:tree_1), mixins(:tree2_1), mixins(:tree3_1)], mixins(:tree2_1).self_and_siblings - assert_equal [mixins(:tree_1), mixins(:tree2_1), mixins(:tree3_1)], mixins(:tree3_1).self_and_siblings - end -end - -class TreeTestWithoutOrder < Test::Unit::TestCase - fixtures :mixins - - def test_root - assert [mixins(:tree_without_order_1), mixins(:tree_without_order_2)].include?(TreeMixinWithoutOrder.root) - end - - def test_roots - assert_equal [], [mixins(:tree_without_order_1), mixins(:tree_without_order_2)] - TreeMixinWithoutOrder.roots - end -end - -class TouchTest < Test::Unit::TestCase - fixtures :mixins - - def test_update - stamped = Mixin.new - - assert_nil stamped.updated_at - assert_nil stamped.created_at - stamped.save - assert_not_nil stamped.updated_at - assert_not_nil stamped.created_at - end - - def test_create - @obj = Mixin.create - assert_not_nil @obj.updated_at - assert_not_nil @obj.created_at - end - - def test_many_updates - stamped = Mixin.new - - assert_nil stamped.updated_at - assert_nil stamped.created_at - stamped.save - assert_not_nil stamped.created_at - assert_not_nil stamped.updated_at - - old_updated_at = stamped.updated_at - - sleep 1 - stamped.save - assert_not_equal stamped.created_at, stamped.updated_at - assert_not_equal old_updated_at, stamped.updated_at - - end - - def test_create_turned_off - Mixin.record_timestamps = false - - assert_nil mixins(:tree_1).updated_at - mixins(:tree_1).save - assert_nil mixins(:tree_1).updated_at - - Mixin.record_timestamps = true - end - -end - - -class ListSubTest < Test::Unit::TestCase - fixtures :mixins - - def test_reordering - assert_equal [mixins(:list_sub_1), - mixins(:list_sub_2), - mixins(:list_sub_3), - mixins(:list_sub_4)], - ListMixin.find(:all, :conditions => 'parent_id = 5000', :order => 'pos') - - mixins(:list_sub_2).move_lower - - assert_equal [mixins(:list_sub_1), - mixins(:list_sub_3), - mixins(:list_sub_2), - mixins(:list_sub_4)], - ListMixin.find(:all, :conditions => 'parent_id = 5000', :order => 'pos') - - mixins(:list_sub_2).move_higher - - assert_equal [mixins(:list_sub_1), - mixins(:list_sub_2), - mixins(:list_sub_3), - mixins(:list_sub_4)], - ListMixin.find(:all, :conditions => 'parent_id = 5000', :order => 'pos') - - mixins(:list_sub_1).move_to_bottom - - assert_equal [mixins(:list_sub_2), - mixins(:list_sub_3), - mixins(:list_sub_4), - mixins(:list_sub_1)], - ListMixin.find(:all, :conditions => 'parent_id = 5000', :order => 'pos') - - mixins(:list_sub_1).move_to_top - - assert_equal [mixins(:list_sub_1), - mixins(:list_sub_2), - mixins(:list_sub_3), - mixins(:list_sub_4)], - ListMixin.find(:all, :conditions => 'parent_id = 5000', :order => 'pos') - - - mixins(:list_sub_2).move_to_bottom - - assert_equal [mixins(:list_sub_1), - mixins(:list_sub_3), - mixins(:list_sub_4), - mixins(:list_sub_2)], - ListMixin.find(:all, :conditions => 'parent_id = 5000', :order => 'pos') - - mixins(:list_sub_4).move_to_top - - assert_equal [mixins(:list_sub_4), - mixins(:list_sub_1), - mixins(:list_sub_3), - mixins(:list_sub_2)], - ListMixin.find(:all, :conditions => 'parent_id = 5000', :order => 'pos') - - end - - def test_move_to_bottom_with_next_to_last_item - assert_equal [mixins(:list_sub_1), - mixins(:list_sub_2), - mixins(:list_sub_3), - mixins(:list_sub_4)], - ListMixin.find(:all, :conditions => 'parent_id = 5000', :order => 'pos') - - mixins(:list_sub_3).move_to_bottom - - assert_equal [mixins(:list_sub_1), - mixins(:list_sub_2), - mixins(:list_sub_4), - mixins(:list_sub_3)], - ListMixin.find(:all, :conditions => 'parent_id = 5000', :order => 'pos') - end - - def test_next_prev - assert_equal mixins(:list_sub_2), mixins(:list_sub_1).lower_item - assert_nil mixins(:list_sub_1).higher_item - assert_equal mixins(:list_sub_3), mixins(:list_sub_4).higher_item - assert_nil mixins(:list_sub_4).lower_item - end - - - def test_injection - item = ListMixin.new("parent_id"=>1) - assert_equal "parent_id = 1", item.scope_condition - assert_equal "pos", item.position_column - end - - - def test_insert_at - new = ListMixin.create("parent_id" => 20) - assert_equal 1, new.pos - - new = ListMixinSub1.create("parent_id" => 20) - assert_equal 2, new.pos - - new = ListMixinSub2.create("parent_id" => 20) - assert_equal 3, new.pos - - new4 = ListMixin.create("parent_id" => 20) - assert_equal 4, new4.pos - - new4.insert_at(3) - assert_equal 3, new4.pos - - new.reload - assert_equal 4, new.pos - - new.insert_at(2) - assert_equal 2, new.pos - - new4.reload - assert_equal 4, new4.pos - - new5 = ListMixinSub1.create("parent_id" => 20) - assert_equal 5, new5.pos - - new5.insert_at(1) - assert_equal 1, new5.pos - - new4.reload - assert_equal 5, new4.pos - end - - def test_delete_middle - assert_equal [mixins(:list_sub_1), - mixins(:list_sub_2), - mixins(:list_sub_3), - mixins(:list_sub_4)], - ListMixin.find(:all, :conditions => 'parent_id = 5000', :order => 'pos') - - mixins(:list_sub_2).destroy - - assert_equal [mixins(:list_sub_1, :reload), - mixins(:list_sub_3, :reload), - mixins(:list_sub_4, :reload)], - ListMixin.find(:all, :conditions => 'parent_id = 5000', :order => 'pos') - - assert_equal 1, mixins(:list_sub_1).pos - assert_equal 2, mixins(:list_sub_3).pos - assert_equal 3, mixins(:list_sub_4).pos - - mixins(:list_sub_1).destroy - - assert_equal [mixins(:list_sub_3, :reload), - mixins(:list_sub_4, :reload)], - ListMixin.find(:all, :conditions => 'parent_id = 5000', :order => 'pos') - - assert_equal 1, mixins(:list_sub_3).pos - assert_equal 2, mixins(:list_sub_4).pos - - end - -end - diff --git a/tracks/vendor/rails/activerecord/test/modules_test.rb b/tracks/vendor/rails/activerecord/test/modules_test.rb deleted file mode 100644 index d34afbb8..00000000 --- a/tracks/vendor/rails/activerecord/test/modules_test.rb +++ /dev/null @@ -1,23 +0,0 @@ -require 'abstract_unit' -require 'fixtures/company_in_module' - -class ModulesTest < Test::Unit::TestCase - fixtures :accounts, :companies, :projects, :developers - - def test_module_spanning_associations - assert MyApplication::Business::Firm.find(:first).has_clients?, "Firm should have clients" - firm = MyApplication::Business::Firm.find(:first) - assert_nil firm.class.table_name.match('::'), "Firm shouldn't have the module appear in its table name" - assert_equal 2, firm.clients_count, "Firm should have two clients" - end - - def test_module_spanning_has_and_belongs_to_many_associations - project = MyApplication::Business::Project.find(:first) - project.developers << MyApplication::Business::Developer.create("name" => "John") - assert "John", project.developers.last.name - end - - def test_associations_spanning_cross_modules - assert MyApplication::Billing::Account.find(1).has_firm?, "37signals account should be able to backtrack" - end -end diff --git a/tracks/vendor/rails/activerecord/test/multiple_db_test.rb b/tracks/vendor/rails/activerecord/test/multiple_db_test.rb deleted file mode 100644 index df2ef106..00000000 --- a/tracks/vendor/rails/activerecord/test/multiple_db_test.rb +++ /dev/null @@ -1,60 +0,0 @@ -require 'abstract_unit' -require 'fixtures/entrant' - -# So we can test whether Course.connection survives a reload. -require_dependency 'fixtures/course' - -class MultipleDbTest < Test::Unit::TestCase - self.use_transactional_fixtures = false - - def setup - @courses = create_fixtures("courses") { Course.retrieve_connection } - @entrants = create_fixtures("entrants") - end - - def test_connected - assert_not_nil Entrant.connection - assert_not_nil Course.connection - end - - def test_proper_connection - assert_not_equal(Entrant.connection, Course.connection) - assert_equal(Entrant.connection, Entrant.retrieve_connection) - assert_equal(Course.connection, Course.retrieve_connection) - assert_equal(ActiveRecord::Base.connection, Entrant.connection) - end - - def test_find - c1 = Course.find(1) - assert_equal "Ruby Development", c1.name - c2 = Course.find(2) - assert_equal "Java Development", c2.name - e1 = Entrant.find(1) - assert_equal "Ruby Developer", e1.name - e2 = Entrant.find(2) - assert_equal "Ruby Guru", e2.name - e3 = Entrant.find(3) - assert_equal "Java Lover", e3.name - end - - def test_associations - c1 = Course.find(1) - assert_equal 2, c1.entrants_count - e1 = Entrant.find(1) - assert_equal e1.course.id, c1.id - c2 = Course.find(2) - assert_equal 1, c2.entrants_count - e3 = Entrant.find(3) - assert_equal e3.course.id, c2.id - end - - def test_course_connection_should_survive_dependency_reload - assert Course.connection - - Dependencies.clear - Object.send(:remove_const, :Course) - require_dependency 'fixtures/course' - - assert Course.connection - end -end diff --git a/tracks/vendor/rails/activerecord/test/pk_test.rb b/tracks/vendor/rails/activerecord/test/pk_test.rb deleted file mode 100644 index 839a784e..00000000 --- a/tracks/vendor/rails/activerecord/test/pk_test.rb +++ /dev/null @@ -1,80 +0,0 @@ -require "#{File.dirname(__FILE__)}/abstract_unit" -require 'fixtures/topic' -require 'fixtures/subscriber' -require 'fixtures/movie' -require 'fixtures/keyboard' - -class PrimaryKeysTest < Test::Unit::TestCase - fixtures :topics, :subscribers, :movies - - def test_integer_key - topic = Topic.find(1) - assert_equal(topics(:first).author_name, topic.author_name) - topic = Topic.find(2) - assert_equal(topics(:second).author_name, topic.author_name) - - topic = Topic.new - topic.title = "New Topic" - assert_equal(nil, topic.id) - assert_nothing_raised { topic.save! } - id = topic.id - - topicReloaded = Topic.find(id) - assert_equal("New Topic", topicReloaded.title) - end - - def test_customized_primary_key_auto_assigns_on_save - Keyboard.delete_all - keyboard = Keyboard.new(:name => 'HHKB') - assert_nothing_raised { keyboard.save! } - assert_equal keyboard.id, Keyboard.find_by_name('HHKB').id - end - - def test_customized_primary_key_can_be_get_before_saving - keyboard = Keyboard.new - assert_nil keyboard.id - assert_nothing_raised { assert_nil keyboard.key_number } - end - - def test_customized_string_primary_key_settable_before_save - subscriber = Subscriber.new - assert_nothing_raised { subscriber.id = 'webster123' } - assert_equal 'webster123', subscriber.id - assert_equal 'webster123', subscriber.nick - end - - def test_string_key - subscriber = Subscriber.find(subscribers(:first).nick) - assert_equal(subscribers(:first).name, subscriber.name) - subscriber = Subscriber.find(subscribers(:second).nick) - assert_equal(subscribers(:second).name, subscriber.name) - - subscriber = Subscriber.new - subscriber.id = "jdoe" - assert_equal("jdoe", subscriber.id) - subscriber.name = "John Doe" - assert_nothing_raised { subscriber.save! } - assert_equal("jdoe", subscriber.id) - - subscriberReloaded = Subscriber.find("jdoe") - assert_equal("John Doe", subscriberReloaded.name) - end - - def test_find_with_more_than_one_string_key - assert_equal 2, Subscriber.find(subscribers(:first).nick, subscribers(:second).nick).length - end - - def test_primary_key_prefix - ActiveRecord::Base.primary_key_prefix_type = :table_name - Topic.reset_primary_key - assert_equal "topicid", Topic.primary_key - - ActiveRecord::Base.primary_key_prefix_type = :table_name_with_underscore - Topic.reset_primary_key - assert_equal "topic_id", Topic.primary_key - - ActiveRecord::Base.primary_key_prefix_type = nil - Topic.reset_primary_key - assert_equal "id", Topic.primary_key - end -end diff --git a/tracks/vendor/rails/activerecord/test/readonly_test.rb b/tracks/vendor/rails/activerecord/test/readonly_test.rb deleted file mode 100644 index bd9b8ef1..00000000 --- a/tracks/vendor/rails/activerecord/test/readonly_test.rb +++ /dev/null @@ -1,101 +0,0 @@ -require 'abstract_unit' -require 'fixtures/post' -require 'fixtures/comment' -require 'fixtures/developer' -require 'fixtures/project' - -# Dummy class methods to test implicit association scoping. -def Comment.foo() find :first end -def Project.foo() find :first end - - -class ReadOnlyTest < Test::Unit::TestCase - fixtures :posts, :comments, :developers, :projects, :developers_projects - - def test_cant_save_readonly_record - dev = Developer.find(1) - assert !dev.readonly? - - dev.readonly! - assert dev.readonly? - - assert_nothing_raised do - dev.name = 'Luscious forbidden fruit.' - assert !dev.save - dev.name = 'Forbidden.' - end - assert_raise(ActiveRecord::ReadOnlyRecord) { dev.save } - assert_raise(ActiveRecord::ReadOnlyRecord) { dev.save! } - end - - - def test_find_with_readonly_option - Developer.find(:all).each { |d| assert !d.readonly? } - Developer.find(:all, :readonly => false).each { |d| assert !d.readonly? } - Developer.find(:all, :readonly => true).each { |d| assert d.readonly? } - end - - - def test_find_with_joins_option_implies_readonly - # Blank joins don't count. - Developer.find(:all, :joins => ' ').each { |d| assert !d.readonly? } - Developer.find(:all, :joins => ' ', :readonly => false).each { |d| assert !d.readonly? } - - # Others do. - Developer.find(:all, :joins => ', projects').each { |d| assert d.readonly? } - Developer.find(:all, :joins => ', projects', :readonly => false).each { |d| assert !d.readonly? } - end - - - def test_habtm_find_readonly - dev = Developer.find(1) - assert !dev.projects.empty? - dev.projects.each { |p| assert !p.readonly? } - dev.projects.find(:all) { |p| assert !p.readonly? } - dev.projects.find(:all, :readonly => true) { |p| assert p.readonly? } - end - - def test_has_many_find_readonly - post = Post.find(1) - assert !post.comments.empty? - post.comments.each { |r| assert !r.readonly? } - post.comments.find(:all) { |r| assert !r.readonly? } - post.comments.find(:all, :readonly => true) { |r| assert r.readonly? } - end - - - def test_readonly_scoping - Post.with_scope(:find => { :conditions => '1=1' }) do - assert !Post.find(1).readonly? - assert Post.find(1, :readonly => true).readonly? - assert !Post.find(1, :readonly => false).readonly? - end - - Post.with_scope(:find => { :joins => ' ' }) do - assert !Post.find(1).readonly? - assert Post.find(1, :readonly => true).readonly? - assert !Post.find(1, :readonly => false).readonly? - end - - # Oracle barfs on this because the join includes unqualified and - # conflicting column names - unless current_adapter?(:OCIAdapter) - Post.with_scope(:find => { :joins => ', developers' }) do - assert Post.find(1).readonly? - assert Post.find(1, :readonly => true).readonly? - assert !Post.find(1, :readonly => false).readonly? - end - end - - Post.with_scope(:find => { :readonly => true }) do - assert Post.find(1).readonly? - assert Post.find(1, :readonly => true).readonly? - assert !Post.find(1, :readonly => false).readonly? - end - end - - def test_association_collection_method_missing_scoping_not_readonly - assert !Developer.find(1).projects.foo.readonly? - assert !Post.find(1).comments.foo.readonly? - end -end diff --git a/tracks/vendor/rails/activerecord/test/reflection_test.rb b/tracks/vendor/rails/activerecord/test/reflection_test.rb deleted file mode 100644 index c3117b8c..00000000 --- a/tracks/vendor/rails/activerecord/test/reflection_test.rb +++ /dev/null @@ -1,97 +0,0 @@ -require 'abstract_unit' -require 'fixtures/topic' -require 'fixtures/customer' -require 'fixtures/company' -require 'fixtures/company_in_module' - -class ReflectionTest < Test::Unit::TestCase - fixtures :topics, :customers, :companies - - def setup - @first = Topic.find(1) - end - - def test_read_attribute_names - assert_equal( - %w( id title author_name author_email_address bonus_time written_on last_read content approved replies_count parent_id type ).sort, - @first.attribute_names - ) - end - - def test_columns - assert_equal 12, Topic.columns.length - end - - def test_columns_are_returned_in_the_order_they_were_declared - column_names = Topic.columns.map { |column| column.name } - assert_equal %w(id title author_name author_email_address written_on bonus_time last_read content approved replies_count parent_id type), column_names - end - - def test_content_columns - content_columns = Topic.content_columns - content_column_names = content_columns.map {|column| column.name} - assert_equal 8, content_columns.length - assert_equal %w(title author_name author_email_address written_on bonus_time last_read content approved).sort, content_column_names.sort - end - - def test_column_string_type_and_limit - assert_equal :string, @first.column_for_attribute("title").type - assert_equal 255, @first.column_for_attribute("title").limit - end - - def test_human_name_for_column - assert_equal "Author name", @first.column_for_attribute("author_name").human_name - end - - def test_integer_columns - assert_equal :integer, @first.column_for_attribute("id").type - end - - def test_aggregation_reflection - reflection_for_address = ActiveRecord::Reflection::AggregateReflection.new( - :composed_of, :address, { :mapping => [ %w(address_street street), %w(address_city city), %w(address_country country) ] }, Customer - ) - - reflection_for_balance = ActiveRecord::Reflection::AggregateReflection.new( - :composed_of, :balance, { :class_name => "Money", :mapping => %w(balance amount) }, Customer - ) - - reflection_for_gps_location = ActiveRecord::Reflection::AggregateReflection.new( - :composed_of, :gps_location, { }, Customer - ) - - assert_equal( - [ reflection_for_address, reflection_for_balance, reflection_for_gps_location ], - Customer.reflect_on_all_aggregations - ) - - assert_equal reflection_for_address, Customer.reflect_on_aggregation(:address) - - assert_equal Address, Customer.reflect_on_aggregation(:address).klass - end - - def test_has_many_reflection - reflection_for_clients = ActiveRecord::Reflection::AssociationReflection.new(:has_many, :clients, { :order => "id", :dependent => true }, Firm) - - assert_equal reflection_for_clients, Firm.reflect_on_association(:clients) - - assert_equal Client, Firm.reflect_on_association(:clients).klass - assert_equal 'companies', Firm.reflect_on_association(:clients).table_name - - assert_equal Client, Firm.reflect_on_association(:clients_of_firm).klass - assert_equal 'companies', Firm.reflect_on_association(:clients_of_firm).table_name - end - - def test_has_one_reflection - reflection_for_account = ActiveRecord::Reflection::AssociationReflection.new(:has_one, :account, { :foreign_key => "firm_id", :dependent => true }, Firm) - assert_equal reflection_for_account, Firm.reflect_on_association(:account) - - assert_equal Account, Firm.reflect_on_association(:account).klass - assert_equal 'accounts', Firm.reflect_on_association(:account).table_name - end - - def test_association_reflection_in_modules - assert_equal MyApplication::Business::Client, MyApplication::Business::Firm.reflect_on_association(:clients_of_firm).klass - assert_equal MyApplication::Business::Firm, MyApplication::Billing::Account.reflect_on_association(:firm).klass - end -end diff --git a/tracks/vendor/rails/activerecord/test/schema_dumper_test.rb b/tracks/vendor/rails/activerecord/test/schema_dumper_test.rb deleted file mode 100644 index e24724c9..00000000 --- a/tracks/vendor/rails/activerecord/test/schema_dumper_test.rb +++ /dev/null @@ -1,19 +0,0 @@ -require 'abstract_unit' -require "#{File.dirname(__FILE__)}/../lib/active_record/schema_dumper" -require 'stringio' - -if ActiveRecord::Base.connection.respond_to?(:tables) - - class SchemaDumperTest < Test::Unit::TestCase - def test_schema_dump - stream = StringIO.new - ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, stream) - output = stream.string - - assert_match %r{create_table "accounts"}, output - assert_match %r{create_table "authors"}, output - assert_no_match %r{create_table "schema_info"}, output - end - end - -end diff --git a/tracks/vendor/rails/activerecord/test/schema_test_postgresql.rb b/tracks/vendor/rails/activerecord/test/schema_test_postgresql.rb deleted file mode 100644 index c743a861..00000000 --- a/tracks/vendor/rails/activerecord/test/schema_test_postgresql.rb +++ /dev/null @@ -1,64 +0,0 @@ -require 'abstract_unit' - -class SchemaTest < Test::Unit::TestCase - self.use_transactional_fixtures = false - - SCHEMA_NAME = 'test_schema' - TABLE_NAME = 'things' - COLUMNS = [ - 'id integer', - 'name character varying(50)', - 'moment timestamp without time zone default now()' - ] - - def setup - @connection = ActiveRecord::Base.connection - @connection.execute "CREATE SCHEMA #{SCHEMA_NAME} CREATE TABLE #{TABLE_NAME} (#{COLUMNS.join(',')})" - end - - def teardown - @connection.execute "DROP SCHEMA #{SCHEMA_NAME} CASCADE" - end - - def test_with_schema_prefixed_table_name - assert_nothing_raised do - assert_equal COLUMNS, columns("#{SCHEMA_NAME}.#{TABLE_NAME}") - end - end - - def test_with_schema_search_path - assert_nothing_raised do - with_schema_search_path(SCHEMA_NAME) do - assert_equal COLUMNS, columns(TABLE_NAME) - end - end - end - - def test_raise_on_unquoted_schema_name - assert_raise(ActiveRecord::StatementInvalid) do - with_schema_search_path '$user,public' - end - end - - def test_without_schema_search_path - assert_raise(ActiveRecord::StatementInvalid) { columns(TABLE_NAME) } - end - - def test_ignore_nil_schema_search_path - assert_nothing_raised { with_schema_search_path nil } - end - - private - def columns(table_name) - @connection.send(:column_definitions, table_name).map do |name, type, default| - "#{name} #{type}" + (default ? " default #{default}" : '') - end - end - - def with_schema_search_path(schema_search_path) - @connection.schema_search_path = schema_search_path - yield if block_given? - ensure - @connection.schema_search_path = "'$user', public" - end -end diff --git a/tracks/vendor/rails/activerecord/test/synonym_test_oci.rb b/tracks/vendor/rails/activerecord/test/synonym_test_oci.rb deleted file mode 100644 index 4d4776c3..00000000 --- a/tracks/vendor/rails/activerecord/test/synonym_test_oci.rb +++ /dev/null @@ -1,17 +0,0 @@ -require 'abstract_unit' -require 'fixtures/topic' -require 'fixtures/subject' - -# confirm that synonyms work just like tables; in this case -# the "subjects" table in Oracle (defined in oci.sql) is just -# a synonym to the "topics" table - -class TestOracleSynonym < Test::Unit::TestCase - - def test_oracle_synonym - topic = Topic.new - subject = Subject.new - assert_equal(topic.attributes, subject.attributes) - end - -end diff --git a/tracks/vendor/rails/activerecord/test/threaded_connections_test.rb b/tracks/vendor/rails/activerecord/test/threaded_connections_test.rb deleted file mode 100644 index 177c6c7e..00000000 --- a/tracks/vendor/rails/activerecord/test/threaded_connections_test.rb +++ /dev/null @@ -1,35 +0,0 @@ -require 'abstract_unit' -require 'fixtures/topic' - -class ThreadedConnectionsTest < Test::Unit::TestCase - self.use_transactional_fixtures = false - - fixtures :topics - - def setup - @connection = ActiveRecord::Base.remove_connection - @connections = [] - end - - def gather_connections(use_threaded_connections) - ActiveRecord::Base.allow_concurrency = use_threaded_connections - ActiveRecord::Base.establish_connection(@connection) - - 5.times do - Thread.new do - Topic.find :first - @connections << ActiveRecord::Base.active_connections.values.first - end.join - end - end - - def test_threaded_connections - gather_connections(true) - assert_equal @connections.uniq.length, 5 - end - - def test_unthreaded_connections - gather_connections(false) - assert_equal @connections.uniq.length, 1 - end -end diff --git a/tracks/vendor/rails/activerecord/test/transactions_test.rb b/tracks/vendor/rails/activerecord/test/transactions_test.rb deleted file mode 100644 index 0048e24b..00000000 --- a/tracks/vendor/rails/activerecord/test/transactions_test.rb +++ /dev/null @@ -1,216 +0,0 @@ -require 'abstract_unit' -require 'fixtures/topic' -require 'fixtures/developer' - -class TransactionTest < Test::Unit::TestCase - self.use_transactional_fixtures = false - - fixtures :topics, :developers - - def setup - # sqlite does not seem to return these in the right order, so we sort them - # explicitly for sqlite's sake. sqlite3 does fine. - @first, @second = Topic.find(1, 2).sort_by { |t| t.id } - end - - def test_successful - Topic.transaction do - @first.approved = true - @second.approved = false - @first.save - @second.save - end - - assert Topic.find(1).approved?, "First should have been approved" - assert !Topic.find(2).approved?, "Second should have been unapproved" - end - - def transaction_with_return - Topic.transaction do - @first.approved = true - @second.approved = false - @first.save - @second.save - return - end - end - - def test_successful_with_return - class << Topic.connection - alias :real_commit_db_transaction :commit_db_transaction - def commit_db_transaction - $committed = true - real_commit_db_transaction - end - end - - $committed = false - transaction_with_return - assert $committed - - assert Topic.find(1).approved?, "First should have been approved" - assert !Topic.find(2).approved?, "Second should have been unapproved" - ensure - class << Topic.connection - alias :commit_db_transaction :real_commit_db_transaction rescue nil - end - end - - def test_successful_with_instance_method - @first.transaction do - @first.approved = true - @second.approved = false - @first.save - @second.save - end - - assert Topic.find(1).approved?, "First should have been approved" - assert !Topic.find(2).approved?, "Second should have been unapproved" - end - - def test_failing_on_exception - begin - Topic.transaction do - @first.approved = true - @second.approved = false - @first.save - @second.save - raise "Bad things!" - end - rescue - # caught it - end - - assert @first.approved?, "First should still be changed in the objects" - assert !@second.approved?, "Second should still be changed in the objects" - - assert !Topic.find(1).approved?, "First shouldn't have been approved" - assert Topic.find(2).approved?, "Second should still be approved" - end - - def test_failing_with_object_rollback - assert !@first.approved?, "First should be unapproved initially" - - begin - Topic.transaction(@first, @second) do - @first.approved = true - @second.approved = false - @first.save - @second.save - raise "Bad things!" - end - rescue - # caught it - end - - assert !@first.approved?, "First shouldn't have been approved" - assert @second.approved?, "Second should still be approved" - end - - def test_callback_rollback_in_save - add_exception_raising_after_save_callback_to_topic - - begin - @first.approved = true - @first.save - flunk - rescue => e - assert_equal "Make the transaction rollback", e.message - assert !Topic.find(1).approved? - ensure - remove_exception_raising_after_save_callback_to_topic - end - end - - def test_nested_explicit_transactions - Topic.transaction do - Topic.transaction do - @first.approved = true - @second.approved = false - @first.save - @second.save - end - end - - assert Topic.find(1).approved?, "First should have been approved" - assert !Topic.find(2).approved?, "Second should have been unapproved" - end - - # This will cause transactions to overlap and fail unless they are - # performed on separate database connections. - def test_transaction_per_thread - assert_nothing_raised do - threads = (1..20).map do - Thread.new do - Topic.transaction do - topic = Topic.find(:first) - topic.approved = !topic.approved? - topic.save! - topic.approved = !topic.approved? - topic.save! - end - end - end - - threads.each { |t| t.join } - end - end - - # Test for dirty reads among simultaneous transactions. - def test_transaction_isolation__read_committed - # Should be invariant. - original_salary = Developer.find(1).salary - temporary_salary = 200000 - - assert_nothing_raised do - threads = (1..20).map do - Thread.new do - Developer.transaction do - # Expect original salary. - dev = Developer.find(1) - assert_equal original_salary, dev.salary - - dev.salary = temporary_salary - dev.save! - - # Expect temporary salary. - dev = Developer.find(1) - assert_equal temporary_salary, dev.salary - - dev.salary = original_salary - dev.save! - - # Expect original salary. - dev = Developer.find(1) - assert_equal original_salary, dev.salary - end - end - end - - # Keep our eyes peeled. - threads << Thread.new do - 10.times do - sleep 0.05 - Developer.transaction do - # Always expect original salary. - assert_equal original_salary, Developer.find(1).salary - end - end - end - - threads.each { |t| t.join } - end - - assert_equal original_salary, Developer.find(1).salary - end - - - private - def add_exception_raising_after_save_callback_to_topic - Topic.class_eval { def after_save() raise "Make the transaction rollback" end } - end - - def remove_exception_raising_after_save_callback_to_topic - Topic.class_eval { remove_method :after_save } - end -end diff --git a/tracks/vendor/rails/activerecord/test/unconnected_test.rb b/tracks/vendor/rails/activerecord/test/unconnected_test.rb deleted file mode 100644 index df656ec7..00000000 --- a/tracks/vendor/rails/activerecord/test/unconnected_test.rb +++ /dev/null @@ -1,25 +0,0 @@ -require 'abstract_unit' - -class TestRecord < ActiveRecord::Base -end - -class TestUnconnectedAdaptor < Test::Unit::TestCase - self.use_transactional_fixtures = false - - def setup - @connection = ActiveRecord::Base.remove_connection - end - - def teardown - ActiveRecord::Base.establish_connection(@connection) - end - - def test_unconnected - assert_raise(ActiveRecord::ConnectionNotEstablished) do - TestRecord.find(1) - end - assert_raise(ActiveRecord::ConnectionNotEstablished) do - TestRecord.new.save - end - end -end diff --git a/tracks/vendor/rails/activerecord/test/validations_test.rb b/tracks/vendor/rails/activerecord/test/validations_test.rb deleted file mode 100644 index f0d75c96..00000000 --- a/tracks/vendor/rails/activerecord/test/validations_test.rb +++ /dev/null @@ -1,840 +0,0 @@ -require 'abstract_unit' -require 'fixtures/topic' -require 'fixtures/reply' -require 'fixtures/developer' - -# The following methods in Topic are used in test_conditional_validation_* -class Topic - def condition_is_true - return true - end - - def condition_is_true_but_its_not - return false - end -end - -class ValidationsTest < Test::Unit::TestCase - fixtures :topics, :developers - - def setup - Topic.write_inheritable_attribute(:validate, nil) - Topic.write_inheritable_attribute(:validate_on_create, nil) - Topic.write_inheritable_attribute(:validate_on_update, nil) - end - - def test_single_field_validation - r = Reply.new - r.title = "There's no content!" - assert !r.save, "A reply without content shouldn't be saveable" - - r.content = "Messa content!" - assert r.save, "A reply with content should be saveable" - end - - def test_single_attr_validation_and_error_msg - r = Reply.new - r.title = "There's no content!" - r.save - assert r.errors.invalid?("content"), "A reply without content should mark that attribute as invalid" - assert_equal "Empty", r.errors.on("content"), "A reply without content should contain an error" - assert_equal 1, r.errors.count - end - - def test_double_attr_validation_and_error_msg - r = Reply.new - assert !r.save - - assert r.errors.invalid?("title"), "A reply without title should mark that attribute as invalid" - assert_equal "Empty", r.errors.on("title"), "A reply without title should contain an error" - - assert r.errors.invalid?("content"), "A reply without content should mark that attribute as invalid" - assert_equal "Empty", r.errors.on("content"), "A reply without content should contain an error" - - assert_equal 2, r.errors.count - end - - def test_error_on_create - r = Reply.new - r.title = "Wrong Create" - assert !r.save - assert r.errors.invalid?("title"), "A reply with a bad title should mark that attribute as invalid" - assert_equal "is Wrong Create", r.errors.on("title"), "A reply with a bad content should contain an error" - end - - def test_error_on_update - r = Reply.new - r.title = "Bad" - r.content = "Good" - assert r.save, "First save should be successful" - - r.title = "Wrong Update" - assert !r.save, "Second save should fail" - - assert r.errors.invalid?("title"), "A reply with a bad title should mark that attribute as invalid" - assert_equal "is Wrong Update", r.errors.on("title"), "A reply with a bad content should contain an error" - end - - def test_invalid_record_exception - assert_raises(ActiveRecord::RecordInvalid) { Reply.create! } - assert_raises(ActiveRecord::RecordInvalid) { Reply.new.save! } - - begin - r = Reply.new - r.save! - flunk - rescue ActiveRecord::RecordInvalid => invalid - assert_equal r, invalid.record - end - end - - def test_single_error_per_attr_iteration - r = Reply.new - r.save - - errors = [] - r.errors.each { |attr, msg| errors << [attr, msg] } - - assert errors.include?(["title", "Empty"]) - assert errors.include?(["content", "Empty"]) - end - - def test_multiple_errors_per_attr_iteration_with_full_error_composition - r = Reply.new - r.title = "Wrong Create" - r.content = "Mismatch" - r.save - - errors = [] - r.errors.each_full { |error| errors << error } - - assert_equal "Title is Wrong Create", errors[0] - assert_equal "Title is Content Mismatch", errors[1] - assert_equal 2, r.errors.count - end - - def test_errors_on_base - r = Reply.new - r.content = "Mismatch" - r.save - r.errors.add_to_base "Reply is not dignifying" - - errors = [] - r.errors.each_full { |error| errors << error } - - assert_equal "Reply is not dignifying", r.errors.on_base - - assert errors.include?("Title Empty") - assert errors.include?("Reply is not dignifying") - assert_equal 2, r.errors.count - end - - def test_create_without_validation - reply = Reply.new - assert !reply.save - assert reply.save(false) - end - - def test_validates_each - perform = true - hits = 0 - Topic.validates_each(:title, :content, [:title, :content]) do |record, attr| - if perform - record.errors.add attr, 'gotcha' - hits += 1 - end - end - t = Topic.new("title" => "valid", "content" => "whatever") - assert !t.save - assert_equal 4, hits - assert_equal %w(gotcha gotcha), t.errors.on(:title) - assert_equal %w(gotcha gotcha), t.errors.on(:content) - ensure - perform = false - end - - def test_errors_on_boundary_breaking - developer = Developer.new("name" => "xs") - assert !developer.save - assert_equal "is too short (min is 3 characters)", developer.errors.on("name") - - developer.name = "All too very long for this boundary, it really is" - assert !developer.save - assert_equal "is too long (max is 20 characters)", developer.errors.on("name") - - developer.name = "Just right" - assert developer.save - end - - def test_title_confirmation_no_confirm - Topic.validates_confirmation_of(:title) - - t = Topic.create("title" => "We should not be confirmed") - assert t.save - end - - def test_title_confirmation - Topic.validates_confirmation_of(:title) - - t = Topic.create("title" => "We should be confirmed","title_confirmation" => "") - assert !t.save - - t.title_confirmation = "We should be confirmed" - assert t.save - end - - def test_terms_of_service_agreement_no_acceptance - Topic.validates_acceptance_of(:terms_of_service, :on => :create) - - t = Topic.create("title" => "We should not be confirmed") - assert t.save - end - - def test_terms_of_service_agreement - Topic.validates_acceptance_of(:terms_of_service, :on => :create) - - t = Topic.create("title" => "We should be confirmed","terms_of_service" => "") - assert !t.save - assert_equal "must be accepted", t.errors.on(:terms_of_service) - - t.terms_of_service = "1" - assert t.save - end - - - def test_eula - Topic.validates_acceptance_of(:eula, :message => "must be abided", :on => :create) - - t = Topic.create("title" => "We should be confirmed","eula" => "") - assert !t.save - assert_equal "must be abided", t.errors.on(:eula) - - t.eula = "1" - assert t.save - end - - def test_terms_of_service_agreement_with_accept_value - Topic.validates_acceptance_of(:terms_of_service, :on => :create, :accept => "I agree.") - - t = Topic.create("title" => "We should be confirmed", "terms_of_service" => "") - assert !t.save - assert_equal "must be accepted", t.errors.on(:terms_of_service) - - t.terms_of_service = "I agree." - assert t.save - end - - def test_validate_presences - Topic.validates_presence_of(:title, :content) - - t = Topic.create - assert !t.save - assert_equal "can't be blank", t.errors.on(:title) - assert_equal "can't be blank", t.errors.on(:content) - - t.title = "something" - t.content = " " - - assert !t.save - assert_equal "can't be blank", t.errors.on(:content) - - t.content = "like stuff" - - assert t.save - end - - def test_validate_uniqueness - Topic.validates_uniqueness_of(:title) - - t = Topic.new("title" => "I'm unique!") - assert t.save, "Should save t as unique" - - t.content = "Remaining unique" - assert t.save, "Should still save t as unique" - - t2 = Topic.new("title" => "I'm unique!") - assert !t2.valid?, "Shouldn't be valid" - assert !t2.save, "Shouldn't save t2 as unique" - assert_equal "has already been taken", t2.errors.on(:title) - - t2.title = "Now Im really also unique" - assert t2.save, "Should now save t2 as unique" - end - - def test_validate_uniqueness_with_scope - Reply.validates_uniqueness_of(:content, :scope => "parent_id") - - t = Topic.create("title" => "I'm unique!") - - r1 = t.replies.create "title" => "r1", "content" => "hello world" - assert r1.valid?, "Saving r1" - - r2 = t.replies.create "title" => "r2", "content" => "hello world" - assert !r2.valid?, "Saving r2 first time" - - r2.content = "something else" - assert r2.save, "Saving r2 second time" - - t2 = Topic.create("title" => "I'm unique too!") - r3 = t2.replies.create "title" => "r3", "content" => "hello world" - assert r3.valid?, "Saving r3" - end - - def test_validate_format - Topic.validates_format_of(:title, :content, :with => /^Validation\smacros \w+!$/, :message => "is bad data") - - t = Topic.create("title" => "i'm incorrect", "content" => "Validation macros rule!") - assert !t.valid?, "Shouldn't be valid" - assert !t.save, "Shouldn't save because it's invalid" - assert_equal "is bad data", t.errors.on(:title) - assert_nil t.errors.on(:content) - - t.title = "Validation macros rule!" - - assert t.save - assert_nil t.errors.on(:title) - - assert_raise(ArgumentError) { Topic.validates_format_of(:title, :content) } - end - - def test_validates_inclusion_of - Topic.validates_inclusion_of( :title, :in => %w( a b c d e f g ) ) - - assert !Topic.create("title" => "a!", "content" => "abc").valid? - assert !Topic.create("title" => "a b", "content" => "abc").valid? - assert !Topic.create("title" => nil, "content" => "def").valid? - - t = Topic.create("title" => "a", "content" => "I know you are but what am I?") - assert t.valid? - t.title = "uhoh" - assert !t.valid? - assert t.errors.on(:title) - assert_equal "is not included in the list", t.errors["title"] - - assert_raise(ArgumentError) { Topic.validates_inclusion_of( :title, :in => nil ) } - assert_raise(ArgumentError) { Topic.validates_inclusion_of( :title, :in => 0) } - - assert_nothing_raised(ArgumentError) { Topic.validates_inclusion_of( :title, :in => "hi!" ) } - assert_nothing_raised(ArgumentError) { Topic.validates_inclusion_of( :title, :in => {} ) } - assert_nothing_raised(ArgumentError) { Topic.validates_inclusion_of( :title, :in => [] ) } - end - - def test_validates_inclusion_of_with_allow_nil - Topic.validates_inclusion_of( :title, :in => %w( a b c d e f g ), :allow_nil=>true ) - - assert !Topic.create("title" => "a!", "content" => "abc").valid? - assert !Topic.create("title" => "", "content" => "abc").valid? - assert Topic.create("title" => nil, "content" => "abc").valid? - end - - def test_numericality_with_allow_nil_and_getter_method - Developer.validates_numericality_of( :salary, :allow_nil => true) - developer = Developer.new("name" => "michael", "salary" => nil) - developer.instance_eval("def salary; read_attribute('salary') ? read_attribute('salary') : 100000; end") - assert developer.valid? - end - - def test_validates_exclusion_of - Topic.validates_exclusion_of( :title, :in => %w( abe monkey ) ) - - assert Topic.create("title" => "something", "content" => "abc").valid? - assert !Topic.create("title" => "monkey", "content" => "abc").valid? - end - - def test_validates_length_of_using_minimum - Topic.validates_length_of :title, :minimum => 5 - - t = Topic.create("title" => "valid", "content" => "whatever") - assert t.valid? - - t.title = "not" - assert !t.valid? - assert t.errors.on(:title) - assert_equal "is too short (min is 5 characters)", t.errors["title"] - - t.title = "" - assert !t.valid? - assert t.errors.on(:title) - assert_equal "is too short (min is 5 characters)", t.errors["title"] - - t.title = nil - assert !t.valid? - assert t.errors.on(:title) - assert_equal "is too short (min is 5 characters)", t.errors["title"] - end - - def test_optionally_validates_length_of_using_minimum - Topic.validates_length_of :title, :minimum => 5, :allow_nil => true - - t = Topic.create("title" => "valid", "content" => "whatever") - assert t.valid? - - t.title = nil - assert t.valid? - end - - def test_validates_length_of_using_maximum - Topic.validates_length_of :title, :maximum => 5 - - t = Topic.create("title" => "valid", "content" => "whatever") - assert t.valid? - - t.title = "notvalid" - assert !t.valid? - assert t.errors.on(:title) - assert_equal "is too long (max is 5 characters)", t.errors["title"] - - t.title = "" - assert t.valid? - - t.title = nil - assert !t.valid? - end - - def test_optionally_validates_length_of_using_maximum - Topic.validates_length_of :title, :maximum => 5, :allow_nil => true - - t = Topic.create("title" => "valid", "content" => "whatever") - assert t.valid? - - t.title = nil - assert t.valid? - end - - def test_validates_length_of_using_within - Topic.validates_length_of(:title, :content, :within => 3..5) - - t = Topic.new("title" => "a!", "content" => "I'm ooooooooh so very long") - assert !t.valid? - assert_equal "is too short (min is 3 characters)", t.errors.on(:title) - assert_equal "is too long (max is 5 characters)", t.errors.on(:content) - - t.title = nil - t.content = nil - assert !t.valid? - assert_equal "is too short (min is 3 characters)", t.errors.on(:title) - assert_equal "is too short (min is 3 characters)", t.errors.on(:content) - - t.title = "abe" - t.content = "mad" - assert t.valid? - end - - def test_optionally_validates_length_of_using_within - Topic.validates_length_of :title, :content, :within => 3..5, :allow_nil => true - - t = Topic.create('title' => 'abc', 'content' => 'abcd') - assert t.valid? - - t.title = nil - assert t.valid? - end - - def test_optionally_validates_length_of_using_within_on_create - Topic.validates_length_of :title, :content, :within => 5..10, :on => :create, :too_long => "my string is too long: %d" - - t = Topic.create("title" => "thisisnotvalid", "content" => "whatever") - assert !t.save - assert t.errors.on(:title) - assert_equal "my string is too long: 10", t.errors[:title] - - t.title = "butthisis" - assert t.save - - t.title = "few" - assert t.save - - t.content = "andthisislong" - assert t.save - - t.content = t.title = "iamfine" - assert t.save - end - - def test_optionally_validates_length_of_using_within_on_update - Topic.validates_length_of :title, :content, :within => 5..10, :on => :update, :too_short => "my string is too short: %d" - - t = Topic.create("title" => "vali", "content" => "whatever") - assert !t.save - assert t.errors.on(:title) - - t.title = "not" - assert !t.save - assert t.errors.on(:title) - assert_equal "my string is too short: 5", t.errors[:title] - - t.title = "valid" - t.content = "andthisistoolong" - assert !t.save - assert t.errors.on(:content) - - t.content = "iamfine" - assert t.save - end - - def test_validates_length_of_using_is - Topic.validates_length_of :title, :is => 5 - - t = Topic.create("title" => "valid", "content" => "whatever") - assert t.valid? - - t.title = "notvalid" - assert !t.valid? - assert t.errors.on(:title) - assert_equal "is the wrong length (should be 5 characters)", t.errors["title"] - - t.title = "" - assert !t.valid? - - t.title = nil - assert !t.valid? - end - - def test_optionally_validates_length_of_using_is - Topic.validates_length_of :title, :is => 5, :allow_nil => true - - t = Topic.create("title" => "valid", "content" => "whatever") - assert t.valid? - - t.title = nil - assert t.valid? - end - - def test_validates_length_of_using_bignum - bigmin = 2 ** 30 - bigmax = 2 ** 32 - bigrange = bigmin...bigmax - assert_nothing_raised do - Topic.validates_length_of :title, :is => bigmin + 5 - Topic.validates_length_of :title, :within => bigrange - Topic.validates_length_of :title, :in => bigrange - Topic.validates_length_of :title, :minimum => bigmin - Topic.validates_length_of :title, :maximum => bigmax - end - end - - def test_validates_length_with_globaly_modified_error_message - ActiveRecord::Errors.default_error_messages[:too_short] = 'tu est trops petit hombre %d' - Topic.validates_length_of :title, :minimum => 10 - t = Topic.create(:title => 'too short') - assert !t.valid? - - assert_equal 'tu est trops petit hombre 10', t.errors['title'] - end - - def test_validates_size_of_association - assert_nothing_raised { Topic.validates_size_of :replies, :minimum => 1 } - t = Topic.new('title' => 'noreplies', 'content' => 'whatever') - assert !t.save - assert t.errors.on(:replies) - t.replies.create('title' => 'areply', 'content' => 'whateveragain') - assert t.valid? - end - - def test_validates_length_of_nasty_params - assert_raise(ArgumentError) { Topic.validates_length_of(:title, :minimum=>6, :maximum=>9) } - assert_raise(ArgumentError) { Topic.validates_length_of(:title, :within=>6, :maximum=>9) } - assert_raise(ArgumentError) { Topic.validates_length_of(:title, :within=>6, :minimum=>9) } - assert_raise(ArgumentError) { Topic.validates_length_of(:title, :within=>6, :is=>9) } - assert_raise(ArgumentError) { Topic.validates_length_of(:title, :minimum=>"a") } - assert_raise(ArgumentError) { Topic.validates_length_of(:title, :maximum=>"a") } - assert_raise(ArgumentError) { Topic.validates_length_of(:title, :within=>"a") } - assert_raise(ArgumentError) { Topic.validates_length_of(:title, :is=>"a") } - end - - def test_validates_length_of_custom_errors_for_minimum_with_message - Topic.validates_length_of( :title, :minimum=>5, :message=>"boo %d" ) - t = Topic.create("title" => "uhoh", "content" => "whatever") - assert !t.valid? - assert t.errors.on(:title) - assert_equal "boo 5", t.errors["title"] - end - - def test_validates_length_of_custom_errors_for_minimum_with_too_short - Topic.validates_length_of( :title, :minimum=>5, :too_short=>"hoo %d" ) - t = Topic.create("title" => "uhoh", "content" => "whatever") - assert !t.valid? - assert t.errors.on(:title) - assert_equal "hoo 5", t.errors["title"] - end - - def test_validates_length_of_custom_errors_for_maximum_with_message - Topic.validates_length_of( :title, :maximum=>5, :message=>"boo %d" ) - t = Topic.create("title" => "uhohuhoh", "content" => "whatever") - assert !t.valid? - assert t.errors.on(:title) - assert_equal "boo 5", t.errors["title"] - end - - def test_validates_length_of_custom_errors_for_maximum_with_too_long - Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %d" ) - t = Topic.create("title" => "uhohuhoh", "content" => "whatever") - assert !t.valid? - assert t.errors.on(:title) - assert_equal "hoo 5", t.errors["title"] - end - - def test_validates_length_of_custom_errors_for_is_with_message - Topic.validates_length_of( :title, :is=>5, :message=>"boo %d" ) - t = Topic.create("title" => "uhohuhoh", "content" => "whatever") - assert !t.valid? - assert t.errors.on(:title) - assert_equal "boo 5", t.errors["title"] - end - - def test_validates_length_of_custom_errors_for_is_with_wrong_length - Topic.validates_length_of( :title, :is=>5, :wrong_length=>"hoo %d" ) - t = Topic.create("title" => "uhohuhoh", "content" => "whatever") - assert !t.valid? - assert t.errors.on(:title) - assert_equal "hoo 5", t.errors["title"] - end - - def test_validates_associated_many - Topic.validates_associated( :replies ) - t = Topic.create("title" => "uhohuhoh", "content" => "whatever") - t.replies << [r = Reply.create("title" => "A reply"), r2 = Reply.create("title" => "Another reply")] - assert !t.valid? - assert t.errors.on(:replies) - assert_equal 1, r.errors.count # make sure all associated objects have been validated - assert_equal 1, r2.errors.count - r.content = r2.content = "non-empty" - assert t.valid? - end - - def test_validates_associated_one - Reply.validates_associated( :topic ) - Topic.validates_presence_of( :content ) - r = Reply.create("title" => "A reply", "content" => "with content!") - r.topic = Topic.create("title" => "uhohuhoh") - assert !r.valid? - assert r.errors.on(:topic) - r.topic.content = "non-empty" - assert r.valid? - end - - def test_validate_block - Topic.validate { |topic| topic.errors.add("title", "will never be valid") } - t = Topic.create("title" => "Title", "content" => "whatever") - assert !t.valid? - assert t.errors.on(:title) - assert_equal "will never be valid", t.errors["title"] - end - - def test_invalid_validator - Topic.validate 3 - assert_raise(ActiveRecord::ActiveRecordError) { t = Topic.create } - end - - def test_throw_away_typing - d = Developer.create "name" => "David", "salary" => "100,000" - assert !d.valid? - assert_equal 100, d.salary - assert_equal "100,000", d.salary_before_type_cast - end - - def test_validates_acceptance_of_with_custom_error_using_quotes - Developer.validates_acceptance_of :salary, :message=> "This string contains 'single' and \"double\" quotes" - d = Developer.new - d.salary = "0" - assert !d.valid? - assert_equal d.errors.on(:salary).first, "This string contains 'single' and \"double\" quotes" - end - - def test_validates_confirmation_of_with_custom_error_using_quotes - Developer.validates_confirmation_of :name, :message=> "This string contains 'single' and \"double\" quotes" - d = Developer.new - d.name = "John" - d.name_confirmation = "Johnny" - assert !d.valid? - assert_equal d.errors.on(:name), "This string contains 'single' and \"double\" quotes" - end - - def test_validates_format_of_with_custom_error_using_quotes - Developer.validates_format_of :name, :with => /^(A-Z*)$/, :message=> "This string contains 'single' and \"double\" quotes" - d = Developer.new - d.name = "John 32" - assert !d.valid? - assert_equal d.errors.on(:name), "This string contains 'single' and \"double\" quotes" - end - - def test_validates_inclusion_of_with_custom_error_using_quotes - Developer.validates_inclusion_of :salary, :in => 1000..80000, :message=> "This string contains 'single' and \"double\" quotes" - d = Developer.new - d.salary = "90,000" - assert !d.valid? - assert_equal d.errors.on(:salary).first, "This string contains 'single' and \"double\" quotes" - end - - def test_validates_length_of_with_custom_too_long_using_quotes - Developer.validates_length_of :name, :maximum => 4, :too_long=> "This string contains 'single' and \"double\" quotes" - d = Developer.new - d.name = "Jeffrey" - assert !d.valid? - assert_equal d.errors.on(:name).first, "This string contains 'single' and \"double\" quotes" - end - - def test_validates_length_of_with_custom_too_short_using_quotes - Developer.validates_length_of :name, :minimum => 4, :too_short=> "This string contains 'single' and \"double\" quotes" - d = Developer.new - d.name = "Joe" - assert !d.valid? - assert_equal d.errors.on(:name).first, "This string contains 'single' and \"double\" quotes" - end - - def test_validates_length_of_with_custom_message_using_quotes - Developer.validates_length_of :name, :minimum => 4, :message=> "This string contains 'single' and \"double\" quotes" - d = Developer.new - d.name = "Joe" - assert !d.valid? - assert_equal d.errors.on(:name).first, "This string contains 'single' and \"double\" quotes" - end - - def test_validates_presence_of_with_custom_message_using_quotes - Developer.validates_presence_of :non_existent, :message=> "This string contains 'single' and \"double\" quotes" - d = Developer.new - d.name = "Joe" - assert !d.valid? - assert_equal d.errors.on(:non_existent), "This string contains 'single' and \"double\" quotes" - end - - def test_validates_uniqueness_of_with_custom_message_using_quotes - Developer.validates_uniqueness_of :name, :message=> "This string contains 'single' and \"double\" quotes" - d = Developer.new - d.name = "David" - assert !d.valid? - assert_equal d.errors.on(:name).first, "This string contains 'single' and \"double\" quotes" - end - - def test_validates_associated_with_custom_message_using_quotes - Reply.validates_associated :topic, :message=> "This string contains 'single' and \"double\" quotes" - Topic.validates_presence_of :content - r = Reply.create("title" => "A reply", "content" => "with content!") - r.topic = Topic.create("title" => "uhohuhoh") - assert !r.valid? - assert_equal r.errors.on(:topic).first, "This string contains 'single' and \"double\" quotes" - end - - def test_conditional_validation_using_method_true - # When the method returns true - Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %d", :if => :condition_is_true ) - t = Topic.create("title" => "uhohuhoh", "content" => "whatever") - assert !t.valid? - assert t.errors.on(:title) - assert_equal "hoo 5", t.errors["title"] - end - - def test_conditional_validation_using_method_false - # When the method returns false - Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %d", :if => :condition_is_true_but_its_not ) - t = Topic.create("title" => "uhohuhoh", "content" => "whatever") - assert t.valid? - assert !t.errors.on(:title) - end - - def test_conditional_validation_using_string_true - # When the evaluated string returns true - Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %d", :if => "a = 1; a == 1" ) - t = Topic.create("title" => "uhohuhoh", "content" => "whatever") - assert !t.valid? - assert t.errors.on(:title) - assert_equal "hoo 5", t.errors["title"] - end - - def test_conditional_validation_using_string_false - # When the evaluated string returns false - Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %d", :if => "false") - t = Topic.create("title" => "uhohuhoh", "content" => "whatever") - assert t.valid? - assert !t.errors.on(:title) - end - - def test_conditional_validation_using_block_true - # When the block returns true - Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %d", - :if => Proc.new { |r| r.content.size > 4 } ) - t = Topic.create("title" => "uhohuhoh", "content" => "whatever") - assert !t.valid? - assert t.errors.on(:title) - assert_equal "hoo 5", t.errors["title"] - end - - def test_conditional_validation_using_block_false - # When the block returns false - Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %d", - :if => Proc.new { |r| r.title != "uhohuhoh"} ) - t = Topic.create("title" => "uhohuhoh", "content" => "whatever") - assert t.valid? - assert !t.errors.on(:title) - end - - def test_validates_associated_missing - Reply.validates_presence_of(:topic) - r = Reply.create("title" => "A reply", "content" => "with content!") - assert !r.valid? - assert r.errors.on(:topic) - - r.topic = Topic.find :first - assert r.valid? - end -end - - -class ValidatesNumericalityTest - NIL = [nil, "", " ", " \t \r \n"] - FLOAT_STRINGS = %w(0.0 +0.0 -0.0 10.0 10.5 -10.5 -0.0001 -090.1) - INTEGER_STRINGS = %w(0 +0 -0 10 +10 -10 0090 -090) - FLOATS = [0.0, 10.0, 10.5, -10.5, -0.0001] + FLOAT_STRINGS - INTEGERS = [0, 10, -10] + INTEGER_STRINGS - JUNK = ["not a number", "42 not a number", "0xdeadbeef", "00-1", "--3", "+-3", "+3-1", "-+019.0", "12.12.13.12"] - - def setup - Topic.write_inheritable_attribute(:validate, nil) - Topic.write_inheritable_attribute(:validate_on_create, nil) - Topic.write_inheritable_attribute(:validate_on_update, nil) - end - - def test_default_validates_numericality_of - Topic.validates_numericality_of :approved - - invalid!(NIL + JUNK) - valid!(FLOATS + INTEGERS) - end - - def test_validates_numericality_of_with_nil_allowed - Topic.validates_numericality_of :approved, :allow_nil => true - - invalid!(JUNK) - valid!(NIL + FLOATS + INTEGERS) - end - - def test_validates_numericality_of_with_integer_only - Topic.validates_numericality_of :approved, :only_integer => true - - invalid!(NIL + JUNK + FLOATS) - valid!(INTEGERS) - end - - def test_validates_numericality_of_with_integer_only_and_nil_allowed - Topic.validates_numericality_of :approved, :only_integer => true, :allow_nil => true - - invalid!(JUNK + FLOATS) - valid!(NIL + INTEGERS) - end - - private - def invalid!(values) - values.each do |value| - topic = Topic.create("title" => "numeric test", "content" => "whatever", "approved" => value) - assert !topic.valid?, "#{value} not rejected as a number" - assert topic.errors.on(:approved) - end - end - - def valid!(values) - values.each do |value| - topic = Topic.create("title" => "numeric test", "content" => "whatever", "approved" => value) - assert topic.valid?, "#{value} not accepted as a number" - end - end -end diff --git a/tracks/vendor/rails/activesupport/CHANGELOG b/tracks/vendor/rails/activesupport/CHANGELOG deleted file mode 100644 index b94063ea..00000000 --- a/tracks/vendor/rails/activesupport/CHANGELOG +++ /dev/null @@ -1,288 +0,0 @@ -*1.2.5* (December 13th, 2005) - -* Become part of Rails 1.0 - - -*1.2.4* (December 7th, 2005) - -* Rename Version constant to VERSION. #2802 [Marcel Molina Jr.] - - -*1.2.3* (November 7th, 2005) - -* Change Inflector#constantize to use eval instead of const_get. [Nicholas Seckar] - -* Fix const_missing handler to ignore the trailing '.rb' on files when comparing paths. [Nicholas Seckar] - -* Define kernel.rb methods in "class Object" instead of "module Kernel" to work around a Windows peculiarity [Sam Stephenson] - -* Fix broken tests caused by incomplete loading of active support. [Nicholas Seckar] - -* Fix status pluralization bug so status_codes doesn't get pluralized as statuses_code. #2758 [keithm@infused.org] - -* Added Kernel#silence_stderr to silence stderr for the duration of the given block [Sam Stephenson] - -* Changed Kernel#` to print a message to stderr (like Unix) instead of raising Errno::ENOENT on Win32 [Sam Stephenson] - -* Changed 0.blank? to false rather than true since it violates everyone's expectation of blankness. #2518, #2705 [rails@jeffcole.net] - -* When loading classes using const_missing, raise a NameError if and only if the file we tried to load was not present. [Nicholas Seckar] - -* Added petabytes and exebytes to numeric extensions #2397 [timct@mac.com] - -* Added Time#end_of_month to accompany Time#beginning_of_month #2514 [Jens-Christian Fischer] - - -*1.2.2* (October 26th, 2005) - -* Set Logger.silencer = false to disable Logger#silence. Useful for debugging fixtures. - -* Add title case method to String to do, e.g., 'action_web_service'.titlecase # => 'Action Web Service'. [Marcel Molina Jr.] - - -*1.2.1* (October 19th, 2005) - -* Classify generated routing code as framework code to avoid appearing in application traces. [Nicholas Seckar] - -* Show all framework frames in the framework trace. [Nicholas Seckar] - - -*1.2.0* (October 16th, 2005) - -* Update Exception extension to show the first few framework frames in an application trace. [Nicholas Seckar] - -* Added Exception extension to provide support for clean backtraces. [Nicholas Seckar] - -* Updated whiny nil to be more concise and useful. [Nicholas Seckar] - -* Added Enumerable#first_match [Nicholas Seckar] - -* Fixed that Time#change should also reset usec when also resetting minutes #2459 [ikeda@dream.big.or.jp] - -* Fix Logger compatibility for distributions that don't keep Ruby and its standard library in sync. - -* Replace '%e' from long and short time formats as Windows does not support it. #2344. [Tom Ward ] - -* Added to_s(:db) to Range, so you can get "BETWEEN '2005-12-10' AND '2005-12-12'" from Date.new(2005, 12, 10)..Date.new(2005, 12, 12) (and likewise with Times) - -* Moved require_library_or_gem into Kernel. #1992 [Michael Schuerig ] - -* Add :rfc822 as an option for Time#to_s (to get rfc822-formatted times) - -* Chain the const_missing hook to any previously existing hook so rails can play nicely with rake - -* Clean logger is compatible with both 1.8.2 and 1.8.3 Logger. #2263 [Michael Schuerig ] - -* Added native, faster implementations of .blank? for the core types #2286 [skae] - -* Fixed clean logger to work with Ruby 1.8.3 Logger class #2245 - -* Fixed memory leak with Active Record classes when Dependencies.mechanism = :load #1704 [c.r.mcgrath@gmail.com] - -* Fixed Inflector.underscore for use with acronyms, so HTML becomes html instead of htm_l #2173 [k@v2studio.com] - -* Fixed dependencies related infinite recursion bug when a controller file does not contain a controller class. Closes #1760. [rcolli2@tampabay.rr.com] - -* Fixed inflections for status, quiz, move #2056 [deirdre@deirdre.net] - -* Added Hash#reverse_merge, Hash#reverse_merge!, and Hash#reverse_update to ease the use of default options - -* Added Array#to_sentence that'll turn ['one', 'two', 'three'] into "one, two, and three" #2157 [m.stienstra@fngtps.com] - -* Added Kernel#silence_warnings to turn off warnings temporarily for the passed block - -* Added String#starts_with? and String#ends_with? #2118 [thijs@vandervossen.net] - -* Added easy extendability to the inflector through Inflector.inflections (using the Inflector::Inflections singleton class). Examples: - - Inflector.inflections do |inflect| - inflect.plural /^(ox)$/i, '\1\2en' - inflect.singular /^(ox)en/i, '\1' - - inflect.irregular 'octopus', 'octopi' - - inflect.uncountable "equipment" - end - -* Added String#at, String#from, String#to, String#first, String#last in ActiveSupport::CoreExtensions::String::Access to ease access to individual characters and substrings in a string serving basically as human names for range access. - -* Make Time#last_month work when invoked on the 31st of a month. - -* Add Time.days_in_month, and make Time#next_month work when invoked on the 31st of a month - -* Fixed that Time#midnight would have a non-zero usec on some platforms #1836 - -* Fixed inflections of "index/indices" #1766 [damn_pepe@gmail.com] - -* Added stripping of _id to String#humanize, so "employee_id" becomes "Employee" #1574 [Justin French] - -* Factor Fixnum and Bignum extensions into Integer extensions [Nicholas Seckar] - -* Hooked #ordinalize into Fixnum and Bignum classes. [Nicholas Seckar, danp] - -* Added Fixnum#ordinalize to turn 1.ordinalize to "1st", 3.ordinalize to "3rd", and 10.ordinalize to "10th" and so on #1724 [paul@cnt.org] - - -*1.1.1* (11 July, 2005) - -* Added more efficient implementation of the development mode reset of classes #1638 [Chris McGrath] - - -*1.1.0* (6 July, 2005) - -* Fixed conflict with Glue gem #1606 [Rick Olson] - -* Added new rules to the Inflector to deal with more unusual plurals mouse/louse => mice/lice, information => information, ox => oxen, virus => viri, archive => archives #1571, #1583, #1490, #1599, #1608 [foamdino@gmail.com/others] - -* Fixed memory leak with Object#remove_subclasses_of, which inflicted a Rails application running in development mode with a ~20KB leak per request #1289 [c.r.mcgrath@gmail.com] - -* Made 1.year == 365.25.days to account for leap years. This allows you to do User.find(:all, :conditions => ['birthday > ?', 50.years.ago]) without losing a lot of days. #1488 [tuxie@dekadance.se] - -* Added an exception if calling id on nil to WhinyNil #584 [kevin-temp@writesoon.com] - -* Added Fix/Bignum#multiple_of? which returns true on 14.multiple_of?(7) and false on 16.multiple_of?(7) #1464 [Thomas Fuchs] - -* Added even? and odd? to work with Bignums in addition to Fixnums #1464 [Thomas Fuchs] - -* Fixed Time#at_beginning_of_week returned the next Monday instead of the previous one when called on a Sunday #1403 [jean.helou@gmail.com] - -* Increased the speed of indifferent hash access by using Hash#default. #1436 [Nicholas Seckar] - -* Added that " " is now also blank? (using strip if available) - -* Fixed Dependencies so all modules are able to load missing constants #1173 [Nicholas Seckar] - -* Fixed the Inflector to underscore strings containing numbers, so Area51Controller becomes area51_controller #1176 [Nicholas Seckar] - -* Fixed that HashWithIndifferentAccess stringified all keys including symbols, ints, objects, and arrays #1162 [Nicholas Seckar] - -* Fixed Time#last_year to go back in time, not forward #1278 [fabien@odilat.com] - -* Fixed the pluralization of analysis to analyses #1295 [seattle@rootimage.msu.edu] - -* Fixed that Time.local(2005,12).months_since(1) would raise "ArgumentError: argument out of range" #1311 [jhahn@niveon.com] - -* Added silencing to the default Logger class - - -*1.0.4* (19th April, 2005) - -* Fixed that in some circumstances controllers outside of modules may have hidden ones inside modules. For example, admin/content might have been hidden by /content. #1075 [Nicholas Seckar] - -* Fixed inflection of perspectives and similar words #1045 [thijs@vandervossen.net] - -* Added Fixnum#even? and Fixnum#odd? - -* Fixed problem with classes being required twice. Object#const_missing now uses require_dependency to load files. It used to use require_or_load which would cause models to be loaded twice, which was not good for validations and other class methods #971 [Nicholas Seckar] - - -*1.0.3* (27th March, 2005) - -* Fixed Inflector.pluralize to handle capitalized words #932 [Jeremy Kemper] - -* Added Object#suppress which allows you to make a saner choice around with exceptions to swallow #980. Example: - - suppress(ZeroDivisionError) { 1/0 } - - ...instead of: - - 1/0 rescue nil # BAD, EVIL, DIRTY. - - -*1.0.2* (22th March, 2005) - -* Added Kernel#returning -- a Ruby-ized realization of the K combinator, courtesy of Mikael Brockman. - - def foo - returning values = [] do - values << 'bar' - values << 'baz' - end - end - - foo # => ['bar', 'baz'] - - -*1.0.1* (7th March, 2005) - -* Fixed Hash#indifferent_access to also deal with include? and fetch and nested hashes #726 [Nicholas Seckar] - -* Added Object#blank? -- see http://redhanded.hobix.com/inspect/objectBlank.html #783 [_why the lucky stiff] - -* Added inflection rules for "sh" words, like "wish" and "fish" #755 [phillip@pjbsoftware.com] - -* Fixed an exception when using Ajax based requests from Safari because Safari appends a \000 to the post body. Symbols can't have \000 in them so indifferent access would throw an exception in the constructor. Indifferent hashes now use strings internally instead. #746 [Tobias Luetke] - -* Added String#to_time and String#to_date for wrapping ParseDate - - -*1.0.0* (24th February, 2005) - -* Added TimeZone as the first of a number of value objects that among others Active Record can use rich value objects using composed_of #688 [Jamis Buck] - -* Added Date::Conversions for getting dates in different convenient string representations and other objects - -* Added Time::Conversions for getting times in different convenient string representations and other objects - -* Added Time::Calculations to ask for things like Time.now.tomorrow, Time.now.yesterday, Time.now.months_ago(4) #580 [DP|Flurin]. Examples: - - "Later today" => now.in(3.hours), - "Tomorrow morning" => now.tomorrow.change(:hour => 9), - "Tomorrow afternoon" => now.tomorrow.change(:hour => 14), - "In a couple of days" => now.tomorrow.tomorrow.change(:hour => 9), - "Next monday" => now.next_week.change(:hour => 9), - "In a month" => now.next_month.change(:hour => 9), - "In 6 months" => now.months_since(6).change(:hour => 9), - "In a year" => now.in(1.year).change(:hour => 9) - -* Upgraded to breakpoint 92 which fixes: - - * overload IRB.parse_opts(), fixes #443 - => breakpoints in tests work even when running them via rake - * untaint handlers, might fix an issue discussed on the Rails ML - * added verbose mode to breakpoint_client - * less noise caused by breakpoint_client by default - * ignored TerminateLineInput exception in signal handler - => quiet exit on Ctrl-C - -* Fixed Inflector for words like "news" and "series" that are the same in plural and singular #603 [echion], #615 [marcenuc] - -* Added Hash#stringify_keys and Hash#stringify_keys! - -* Added IndifferentAccess as a way to wrap a hash by a symbol-based store that also can be accessed by string keys - -* Added Inflector.constantize to turn "Admin::User" into a reference for the constant Admin::User - -* Added that Inflector.camelize and Inflector.underscore can deal with modules like turning "Admin::User" into "admin/user" and back - -* Added Inflector.humanize to turn attribute names like employee_salary into "Employee salary". Used by automated error reporting in AR. - -* Added availability of class inheritable attributes to the masses #477 [Jeremy Kemper] - - class Foo - class_inheritable_reader :read_me - class_inheritable_writer :write_me - class_inheritable_accessor :read_and_write_me - class_inheritable_array :read_and_concat_me - class_inheritable_hash :read_and_update_me - end - - # Bar gets a clone of (not a reference to) Foo's attributes. - class Bar < Foo - end - - Bar.read_and_write_me == Foo.read_and_write_me - Bar.read_and_write_me = 'bar' - Bar.read_and_write_me != Foo.read_and_write_me - -* Added Inflections as an extension on String, so Inflector.pluralize(Inflector.classify(name)) becomes name.classify.pluralize #476 [Jeremy Kemper] - -* Added Byte operations to Numeric, so 5.5.megabytes + 200.kilobytes #461 [Marcel Molina] - -* Fixed that Dependencies.reload can't load the same file twice #420 [Kent Sibilev] - -* Added Fixnum#ago/until, Fixnum#since/from_now #450 [Jeremy Kemper] - -* Added that Inflector now accepts Symbols and Classes by calling .to_s on the word supplied - -* Added time unit extensions to Fixnum that'll return the period in seconds, like 2.days + 4.hours. diff --git a/tracks/vendor/rails/activesupport/lib/active_support.rb b/tracks/vendor/rails/activesupport/lib/active_support.rb deleted file mode 100644 index 7d5440f2..00000000 --- a/tracks/vendor/rails/activesupport/lib/active_support.rb +++ /dev/null @@ -1,36 +0,0 @@ -#-- -# Copyright (c) 2005 David Heinemeier Hansson -# -# 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. -#++ - -$:.unshift(File.dirname(__FILE__)) - -require 'active_support/class_attribute_accessors' -require 'active_support/class_inheritable_attributes' -require 'active_support/inflector' - -require 'active_support/core_ext' -require 'active_support/clean_logger' -require 'active_support/dependencies' - -require 'active_support/ordered_options' - -require 'active_support/values/time_zone' \ No newline at end of file diff --git a/tracks/vendor/rails/activesupport/lib/active_support/binding_of_caller.rb b/tracks/vendor/rails/activesupport/lib/active_support/binding_of_caller.rb deleted file mode 100644 index e224c996..00000000 --- a/tracks/vendor/rails/activesupport/lib/active_support/binding_of_caller.rb +++ /dev/null @@ -1,84 +0,0 @@ -begin - require 'simplecc' -rescue LoadError - class Continuation # :nodoc: # for RDoc - end - def Continuation.create(*args, &block) # :nodoc: - cc = nil; result = callcc {|c| cc = c; block.call(cc) if block and args.empty?} - result ||= args - return *[cc, *result] - end -end - -class Binding; end # for RDoc -# This method returns the binding of the method that called your -# method. It will raise an Exception when you're not inside a method. -# -# It's used like this: -# def inc_counter(amount = 1) -# Binding.of_caller do |binding| -# # Create a lambda that will increase the variable 'counter' -# # in the caller of this method when called. -# inc = eval("lambda { |arg| counter += arg }", binding) -# # We can refer to amount from inside this block safely. -# inc.call(amount) -# end -# # No other statements can go here. Put them inside the block. -# end -# counter = 0 -# 2.times { inc_counter } -# counter # => 2 -# -# Binding.of_caller must be the last statement in the method. -# This means that you will have to put everything you want to -# do after the call to Binding.of_caller into the block of it. -# This should be no problem however, because Ruby has closures. -# If you don't do this an Exception will be raised. Because of -# the way that Binding.of_caller is implemented it has to be -# done this way. -def Binding.of_caller(&block) - old_critical = Thread.critical - Thread.critical = true - count = 0 - cc, result, error, extra_data = Continuation.create(nil, nil) - error.call if error - - tracer = lambda do |*args| - type, context, extra_data = args[0], args[4], args - if type == "return" - count += 1 - # First this method and then calling one will return -- - # the trace event of the second event gets the context - # of the method which called the method that called this - # method. - if count == 2 - # It would be nice if we could restore the trace_func - # that was set before we swapped in our own one, but - # this is impossible without overloading set_trace_func - # in current Ruby. - set_trace_func(nil) - cc.call(eval("binding", context), nil, extra_data) - end - elsif type == "line" then - nil - elsif type == "c-return" and extra_data[3] == :set_trace_func then - nil - else - set_trace_func(nil) - error_msg = "Binding.of_caller used in non-method context or " + - "trailing statements of method using it aren't in the block." - cc.call(nil, lambda { raise(ArgumentError, error_msg) }, nil) - end - end - - unless result - set_trace_func(tracer) - return nil - else - Thread.critical = old_critical - case block.arity - when 1 then yield(result) - else yield(result, extra_data) - end - end -end diff --git a/tracks/vendor/rails/activesupport/lib/active_support/breakpoint.rb b/tracks/vendor/rails/activesupport/lib/active_support/breakpoint.rb deleted file mode 100644 index ab2efd39..00000000 --- a/tracks/vendor/rails/activesupport/lib/active_support/breakpoint.rb +++ /dev/null @@ -1,523 +0,0 @@ -# The Breakpoint library provides the convenience of -# being able to inspect and modify state, diagnose -# bugs all via IRB by simply setting breakpoints in -# your applications by the call of a method. -# -# This library was written and is supported by me, -# Florian Gross. I can be reached at flgr@ccan.de -# and enjoy getting feedback about my libraries. -# -# The whole library (including breakpoint_client.rb -# and binding_of_caller.rb) is licensed under the -# same license that Ruby uses. (Which is currently -# either the GNU General Public License or a custom -# one that allows for commercial usage.) If you for -# some good reason need to use this under another -# license please contact me. - -require 'irb' -require File.dirname(__FILE__) + '/binding_of_caller' -require 'drb' -require 'drb/acl' - -module Breakpoint - id = %q$Id: breakpoint.rb 92 2005-02-04 22:35:53Z flgr $ - Version = id.split(" ")[2].to_i - - extend self - - # This will pop up an interactive ruby session at a - # pre-defined break point in a Ruby application. In - # this session you can examine the environment of - # the break point. - # - # You can get a list of variables in the context using - # local_variables via +local_variables+. You can then - # examine their values by typing their names. - # - # You can have a look at the call stack via +caller+. - # - # The source code around the location where the breakpoint - # was executed can be examined via +source_lines+. Its - # argument specifies how much lines of context to display. - # The default amount of context is 5 lines. Note that - # the call to +source_lines+ can raise an exception when - # it isn't able to read in the source code. - # - # breakpoints can also return a value. They will execute - # a supplied block for getting a default return value. - # A custom value can be returned from the session by doing - # +throw(:debug_return, value)+. - # - # You can also give names to break points which will be - # used in the message that is displayed upon execution - # of them. - # - # Here's a sample of how breakpoints should be placed: - # - # class Person - # def initialize(name, age) - # @name, @age = name, age - # breakpoint("Person#initialize") - # end - # - # attr_reader :age - # def name - # breakpoint("Person#name") { @name } - # end - # end - # - # person = Person.new("Random Person", 23) - # puts "Name: #{person.name}" - # - # And here is a sample debug session: - # - # Executing break point "Person#initialize" at file.rb:4 in `initialize' - # irb(#):001:0> local_variables - # => ["name", "age", "_", "__"] - # irb(#):002:0> [name, age] - # => ["Random Person", 23] - # irb(#):003:0> [@name, @age] - # => ["Random Person", 23] - # irb(#):004:0> self - # => # - # irb(#):005:0> @age += 1; self - # => # - # irb(#):006:0> exit - # Executing break point "Person#name" at file.rb:9 in `name' - # irb(#):001:0> throw(:debug_return, "Overriden name") - # Name: Overriden name - # - # Breakpoint sessions will automatically have a few - # convenience methods available. See Breakpoint::CommandBundle - # for a list of them. - # - # Breakpoints can also be used remotely over sockets. - # This is implemented by running part of the IRB session - # in the application and part of it in a special client. - # You have to call Breakpoint.activate_drb to enable - # support for remote breakpoints and then run - # breakpoint_client.rb which is distributed with this - # library. See the documentation of Breakpoint.activate_drb - # for details. - def breakpoint(id = nil, context = nil, &block) - callstack = caller - callstack.slice!(0, 3) if callstack.first["breakpoint"] - file, line, method = *callstack.first.match(/^(.+?):(\d+)(?::in `(.*?)')?/).captures - - message = "Executing break point " + (id ? "#{id.inspect} " : "") + - "at #{file}:#{line}" + (method ? " in `#{method}'" : "") - - if context then - return handle_breakpoint(context, message, file, line, &block) - end - - Binding.of_caller do |binding_context| - handle_breakpoint(binding_context, message, file, line, &block) - end - end - - module CommandBundle #:nodoc: - # Proxy to a Breakpoint client. Lets you directly execute code - # in the context of the client. - class Client #:nodoc: - def initialize(eval_handler) # :nodoc: - eval_handler.untaint - @eval_handler = eval_handler - end - - instance_methods.each do |method| - next if method[/^__.+__$/] - undef_method method - end - - # Executes the specified code at the client. - def eval(code) - @eval_handler.call(code) - end - - # Will execute the specified statement at the client. - def method_missing(method, *args, &block) - if args.empty? and not block - result = eval "#{method}" - else - # This is a bit ugly. The alternative would be using an - # eval context instead of an eval handler for executing - # the code at the client. The problem with that approach - # is that we would have to handle special expressions - # like "self", "nil" or constants ourself which is hard. - remote = eval %{ - result = lambda { |block, *args| #{method}(*args, &block) } - def result.call_with_block(*args, &block) - call(block, *args) - end - result - } - remote.call_with_block(*args, &block) - end - - return result - end - end - - # Returns the source code surrounding the location where the - # breakpoint was issued. - def source_lines(context = 5, return_line_numbers = false) - lines = File.readlines(@__bp_file).map { |line| line.chomp } - - break_line = @__bp_line - start_line = [break_line - context, 1].max - end_line = break_line + context - - result = lines[(start_line - 1) .. (end_line - 1)] - - if return_line_numbers then - return [start_line, break_line, result] - else - return result - end - end - - # Lets an object that will forward method calls to the breakpoint - # client. This is useful for outputting longer things at the client - # and so on. You can for example do these things: - # - # client.puts "Hello" # outputs "Hello" at client console - # # outputs "Hello" into the file temp.txt at the client - # client.File.open("temp.txt", "w") { |f| f.puts "Hello" } - def client() - if Breakpoint.use_drb? then - sleep(0.5) until Breakpoint.drb_service.eval_handler - Client.new(Breakpoint.drb_service.eval_handler) - else - Client.new(lambda { |code| eval(code, TOPLEVEL_BINDING) }) - end - end - end - - def handle_breakpoint(context, message, file = "", line = "", &block) # :nodoc: - catch(:debug_return) do |value| - eval(%{ - @__bp_file = #{file.inspect} - @__bp_line = #{line} - extend Breakpoint::CommandBundle - extend DRbUndumped if self - }, context) rescue nil - - if not use_drb? then - puts message - IRB.start(nil, IRB::WorkSpace.new(context)) - else - @drb_service.add_breakpoint(context, message) - end - - block.call if block - end - end - - # These exceptions will be raised on failed asserts - # if Breakpoint.asserts_cause_exceptions is set to - # true. - class FailedAssertError < RuntimeError #:nodoc: - end - - # This asserts that the block evaluates to true. - # If it doesn't evaluate to true a breakpoint will - # automatically be created at that execution point. - # - # You can disable assert checking in production - # code by setting Breakpoint.optimize_asserts to - # true. (It will still be enabled when Ruby is run - # via the -d argument.) - # - # Example: - # person_name = "Foobar" - # assert { not person_name.nil? } - # - # Note: If you want to use this method from an - # unit test, you will have to call it by its full - # name, Breakpoint.assert. - def assert(context = nil, &condition) - return if Breakpoint.optimize_asserts and not $DEBUG - return if yield - - callstack = caller - callstack.slice!(0, 3) if callstack.first["assert"] - file, line, method = *callstack.first.match(/^(.+?):(\d+)(?::in `(.*?)')?/).captures - - message = "Assert failed at #{file}:#{line}#{" in `#{method}'" if method}." - - if Breakpoint.asserts_cause_exceptions and not $DEBUG then - raise(Breakpoint::FailedAssertError, message) - end - - message += " Executing implicit breakpoint." - - if context then - return handle_breakpoint(context, message, file, line) - end - - Binding.of_caller do |context| - handle_breakpoint(context, message, file, line) - end - end - - # Whether asserts should be ignored if not in debug mode. - # Debug mode can be enabled by running ruby with the -d - # switch or by setting $DEBUG to true. - attr_accessor :optimize_asserts - self.optimize_asserts = false - - # Whether an Exception should be raised on failed asserts - # in non-$DEBUG code or not. By default this is disabled. - attr_accessor :asserts_cause_exceptions - self.asserts_cause_exceptions = false - @use_drb = false - - attr_reader :drb_service # :nodoc: - - class DRbService # :nodoc: - include DRbUndumped - - def initialize - @handler = @eval_handler = @collision_handler = nil - - IRB.instance_eval { @CONF[:RC] = true } - IRB.run_config - end - - def collision - sleep(0.5) until @collision_handler - - @collision_handler.untaint - - @collision_handler.call - end - - def ping() end - - def add_breakpoint(context, message) - workspace = IRB::WorkSpace.new(context) - workspace.extend(DRbUndumped) - - sleep(0.5) until @handler - - @handler.untaint - @handler.call(workspace, message) - end - - attr_accessor :handler, :eval_handler, :collision_handler - end - - # Will run Breakpoint in DRb mode. This will spawn a server - # that can be attached to via the breakpoint-client command - # whenever a breakpoint is executed. This is useful when you - # are debugging CGI applications or other applications where - # you can't access debug sessions via the standard input and - # output of your application. - # - # You can specify an URI where the DRb server will run at. - # This way you can specify the port the server runs on. The - # default URI is druby://localhost:42531. - # - # Please note that breakpoints will be skipped silently in - # case the DRb server can not spawned. (This can happen if - # the port is already used by another instance of your - # application on CGI or another application.) - # - # Also note that by default this will only allow access - # from localhost. You can however specify a list of - # allowed hosts or nil (to allow access from everywhere). - # But that will still not protect you from somebody - # reading the data as it goes through the net. - # - # A good approach for getting security and remote access - # is setting up an SSH tunnel between the DRb service - # and the client. This is usually done like this: - # - # $ ssh -L20000:127.0.0.1:20000 -R10000:127.0.0.1:10000 example.com - # (This will connect port 20000 at the client side to port - # 20000 at the server side, and port 10000 at the server - # side to port 10000 at the client side.) - # - # After that do this on the server side: (the code being debugged) - # Breakpoint.activate_drb("druby://127.0.0.1:20000", "localhost") - # - # And at the client side: - # ruby breakpoint_client.rb -c druby://127.0.0.1:10000 -s druby://127.0.0.1:20000 - # - # Running through such a SSH proxy will also let you use - # breakpoint.rb in case you are behind a firewall. - # - # Detailed information about running DRb through firewalls is - # available at http://www.rubygarden.org/ruby?DrbTutorial - def activate_drb(uri = nil, allowed_hosts = ['localhost', '127.0.0.1', '::1'], - ignore_collisions = false) - - return false if @use_drb - - uri ||= 'druby://localhost:42531' - - if allowed_hosts then - acl = ["deny", "all"] - - Array(allowed_hosts).each do |host| - acl += ["allow", host] - end - - DRb.install_acl(ACL.new(acl)) - end - - @use_drb = true - @drb_service = DRbService.new - did_collision = false - begin - @service = DRb.start_service(uri, @drb_service) - rescue Errno::EADDRINUSE - if ignore_collisions then - nil - else - # The port is already occupied by another - # Breakpoint service. We will try to tell - # the old service that we want its port. - # It will then forward that request to the - # user and retry. - unless did_collision then - DRbObject.new(nil, uri).collision - did_collision = true - end - sleep(10) - retry - end - end - - return true - end - - # Deactivates a running Breakpoint service. - def deactivate_drb - @service.stop_service unless @service.nil? - @service = nil - @use_drb = false - @drb_service = nil - end - - # Returns true when Breakpoints are used over DRb. - # Breakpoint.activate_drb causes this to be true. - def use_drb? - @use_drb == true - end -end - -module IRB #:nodoc: - class << self; remove_method :start; end - def self.start(ap_path = nil, main_context = nil, workspace = nil) - $0 = File::basename(ap_path, ".rb") if ap_path - - # suppress some warnings about redefined constants - old_verbose, $VERBOSE = $VERBOSE, nil - IRB.setup(ap_path) - $VERBOSE = old_verbose - - if @CONF[:SCRIPT] then - irb = Irb.new(main_context, @CONF[:SCRIPT]) - else - irb = Irb.new(main_context) - end - - if workspace then - irb.context.workspace = workspace - end - - @CONF[:IRB_RC].call(irb.context) if @CONF[:IRB_RC] - @CONF[:MAIN_CONTEXT] = irb.context - - old_sigint = trap("SIGINT") do - begin - irb.signal_handle - rescue RubyLex::TerminateLineInput - # ignored - end - end - - catch(:IRB_EXIT) do - irb.eval_input - end - ensure - trap("SIGINT", old_sigint) - end - - class << self - alias :old_CurrentContext :CurrentContext - remove_method :CurrentContext - end - def IRB.CurrentContext - if old_CurrentContext.nil? and Breakpoint.use_drb? then - result = Object.new - def result.last_value; end - return result - else - old_CurrentContext - end - end - def IRB.parse_opts() end - - class Context #:nodoc: - alias :old_evaluate :evaluate - def evaluate(line, line_no) - if line.chomp == "exit" then - exit - else - old_evaluate(line, line_no) - end - end - end - - class WorkSpace #:nodoc: - alias :old_evaluate :evaluate - - def evaluate(*args) - if Breakpoint.use_drb? then - result = old_evaluate(*args) - if args[0] != :no_proxy and - not [true, false, nil].include?(result) - then - result.extend(DRbUndumped) rescue nil - end - return result - else - old_evaluate(*args) - end - end - end - - module InputCompletor #:nodoc: - def self.eval(code, context, *more) - # Big hack, this assumes that InputCompletor - # will only call eval() when it wants code - # to be executed in the IRB context. - IRB.conf[:MAIN_CONTEXT].workspace.evaluate(:no_proxy, code, *more) - end - end -end - -module DRb # :nodoc: - class DRbObject #:nodoc: - undef :inspect if method_defined?(:inspect) - undef :clone if method_defined?(:clone) - end -end - -# See Breakpoint.breakpoint -def breakpoint(id = nil, &block) - Binding.of_caller do |context| - Breakpoint.breakpoint(id, context, &block) - end -end - -# See Breakpoint.assert -def assert(&block) - Binding.of_caller do |context| - Breakpoint.assert(context, &block) - end -end diff --git a/tracks/vendor/rails/activesupport/lib/active_support/class_attribute_accessors.rb b/tracks/vendor/rails/activesupport/lib/active_support/class_attribute_accessors.rb deleted file mode 100644 index bb043f8e..00000000 --- a/tracks/vendor/rails/activesupport/lib/active_support/class_attribute_accessors.rb +++ /dev/null @@ -1,57 +0,0 @@ -# Extends the class object with class and instance accessors for class attributes, -# just like the native attr* accessors for instance attributes. -class Class # :nodoc: - def cattr_reader(*syms) - syms.select { |sym| sym.respond_to?(:id2name) }.each do |sym| - class_eval <<-EOS - if ! defined? @@#{sym.id2name} - @@#{sym.id2name} = nil - end - - def self.#{sym.id2name} - @@#{sym} - end - - def #{sym.id2name} - @@#{sym} - end - - def call_#{sym.id2name} - case @@#{sym.id2name} - when Symbol then send(@@#{sym}) - when Proc then @@#{sym}.call(self) - when String then @@#{sym} - else nil - end - end - EOS - end - end - - def cattr_writer(*syms) - syms.select { |sym| sym.respond_to?(:id2name) }.each do |sym| - class_eval <<-EOS - if ! defined? @@#{sym.id2name} - @@#{sym.id2name} = nil - end - - def self.#{sym.id2name}=(obj) - @@#{sym.id2name} = obj - end - - def self.set_#{sym.id2name}(obj) - @@#{sym.id2name} = obj - end - - def #{sym.id2name}=(obj) - @@#{sym} = obj - end - EOS - end - end - - def cattr_accessor(*syms) - cattr_reader(*syms) - cattr_writer(*syms) - end -end diff --git a/tracks/vendor/rails/activesupport/lib/active_support/class_inheritable_attributes.rb b/tracks/vendor/rails/activesupport/lib/active_support/class_inheritable_attributes.rb deleted file mode 100644 index f9ca7af7..00000000 --- a/tracks/vendor/rails/activesupport/lib/active_support/class_inheritable_attributes.rb +++ /dev/null @@ -1,117 +0,0 @@ -# Retain for backward compatibility. Methods are now included in Class. -module ClassInheritableAttributes # :nodoc: -end - -# Allows attributes to be shared within an inheritance hierarchy, but where each descendant gets a copy of -# their parents' attributes, instead of just a pointer to the same. This means that the child can add elements -# to, for example, an array without those additions being shared with either their parent, siblings, or -# children, which is unlike the regular class-level attributes that are shared across the entire hierarchy. -class Class # :nodoc: - def class_inheritable_reader(*syms) - syms.each do |sym| - class_eval <<-EOS - def self.#{sym} - read_inheritable_attribute(:#{sym}) - end - - def #{sym} - self.class.#{sym} - end - EOS - end - end - - def class_inheritable_writer(*syms) - syms.each do |sym| - class_eval <<-EOS - def self.#{sym}=(obj) - write_inheritable_attribute(:#{sym}, obj) - end - - def #{sym}=(obj) - self.class.#{sym} = obj - end - EOS - end - end - - def class_inheritable_array_writer(*syms) - syms.each do |sym| - class_eval <<-EOS - def self.#{sym}=(obj) - write_inheritable_array(:#{sym}, obj) - end - - def #{sym}=(obj) - self.class.#{sym} = obj - end - EOS - end - end - - def class_inheritable_hash_writer(*syms) - syms.each do |sym| - class_eval <<-EOS - def self.#{sym}=(obj) - write_inheritable_hash(:#{sym}, obj) - end - - def #{sym}=(obj) - self.class.#{sym} = obj - end - EOS - end - end - - def class_inheritable_accessor(*syms) - class_inheritable_reader(*syms) - class_inheritable_writer(*syms) - end - - def class_inheritable_array(*syms) - class_inheritable_reader(*syms) - class_inheritable_array_writer(*syms) - end - - def class_inheritable_hash(*syms) - class_inheritable_reader(*syms) - class_inheritable_hash_writer(*syms) - end - - def inheritable_attributes - @inheritable_attributes ||= {} - end - - def write_inheritable_attribute(key, value) - inheritable_attributes[key] = value - end - - def write_inheritable_array(key, elements) - write_inheritable_attribute(key, []) if read_inheritable_attribute(key).nil? - write_inheritable_attribute(key, read_inheritable_attribute(key) + elements) - end - - def write_inheritable_hash(key, hash) - write_inheritable_attribute(key, {}) if read_inheritable_attribute(key).nil? - write_inheritable_attribute(key, read_inheritable_attribute(key).merge(hash)) - end - - def read_inheritable_attribute(key) - inheritable_attributes[key] - end - - def reset_inheritable_attributes - inheritable_attributes.clear - end - - private - def inherited_with_inheritable_attributes(child) - inherited_without_inheritable_attributes(child) if respond_to?(:inherited_without_inheritable_attributes) - child.instance_variable_set('@inheritable_attributes', inheritable_attributes.dup) - end - - if respond_to?(:inherited) - alias_method :inherited_without_inheritable_attributes, :inherited - end - alias_method :inherited, :inherited_with_inheritable_attributes -end diff --git a/tracks/vendor/rails/activesupport/lib/active_support/clean_logger.rb b/tracks/vendor/rails/activesupport/lib/active_support/clean_logger.rb deleted file mode 100644 index 89dfae8f..00000000 --- a/tracks/vendor/rails/activesupport/lib/active_support/clean_logger.rb +++ /dev/null @@ -1,36 +0,0 @@ -require 'logger' -require File.dirname(__FILE__) + '/class_attribute_accessors' - -class Logger #:nodoc: - cattr_accessor :silencer - self.silencer = true - - # Silences the logger for the duration of the block. - def silence(temporary_level = Logger::ERROR) - if silencer - begin - old_logger_level, self.level = level, temporary_level - yield self - ensure - self.level = old_logger_level - end - else - yield self - end - end - - private - # Ruby 1.8.3 transposed the msg and progname arguments to format_message. - # We can't test RUBY_VERSION because some distributions don't keep Ruby - # and its standard library in sync, leading to installations of Ruby 1.8.2 - # with Logger from 1.8.3 and vice versa. - if method_defined?(:formatter=) - def format_message(severity, timestamp, progname, msg) - "#{msg}\n" - end - else - def format_message(severity, timestamp, msg, progname) - "#{msg}\n" - end - end -end diff --git a/tracks/vendor/rails/activesupport/lib/active_support/core_ext.rb b/tracks/vendor/rails/activesupport/lib/active_support/core_ext.rb deleted file mode 100644 index 573313e7..00000000 --- a/tracks/vendor/rails/activesupport/lib/active_support/core_ext.rb +++ /dev/null @@ -1 +0,0 @@ -Dir[File.dirname(__FILE__) + "/core_ext/*.rb"].each { |file| require(file) } diff --git a/tracks/vendor/rails/activesupport/lib/active_support/core_ext/array.rb b/tracks/vendor/rails/activesupport/lib/active_support/core_ext/array.rb deleted file mode 100644 index ddf2a369..00000000 --- a/tracks/vendor/rails/activesupport/lib/active_support/core_ext/array.rb +++ /dev/null @@ -1,5 +0,0 @@ -require File.dirname(__FILE__) + '/array/conversions' - -class Array #:nodoc: - include ActiveSupport::CoreExtensions::Array::Conversions -end diff --git a/tracks/vendor/rails/activesupport/lib/active_support/core_ext/array/conversions.rb b/tracks/vendor/rails/activesupport/lib/active_support/core_ext/array/conversions.rb deleted file mode 100644 index e9e9cf44..00000000 --- a/tracks/vendor/rails/activesupport/lib/active_support/core_ext/array/conversions.rb +++ /dev/null @@ -1,30 +0,0 @@ -module ActiveSupport #:nodoc: - module CoreExtensions #:nodoc: - module Array #:nodoc: - # Enables to conversion of Arrays to human readable lists. ['one', 'two', 'three'] => "one, two, and three" - module Conversions - # Converts the array to comma-seperated sentence where the last element is joined by the connector word. Options: - # * :connector: The word used to join the last element in arrays with more than two elements (default: "and") - # * :skip_last_comma: Set to true to return "a, b and c" instead of "a, b, and c". - def to_sentence(options = {}) - options.assert_valid_keys(:connector, :skip_last_comma) - options.reverse_merge! :connector => 'and', :skip_last_comma => false - - case length - when 1 - self[0] - when 2 - "#{self[0]} #{options[:connector]} #{self[1]}" - else - "#{self[0...-1].join(', ')}#{options[:skip_last_comma] ? '' : ','} #{options[:connector]} #{self[-1]}" - end - end - - # When an array is given to url_for, it is converted to a slash separated string. - def to_param - join '/' - end - end - end - end -end diff --git a/tracks/vendor/rails/activesupport/lib/active_support/core_ext/blank.rb b/tracks/vendor/rails/activesupport/lib/active_support/core_ext/blank.rb deleted file mode 100644 index 791cdc57..00000000 --- a/tracks/vendor/rails/activesupport/lib/active_support/core_ext/blank.rb +++ /dev/null @@ -1,38 +0,0 @@ -# The methods here are provided to speed up function blank? in class Object -class NilClass #:nodoc: - def blank? - true - end -end - -class FalseClass #:nodoc: - def blank? - true - end -end - -class TrueClass #:nodoc: - def blank? - false - end -end - -class Array #:nodoc: - alias_method :blank?, :empty? -end - -class Hash #:nodoc: - alias_method :blank?, :empty? -end - -class String #:nodoc: - def blank? - empty? || strip.empty? - end -end - -class Numeric #:nodoc: - def blank? - false - end -end diff --git a/tracks/vendor/rails/activesupport/lib/active_support/core_ext/cgi.rb b/tracks/vendor/rails/activesupport/lib/active_support/core_ext/cgi.rb deleted file mode 100644 index 072a7c99..00000000 --- a/tracks/vendor/rails/activesupport/lib/active_support/core_ext/cgi.rb +++ /dev/null @@ -1,5 +0,0 @@ -require File.dirname(__FILE__) + '/cgi/escape_skipping_slashes' - -class CGI #:nodoc: - extend(ActiveSupport::CoreExtensions::CGI::EscapeSkippingSlashes) -end diff --git a/tracks/vendor/rails/activesupport/lib/active_support/core_ext/cgi/escape_skipping_slashes.rb b/tracks/vendor/rails/activesupport/lib/active_support/core_ext/cgi/escape_skipping_slashes.rb deleted file mode 100644 index a21e98fa..00000000 --- a/tracks/vendor/rails/activesupport/lib/active_support/core_ext/cgi/escape_skipping_slashes.rb +++ /dev/null @@ -1,14 +0,0 @@ -module ActiveSupport #:nodoc: - module CoreExtensions #:nodoc: - module CGI #:nodoc: - module EscapeSkippingSlashes #:nodoc: - def escape_skipping_slashes(str) - str = str.join('/') if str.respond_to? :join - str.gsub(/([^ \/a-zA-Z0-9_.-])/n) do - "%#{$1.unpack('H2').first.upcase}" - end.tr(' ', '+') - end - end - end - end -end diff --git a/tracks/vendor/rails/activesupport/lib/active_support/core_ext/date.rb b/tracks/vendor/rails/activesupport/lib/active_support/core_ext/date.rb deleted file mode 100644 index 239b8c14..00000000 --- a/tracks/vendor/rails/activesupport/lib/active_support/core_ext/date.rb +++ /dev/null @@ -1,6 +0,0 @@ -require 'date' -require File.dirname(__FILE__) + '/date/conversions' - -class Date#:nodoc: - include ActiveSupport::CoreExtensions::Date::Conversions -end diff --git a/tracks/vendor/rails/activesupport/lib/active_support/core_ext/date/conversions.rb b/tracks/vendor/rails/activesupport/lib/active_support/core_ext/date/conversions.rb deleted file mode 100644 index a9d7eb09..00000000 --- a/tracks/vendor/rails/activesupport/lib/active_support/core_ext/date/conversions.rb +++ /dev/null @@ -1,31 +0,0 @@ -module ActiveSupport #:nodoc: - module CoreExtensions #:nodoc: - module Date #:nodoc: - # Getting dates in different convenient string representations and other objects - module Conversions - DATE_FORMATS = { - :short => "%e %b", - :long => "%B %e, %Y" - } - - def self.included(klass) #:nodoc: - klass.send(:alias_method, :to_default_s, :to_s) - klass.send(:alias_method, :to_s, :to_formatted_s) - end - - def to_formatted_s(format = :default) - DATE_FORMATS[format] ? strftime(DATE_FORMATS[format]).strip : to_default_s - end - - # To be able to keep Dates and Times interchangeable on conversions - def to_date - self - end - - def to_time(form = :local) - ::Time.send(form, year, month, day) - end - end - end - end -end \ No newline at end of file diff --git a/tracks/vendor/rails/activesupport/lib/active_support/core_ext/enumerable.rb b/tracks/vendor/rails/activesupport/lib/active_support/core_ext/enumerable.rb deleted file mode 100644 index 49e1b7bb..00000000 --- a/tracks/vendor/rails/activesupport/lib/active_support/core_ext/enumerable.rb +++ /dev/null @@ -1,9 +0,0 @@ -module Enumerable #:nodoc: - def first_match - match = nil - each do |items| - break if match = yield(items) - end - match - end -end \ No newline at end of file diff --git a/tracks/vendor/rails/activesupport/lib/active_support/core_ext/exception.rb b/tracks/vendor/rails/activesupport/lib/active_support/core_ext/exception.rb deleted file mode 100644 index 2541f374..00000000 --- a/tracks/vendor/rails/activesupport/lib/active_support/core_ext/exception.rb +++ /dev/null @@ -1,29 +0,0 @@ -class Exception - - alias :clean_message :message - - TraceSubstitutions = [] - FrameworkRegexp = /generated_code|vendor|dispatch|ruby|script\/\w+/ - - def clean_backtrace - backtrace.collect do |line| - TraceSubstitutions.inject(line) do |line, (regexp, sub)| - line.gsub regexp, sub - end - end - end - - def application_backtrace - before_application_frame = true - - clean_backtrace.reject do |line| - non_app_frame = !! (line =~ FrameworkRegexp) - before_application_frame = false unless non_app_frame - non_app_frame && ! before_application_frame - end - end - - def framework_backtrace - clean_backtrace.select {|line| line =~ FrameworkRegexp} - end -end \ No newline at end of file diff --git a/tracks/vendor/rails/activesupport/lib/active_support/core_ext/hash.rb b/tracks/vendor/rails/activesupport/lib/active_support/core_ext/hash.rb deleted file mode 100644 index f16368b1..00000000 --- a/tracks/vendor/rails/activesupport/lib/active_support/core_ext/hash.rb +++ /dev/null @@ -1,9 +0,0 @@ -require File.dirname(__FILE__) + '/hash/keys' -require File.dirname(__FILE__) + '/hash/indifferent_access' -require File.dirname(__FILE__) + '/hash/reverse_merge' - -class Hash #:nodoc: - include ActiveSupport::CoreExtensions::Hash::Keys - include ActiveSupport::CoreExtensions::Hash::IndifferentAccess - include ActiveSupport::CoreExtensions::Hash::ReverseMerge -end diff --git a/tracks/vendor/rails/activesupport/lib/active_support/core_ext/hash/indifferent_access.rb b/tracks/vendor/rails/activesupport/lib/active_support/core_ext/hash/indifferent_access.rb deleted file mode 100644 index d818d86a..00000000 --- a/tracks/vendor/rails/activesupport/lib/active_support/core_ext/hash/indifferent_access.rb +++ /dev/null @@ -1,60 +0,0 @@ -# This implementation is HODEL-HASH-9600 compliant -class HashWithIndifferentAccess < Hash - def initialize(constructor = {}) - if constructor.is_a?(Hash) - super() - update(constructor) - else - super(constructor) - end - end - - def default(key) - self[key.to_s] if key.is_a?(Symbol) - end - - alias_method :regular_writer, :[]= unless method_defined?(:regular_writer) - - def []=(key, value) - regular_writer(convert_key(key), convert_value(value)) - end - def update(hash) - hash.each {|key, value| self[key] = value} - end - - def key?(key) - super(convert_key(key)) - end - - alias_method :include?, :key? - alias_method :has_key?, :key? - alias_method :member?, :key? - - def fetch(key, *extras) - super(convert_key(key), *extras) - end - - def values_at(*indices) - indices.collect {|key| self[convert_key(key)]} - end - - protected - def convert_key(key) - key.kind_of?(Symbol) ? key.to_s : key - end - def convert_value(value) - value.is_a?(Hash) ? value.with_indifferent_access : value - end -end - -module ActiveSupport #:nodoc: - module CoreExtensions #:nodoc: - module Hash #:nodoc: - module IndifferentAccess #:nodoc: - def with_indifferent_access - HashWithIndifferentAccess.new(self) - end - end - end - end -end diff --git a/tracks/vendor/rails/activesupport/lib/active_support/core_ext/hash/keys.rb b/tracks/vendor/rails/activesupport/lib/active_support/core_ext/hash/keys.rb deleted file mode 100644 index 3c8a59f0..00000000 --- a/tracks/vendor/rails/activesupport/lib/active_support/core_ext/hash/keys.rb +++ /dev/null @@ -1,53 +0,0 @@ -module ActiveSupport #:nodoc: - module CoreExtensions #:nodoc: - module Hash #:nodoc: - module Keys - # Return a new hash with all keys converted to strings. - def stringify_keys - inject({}) do |options, (key, value)| - options[key.to_s] = value - options - end - end - - # Destructively convert all keys to strings. - def stringify_keys! - keys.each do |key| - unless key.class.to_s == "String" # weird hack to make the tests run when string_ext_test.rb is also running - self[key.to_s] = self[key] - delete(key) - end - end - self - end - - # Return a new hash with all keys converted to symbols. - def symbolize_keys - inject({}) do |options, (key, value)| - options[key.to_sym] = value - options - end - end - - # Destructively convert all keys to symbols. - def symbolize_keys! - keys.each do |key| - unless key.is_a?(Symbol) - self[key.to_sym] = self[key] - delete(key) - end - end - self - end - - alias_method :to_options, :symbolize_keys - alias_method :to_options!, :symbolize_keys! - - def assert_valid_keys(*valid_keys) - unknown_keys = keys - [valid_keys].flatten - raise(ArgumentError, "Unknown key(s): #{unknown_keys.join(", ")}") unless unknown_keys.empty? - end - end - end - end -end diff --git a/tracks/vendor/rails/activesupport/lib/active_support/core_ext/hash/reverse_merge.rb b/tracks/vendor/rails/activesupport/lib/active_support/core_ext/hash/reverse_merge.rb deleted file mode 100644 index 46c53871..00000000 --- a/tracks/vendor/rails/activesupport/lib/active_support/core_ext/hash/reverse_merge.rb +++ /dev/null @@ -1,25 +0,0 @@ -module ActiveSupport #:nodoc: - module CoreExtensions #:nodoc: - module Hash #:nodoc: - # Allows for reverse merging where its the keys in the calling hash that wins over those in the other_hash. - # This is particularly useful for initializing an incoming option hash with default values: - # - # def setup(options = {}) - # options.reverse_merge! :size => 25, :velocity => 10 - # end - # - # The default :size and :velocity is only set if the +options+ passed in doesn't already have those keys set. - module ReverseMerge - def reverse_merge(other_hash) - other_hash.merge(self) - end - - def reverse_merge!(other_hash) - replace(reverse_merge(other_hash)) - end - - alias_method :reverse_update, :reverse_merge - end - end - end -end \ No newline at end of file diff --git a/tracks/vendor/rails/activesupport/lib/active_support/core_ext/integer.rb b/tracks/vendor/rails/activesupport/lib/active_support/core_ext/integer.rb deleted file mode 100644 index 9346b88f..00000000 --- a/tracks/vendor/rails/activesupport/lib/active_support/core_ext/integer.rb +++ /dev/null @@ -1,7 +0,0 @@ -require File.dirname(__FILE__) + '/integer/even_odd' -require File.dirname(__FILE__) + '/integer/inflections' - -class Integer #:nodoc: - include ActiveSupport::CoreExtensions::Integer::EvenOdd - include ActiveSupport::CoreExtensions::Integer::Inflections -end diff --git a/tracks/vendor/rails/activesupport/lib/active_support/core_ext/integer/even_odd.rb b/tracks/vendor/rails/activesupport/lib/active_support/core_ext/integer/even_odd.rb deleted file mode 100644 index 3762308c..00000000 --- a/tracks/vendor/rails/activesupport/lib/active_support/core_ext/integer/even_odd.rb +++ /dev/null @@ -1,24 +0,0 @@ -module ActiveSupport #:nodoc: - module CoreExtensions #:nodoc: - module Integer #:nodoc: - # For checking if a fixnum is even or odd. - # * 1.even? # => false - # * 1.odd? # => true - # * 2.even? # => true - # * 2.odd? # => false - module EvenOdd - def multiple_of?(number) - self % number == 0 - end - - def even? - multiple_of? 2 - end - - def odd? - !even? - end - end - end - end -end diff --git a/tracks/vendor/rails/activesupport/lib/active_support/core_ext/integer/inflections.rb b/tracks/vendor/rails/activesupport/lib/active_support/core_ext/integer/inflections.rb deleted file mode 100644 index a86c4cc2..00000000 --- a/tracks/vendor/rails/activesupport/lib/active_support/core_ext/integer/inflections.rb +++ /dev/null @@ -1,15 +0,0 @@ -require File.dirname(__FILE__) + '/../../inflector' -module ActiveSupport #:nodoc: - module CoreExtensions #:nodoc: - module Integer #:nodoc: - module Inflections - # 1.ordinalize # => "1st" - # 3.ordinalize # => "3rd" - # 10.ordinalize # => "10th" - def ordinalize - Inflector.ordinalize(self) - end - end - end - end -end diff --git a/tracks/vendor/rails/activesupport/lib/active_support/core_ext/kernel.rb b/tracks/vendor/rails/activesupport/lib/active_support/core_ext/kernel.rb deleted file mode 100644 index b687af03..00000000 --- a/tracks/vendor/rails/activesupport/lib/active_support/core_ext/kernel.rb +++ /dev/null @@ -1,79 +0,0 @@ -class Object - # A Ruby-ized realization of the K combinator, courtesy of Mikael Brockman. - # - # def foo - # returning values = [] do - # values << 'bar' - # values << 'baz' - # end - # end - # - # foo # => ['bar', 'baz'] - # - def returning(value) - yield - value - end - - # Sets $VERBOSE to nil for the duration of the block and back to its original value afterwards. - # - # silence_warnings do - # value = noisy_call # no warning voiced - # end - # - # noisy_call # warning voiced - def silence_warnings - old_verbose, $VERBOSE = $VERBOSE, nil - yield - ensure - $VERBOSE = old_verbose - end - - # Silences stderr for the duration of the block. - # - # silence_stderr do - # $stderr.puts 'This will never be seen' - # end - # - # $stderr.puts 'But this will' - def silence_stderr - old_stderr = STDERR.dup - STDERR.reopen(RUBY_PLATFORM =~ /mswin/ ? 'NUL:' : '/dev/null') - STDERR.sync = true - yield - ensure - STDERR.reopen(old_stderr) - end - - # Makes backticks behave (somewhat more) similarly on all platforms. - # On win32 `nonexistent_command` raises Errno::ENOENT; on Unix, the - # spawned shell prints a message to stderr and sets $?. We emulate - # Unix on the former but not the latter. - def `(command) #:nodoc: - super - rescue Errno::ENOENT => e - STDERR.puts "#$0: #{e}" - end - - # Method that requires a library, ensuring that rubygems is loaded - def require_library_or_gem(library_name) - begin - require library_name - rescue LoadError => cannot_require - # 1. Requiring the module is unsuccessful, maybe it's a gem and nobody required rubygems yet. Try. - begin - require 'rubygems' - rescue LoadError => rubygems_not_installed - raise cannot_require - end - # 2. Rubygems is installed and loaded. Try to load the library again - begin - require library_name - rescue LoadError => gem_not_installed - raise cannot_require - end - end - end - - -end diff --git a/tracks/vendor/rails/activesupport/lib/active_support/core_ext/load_error.rb b/tracks/vendor/rails/activesupport/lib/active_support/core_ext/load_error.rb deleted file mode 100644 index fac4639e..00000000 --- a/tracks/vendor/rails/activesupport/lib/active_support/core_ext/load_error.rb +++ /dev/null @@ -1,38 +0,0 @@ -class MissingSourceFile < LoadError #:nodoc: - attr_reader :path - def initialize(message, path) - super(message) - @path = path - end - - def is_missing?(path) - path.gsub(/\.rb$/, '') == self.path.gsub(/\.rb$/, '') - end - - def self.from_message(message) - REGEXPS.each do |regexp, capture| - match = regexp.match(message) - return MissingSourceFile.new(message, match[capture]) unless match.nil? - end - nil - end - - REGEXPS = [ - [/^no such file to load -- (.+)$/i, 1], - [/^Missing \w+ (file\s*)?([^\s]+.rb)$/i, 2], - [/^Missing API definition file in (.+)$/i, 1] - ] -end - -module ActiveSupport #:nodoc: - module CoreExtensions #:nodoc: - module LoadErrorExtensions #:nodoc: - module LoadErrorClassMethods #:nodoc: - def new(*args) - (self == LoadError && MissingSourceFile.from_message(args.first)) || super - end - end - ::LoadError.extend(LoadErrorClassMethods) - end - end -end diff --git a/tracks/vendor/rails/activesupport/lib/active_support/core_ext/numeric.rb b/tracks/vendor/rails/activesupport/lib/active_support/core_ext/numeric.rb deleted file mode 100644 index 88fead7a..00000000 --- a/tracks/vendor/rails/activesupport/lib/active_support/core_ext/numeric.rb +++ /dev/null @@ -1,7 +0,0 @@ -require File.dirname(__FILE__) + '/numeric/time' -require File.dirname(__FILE__) + '/numeric/bytes' - -class Numeric #:nodoc: - include ActiveSupport::CoreExtensions::Numeric::Time - include ActiveSupport::CoreExtensions::Numeric::Bytes -end diff --git a/tracks/vendor/rails/activesupport/lib/active_support/core_ext/numeric/bytes.rb b/tracks/vendor/rails/activesupport/lib/active_support/core_ext/numeric/bytes.rb deleted file mode 100644 index 56477673..00000000 --- a/tracks/vendor/rails/activesupport/lib/active_support/core_ext/numeric/bytes.rb +++ /dev/null @@ -1,44 +0,0 @@ -module ActiveSupport #:nodoc: - module CoreExtensions #:nodoc: - module Numeric #:nodoc: - # Enables the use of byte calculations and declarations, like 45.bytes + 2.6.megabytes - module Bytes - def bytes - self - end - alias :byte :bytes - - def kilobytes - self * 1024 - end - alias :kilobyte :kilobytes - - def megabytes - self * 1024.kilobytes - end - alias :megabyte :megabytes - - def gigabytes - self * 1024.megabytes - end - alias :gigabyte :gigabytes - - def terabytes - self * 1024.gigabytes - end - alias :terabyte :terabytes - - def petabytes - self * 1024.terabytes - end - alias :petabyte :petabytes - - def exabytes - self * 1024.petabytes - end - alias :exabyte :exabytes - - end - end - end -end diff --git a/tracks/vendor/rails/activesupport/lib/active_support/core_ext/numeric/time.rb b/tracks/vendor/rails/activesupport/lib/active_support/core_ext/numeric/time.rb deleted file mode 100644 index de726281..00000000 --- a/tracks/vendor/rails/activesupport/lib/active_support/core_ext/numeric/time.rb +++ /dev/null @@ -1,59 +0,0 @@ -module ActiveSupport #:nodoc: - module CoreExtensions #:nodoc: - module Numeric #:nodoc: - # Enables the use of time calculations and declarations, like 45.minutes + 2.hours + 4.years - module Time - def minutes - self * 60 - end - alias :minute :minutes - - def hours - self * 60.minutes - end - alias :hour :hours - - def days - self * 24.hours - end - alias :day :days - - def weeks - self * 7.days - end - alias :week :weeks - - def fortnights - self * 2.weeks - end - alias :fortnight :fortnights - - def months - self * 30.days - end - alias :month :months - - def years - (self * 365.25.days).to_i - end - alias :year :years - - # Reads best without arguments: 10.minutes.ago - def ago(time = ::Time.now) - time - self - end - - # Reads best with argument: 10.minutes.until(time) - alias :until :ago - - # Reads best with argument: 10.minutes.since(time) - def since(time = ::Time.now) - time + self - end - - # Reads best without arguments: 10.minutes.from_now - alias :from_now :since - end - end - end -end diff --git a/tracks/vendor/rails/activesupport/lib/active_support/core_ext/object_and_class.rb b/tracks/vendor/rails/activesupport/lib/active_support/core_ext/object_and_class.rb deleted file mode 100644 index 1e080d35..00000000 --- a/tracks/vendor/rails/activesupport/lib/active_support/core_ext/object_and_class.rb +++ /dev/null @@ -1,44 +0,0 @@ -class Object #:nodoc: - def remove_subclasses_of(*superclasses) - subclasses_of(*superclasses).each do |subclass| - Object.send(:remove_const, subclass.to_s) rescue nil - end - end - - def subclasses_of(*superclasses) - subclasses = [] - ObjectSpace.each_object(Class) do |k| - next if (k.ancestors & superclasses).empty? || superclasses.include?(k) || k.to_s.include?("::") || subclasses.include?(k) - subclasses << k - end - subclasses - end - - # "", " ", nil, [], and {} are blank - def blank? - if respond_to?(:empty?) && respond_to?(:strip) - empty? or strip.empty? - elsif respond_to?(:empty?) - empty? - else - !self - end - end - - def suppress(*exception_classes) - begin yield - rescue Exception => e - raise unless exception_classes.any? {|cls| e.kind_of? cls} - end - end -end - -class Class #:nodoc: - def remove_subclasses - Object.remove_subclasses_of(self) - end - - def subclasses - Object.subclasses_of(self).map { |o| o.to_s } - end -end diff --git a/tracks/vendor/rails/activesupport/lib/active_support/core_ext/range.rb b/tracks/vendor/rails/activesupport/lib/active_support/core_ext/range.rb deleted file mode 100644 index ca775115..00000000 --- a/tracks/vendor/rails/activesupport/lib/active_support/core_ext/range.rb +++ /dev/null @@ -1,5 +0,0 @@ -require File.dirname(__FILE__) + '/range/conversions' - -class Range #:nodoc: - include ActiveSupport::CoreExtensions::Range::Conversions -end diff --git a/tracks/vendor/rails/activesupport/lib/active_support/core_ext/range/conversions.rb b/tracks/vendor/rails/activesupport/lib/active_support/core_ext/range/conversions.rb deleted file mode 100644 index 677ba639..00000000 --- a/tracks/vendor/rails/activesupport/lib/active_support/core_ext/range/conversions.rb +++ /dev/null @@ -1,21 +0,0 @@ -module ActiveSupport #:nodoc: - module CoreExtensions #:nodoc: - module Range #:nodoc: - # Getting dates in different convenient string representations and other objects - module Conversions - DATE_FORMATS = { - :db => Proc.new { |start, stop| "BETWEEN '#{start.to_s(:db)}' AND '#{stop.to_s(:db)}'" } - } - - def self.included(klass) #:nodoc: - klass.send(:alias_method, :to_default_s, :to_s) - klass.send(:alias_method, :to_s, :to_formatted_s) - end - - def to_formatted_s(format = :default) - DATE_FORMATS[format] ? DATE_FORMATS[format].call(first, last) : to_default_s - end - end - end - end -end \ No newline at end of file diff --git a/tracks/vendor/rails/activesupport/lib/active_support/core_ext/string.rb b/tracks/vendor/rails/activesupport/lib/active_support/core_ext/string.rb deleted file mode 100644 index 979f8a05..00000000 --- a/tracks/vendor/rails/activesupport/lib/active_support/core_ext/string.rb +++ /dev/null @@ -1,11 +0,0 @@ -require File.dirname(__FILE__) + '/string/inflections' -require File.dirname(__FILE__) + '/string/conversions' -require File.dirname(__FILE__) + '/string/access' -require File.dirname(__FILE__) + '/string/starts_ends_with' - -class String #:nodoc: - include ActiveSupport::CoreExtensions::String::Access - include ActiveSupport::CoreExtensions::String::Conversions - include ActiveSupport::CoreExtensions::String::Inflections - include ActiveSupport::CoreExtensions::String::StartsEndsWith -end diff --git a/tracks/vendor/rails/activesupport/lib/active_support/core_ext/string/access.rb b/tracks/vendor/rails/activesupport/lib/active_support/core_ext/string/access.rb deleted file mode 100644 index f59690b0..00000000 --- a/tracks/vendor/rails/activesupport/lib/active_support/core_ext/string/access.rb +++ /dev/null @@ -1,58 +0,0 @@ -module ActiveSupport #:nodoc: - module CoreExtensions #:nodoc: - module String #:nodoc: - # Makes it easier to access parts of a string, such as specific characters and substrings. - module Access - # Returns the character at the +position+ treating the string as an array (where 0 is the first character). - # - # Examples: - # "hello".at(0) # => "h" - # "hello".at(4) # => "o" - # "hello".at(10) # => nil - def at(position) - self[position, 1] - end - - # Returns the remaining of the string from the +position+ treating the string as an array (where 0 is the first character). - # - # Examples: - # "hello".from(0) # => "hello" - # "hello".from(2) # => "llo" - # "hello".from(10) # => nil - def from(position) - self[position..-1] - end - - # Returns the beginning of the string up to the +position+ treating the string as an array (where 0 is the first character). - # - # Examples: - # "hello".to(0) # => "h" - # "hello".to(2) # => "hel" - # "hello".to(10) # => "hello" - def to(position) - self[0..position] - end - - # Returns the first character of the string or the first +limit+ characters. - # - # Examples: - # "hello".first # => "h" - # "hello".first(2) # => "he" - # "hello".first(10) # => "hello" - def first(limit = 1) - self[0..(limit - 1)] - end - - # Returns the last character of the string or the last +limit+ characters. - # - # Examples: - # "hello".last # => "o" - # "hello".last(2) # => "lo" - # "hello".last(10) # => "hello" - def last(limit = 1) - self[(-limit)..-1] - end - end - end - end -end \ No newline at end of file diff --git a/tracks/vendor/rails/activesupport/lib/active_support/core_ext/string/conversions.rb b/tracks/vendor/rails/activesupport/lib/active_support/core_ext/string/conversions.rb deleted file mode 100644 index cfb767d1..00000000 --- a/tracks/vendor/rails/activesupport/lib/active_support/core_ext/string/conversions.rb +++ /dev/null @@ -1,19 +0,0 @@ -require 'parsedate' - -module ActiveSupport #:nodoc: - module CoreExtensions #:nodoc: - module String #:nodoc: - # Converting strings to other objects - module Conversions - # Form can be either :utc (default) or :local. - def to_time(form = :utc) - ::Time.send(form, *ParseDate.parsedate(self)) - end - - def to_date - ::Date.new(*ParseDate.parsedate(self)[0..2]) - end - end - end - end -end \ No newline at end of file diff --git a/tracks/vendor/rails/activesupport/lib/active_support/core_ext/string/inflections.rb b/tracks/vendor/rails/activesupport/lib/active_support/core_ext/string/inflections.rb deleted file mode 100644 index 9b5e9ddf..00000000 --- a/tracks/vendor/rails/activesupport/lib/active_support/core_ext/string/inflections.rb +++ /dev/null @@ -1,57 +0,0 @@ -require File.dirname(__FILE__) + '/../../inflector' -module ActiveSupport #:nodoc: - module CoreExtensions #:nodoc: - module String #:nodoc: - # Makes it possible to do "posts".singularize that returns "post" and "MegaCoolClass".underscore that returns "mega_cool_class". - module Inflections - def pluralize - Inflector.pluralize(self) - end - - def singularize - Inflector.singularize(self) - end - - def camelize - Inflector.camelize(self) - end - alias_method :camelcase, :camelize - - def titleize - Inflector.titleize(self) - end - alias_method :titlecase, :titleize - - def underscore - Inflector.underscore(self) - end - - def demodulize - Inflector.demodulize(self) - end - - def tableize - Inflector.tableize(self) - end - - def classify - Inflector.classify(self) - end - - # Capitalizes the first word and turns underscores into spaces and strips _id, so "employee_salary" becomes "Employee salary" - # and "author_id" becomes "Author". - def humanize - Inflector.humanize(self) - end - - def foreign_key(separate_class_name_and_id_with_underscore = true) - Inflector.foreign_key(self, separate_class_name_and_id_with_underscore) - end - - def constantize - Inflector.constantize(self) - end - end - end - end -end diff --git a/tracks/vendor/rails/activesupport/lib/active_support/core_ext/string/starts_ends_with.rb b/tracks/vendor/rails/activesupport/lib/active_support/core_ext/string/starts_ends_with.rb deleted file mode 100644 index 67174019..00000000 --- a/tracks/vendor/rails/activesupport/lib/active_support/core_ext/string/starts_ends_with.rb +++ /dev/null @@ -1,20 +0,0 @@ -module ActiveSupport #:nodoc: - module CoreExtensions #:nodoc: - module String #:nodoc: - # Additional string tests. - module StartsEndsWith - # Does the string start with the specified +prefix+? - def starts_with?(prefix) - prefix = prefix.to_s - self[0, prefix.length] == prefix - end - - # Does the string end with the specified +suffix+? - def ends_with?(suffix) - suffix = suffix.to_s - self[-suffix.length, suffix.length] == suffix - end - end - end - end -end diff --git a/tracks/vendor/rails/activesupport/lib/active_support/core_ext/time.rb b/tracks/vendor/rails/activesupport/lib/active_support/core_ext/time.rb deleted file mode 100644 index 9e3c7a03..00000000 --- a/tracks/vendor/rails/activesupport/lib/active_support/core_ext/time.rb +++ /dev/null @@ -1,7 +0,0 @@ -require File.dirname(__FILE__) + '/time/calculations' -require File.dirname(__FILE__) + '/time/conversions' - -class Time#:nodoc: - include ActiveSupport::CoreExtensions::Time::Calculations - include ActiveSupport::CoreExtensions::Time::Conversions -end diff --git a/tracks/vendor/rails/activesupport/lib/active_support/core_ext/time/calculations.rb b/tracks/vendor/rails/activesupport/lib/active_support/core_ext/time/calculations.rb deleted file mode 100644 index 43424df8..00000000 --- a/tracks/vendor/rails/activesupport/lib/active_support/core_ext/time/calculations.rb +++ /dev/null @@ -1,174 +0,0 @@ -module ActiveSupport #:nodoc: - module CoreExtensions #:nodoc: - module Time #:nodoc: - # Enables the use of time calculations within Time itself - module Calculations - def self.append_features(base) #:nodoc: - super - base.extend(ClassMethods) - end - - module ClassMethods - # Return the number of days in the given month. If a year is given, - # February will return the correct number of days for leap years. - # Otherwise, this method will always report February as having 28 - # days. - def days_in_month(month, year=nil) - if month == 2 - !year.nil? && (year % 4 == 0) && ((year % 100 != 0) || (year % 400 == 0)) ? 29 : 28 - elsif month <= 7 - month % 2 == 0 ? 30 : 31 - else - month % 2 == 0 ? 31 : 30 - end - end - end - - # Seconds since midnight: Time.now.seconds_since_midnight - def seconds_since_midnight - self.hour.hours + self.min.minutes + self.sec + (self.usec/1.0e+6) - end - - # Returns a new Time where one or more of the elements have been changed according to the +options+ parameter. The time options - # (hour, minute, sec, usec) reset cascadingly, so if only the hour is passed, then minute, sec, and usec is set to 0. If the hour and - # minute is passed, then sec and usec is set to 0. - def change(options) - ::Time.send( - self.utc? ? :utc : :local, - options[:year] || self.year, - options[:month] || self.month, - options[:mday] || self.mday, - options[:hour] || self.hour, - options[:min] || (options[:hour] ? 0 : self.min), - options[:sec] || ((options[:hour] || options[:min]) ? 0 : self.sec), - options[:usec] || ((options[:hour] || options[:min] || options[:sec]) ? 0 : self.usec) - ) - end - - # Returns a new Time representing the time a number of seconds ago, this is basically a wrapper around the Numeric extension - # Do not use this method in combination with x.months, use months_ago instead! - def ago(seconds) - seconds.until(self) - end - - # Returns a new Time representing the time a number of seconds since the instance time, this is basically a wrapper around - #the Numeric extension. Do not use this method in combination with x.months, use months_since instead! - def since(seconds) - seconds.since(self) - end - alias :in :since - - # Returns a new Time representing the time a number of specified months ago - def months_ago(months) - months_since(-months) - end - - def months_since(months) - year, month, mday = self.year, self.month, self.mday - - month += months - - # in case months is negative - while month < 1 - month += 12 - year -= 1 - end - - # in case months is positive - while month > 12 - month -= 12 - year += 1 - end - - max = ::Time.days_in_month(month, year) - mday = max if mday > max - - change(:year => year, :month => month, :mday => mday) - end - - # Returns a new Time representing the time a number of specified years ago - def years_ago(years) - change(:year => self.year - years) - end - - def years_since(years) - change(:year => self.year + years) - end - - # Short-hand for years_ago(1) - def last_year - years_ago(1) - end - - # Short-hand for years_since(1) - def next_year - years_since(1) - end - - - # Short-hand for months_ago(1) - def last_month - months_ago(1) - end - - # Short-hand for months_since(1) - def next_month - months_since(1) - end - - # Returns a new Time representing the "start" of this week (Monday, 0:00) - def beginning_of_week - days_to_monday = self.wday!=0 ? self.wday-1 : 6 - (self - days_to_monday.days).midnight - end - alias :monday :beginning_of_week - alias :at_beginning_of_week :beginning_of_week - - # Returns a new Time representing the start of the given day in next week (default is Monday). - def next_week(day = :monday) - days_into_week = { :monday => 0, :tuesday => 1, :wednesday => 2, :thursday => 3, :friday => 4, :saturday => 5, :sunday => 6} - since(1.week).beginning_of_week.since(days_into_week[day].day).change(:hour => 0) - end - - # Returns a new Time representing the start of the day (0:00) - def beginning_of_day - (self - self.seconds_since_midnight).change(:usec => 0) - end - alias :midnight :beginning_of_day - alias :at_midnight :beginning_of_day - alias :at_beginning_of_day :beginning_of_day - - # Returns a new Time representing the start of the month (1st of the month, 0:00) - def beginning_of_month - #self - ((self.mday-1).days + self.seconds_since_midnight) - change(:mday => 1,:hour => 0, :min => 0, :sec => 0, :usec => 0) - end - alias :at_beginning_of_month :beginning_of_month - - # Returns a new Time representing the end of the month (last day of the month, 0:00) - def end_of_month - #self - ((self.mday-1).days + self.seconds_since_midnight) - last_day = ::Time.days_in_month( self.month, self.year ) - change(:mday => last_day,:hour => 0, :min => 0, :sec => 0, :usec => 0) - end - alias :at_end_of_month :end_of_month - - # Returns a new Time representing the start of the year (1st of january, 0:00) - def beginning_of_year - change(:month => 1,:mday => 1,:hour => 0, :min => 0, :sec => 0, :usec => 0) - end - alias :at_beginning_of_year :beginning_of_year - - # Convenience method which returns a new Time representing the time 1 day ago - def yesterday - self.ago(1.day) - end - - # Convenience method which returns a new Time representing the time 1 day since the instance time - def tomorrow - self.since(1.day) - end - end - end - end -end diff --git a/tracks/vendor/rails/activesupport/lib/active_support/core_ext/time/conversions.rb b/tracks/vendor/rails/activesupport/lib/active_support/core_ext/time/conversions.rb deleted file mode 100644 index 408ff515..00000000 --- a/tracks/vendor/rails/activesupport/lib/active_support/core_ext/time/conversions.rb +++ /dev/null @@ -1,36 +0,0 @@ -require 'date' - -module ActiveSupport #:nodoc: - module CoreExtensions #:nodoc: - module Time #:nodoc: - # Getting times in different convenient string representations and other objects - module Conversions - DATE_FORMATS = { - :db => "%Y-%m-%d %H:%M:%S", - :short => "%d %b %H:%M", - :long => "%B %d, %Y %H:%M", - :rfc822 => "%a, %d %b %Y %H:%M:%S %z" - } - - def self.append_features(klass) - super - klass.send(:alias_method, :to_default_s, :to_s) - klass.send(:alias_method, :to_s, :to_formatted_s) - end - - def to_formatted_s(format = :default) - DATE_FORMATS[format] ? strftime(DATE_FORMATS[format]).strip : to_default_s - end - - def to_date - ::Date.new(year, month, day) - end - - # To be able to keep Dates and Times interchangeable on conversions - def to_time - self - end - end - end - end -end diff --git a/tracks/vendor/rails/activesupport/lib/active_support/dependencies.rb b/tracks/vendor/rails/activesupport/lib/active_support/dependencies.rb deleted file mode 100644 index 9681af6d..00000000 --- a/tracks/vendor/rails/activesupport/lib/active_support/dependencies.rb +++ /dev/null @@ -1,240 +0,0 @@ -require File.dirname(__FILE__) + '/module_attribute_accessors' -require File.dirname(__FILE__) + '/core_ext/load_error' - -module Dependencies #:nodoc: - extend self - - @@loaded = [ ] - mattr_accessor :loaded - - @@mechanism = :load - mattr_accessor :mechanism - - def load? - mechanism == :load - end - - def depend_on(file_name, swallow_load_errors = false) - unless loaded.include?(file_name) - loaded << file_name - - begin - require_or_load(file_name) - rescue LoadError - raise unless swallow_load_errors - end - end - end - - def associate_with(file_name) - depend_on(file_name, true) - end - - def clear - self.loaded = [ ] - end - - def require_or_load(file_name) - file_name = "#{file_name}.rb" unless ! load? || file_name[-3..-1] == '.rb' - load? ? load(file_name) : require(file_name) - end - - def remove_subclasses_for(*classes) - Object.remove_subclasses_of(*classes) - end - - # LoadingModules implement namespace-safe dynamic loading. - # They support automatic loading via const_missing, allowing contained items to be automatically - # loaded when required. No extra syntax is required, as expressions such as Controller::Admin::UserController - # load the relavent files automatically. - # - # Ruby-style modules are supported, as a folder named 'submodule' will load 'submodule.rb' when available. - class LoadingModule < Module #:nodoc: - attr_reader :path - attr_reader :root - - class << self - def root(*load_paths) - RootLoadingModule.new(*load_paths) - end - end - - def initialize(root, path=[]) - @path = path.clone.freeze - @root = root - end - - def root?() self.root == self end - def load_paths() self.root.load_paths end - - # Load missing constants if possible. - def const_missing(name) - const_load!(name) ? const_get(name) : super(name) - end - - # Load the controller class or a parent module. - def const_load!(name, file_name = nil) - file_name ||= 'application' if root? && name.to_s == 'ApplicationController' - path = self.path + [file_name || name] - - load_paths.each do |load_path| - fs_path = load_path.filesystem_path(path) - next unless fs_path - - case - when File.directory?(fs_path) - new_module = LoadingModule.new(self.root, self.path + [name]) - self.const_set name, new_module - if self.root? - if Object.const_defined?(name) - msg = "Cannot load module #{name}: Object::#{name} is set to #{Object.const_get(name).inspect}" - raise NameError, msg - end - Object.const_set(name, new_module) - end - break - when File.file?(fs_path) - loaded_file = self.root.load_file!(fs_path) - - # Import the loaded constant from Object provided we are the root node. - self.const_set(name, Object.const_get(name)) if self.root? && Object.const_defined?(name) - - # Throw an error if we load the file but we don't find the Object we expect - if loaded_file and not self.const_defined?(name) - msg = "Already loaded file '#{fs_path}' but '#{name.to_s}' was not set, perhaps you need to rename '#{fs_path}'?" - raise LoadError, msg - end - break - end - end - - self.const_defined?(name) - end - - # Is this name present or loadable? - # This method is used by Routes to find valid controllers. - def const_available?(name) - self.const_defined?(name) || load_paths.any? {|lp| lp.filesystem_path(path + [name])} - end - end - - class RootLoadingModule < LoadingModule #:nodoc: - attr_reader :load_paths - - def initialize(*paths) - @load_paths = paths.flatten.collect {|p| p.kind_of?(ConstantLoadPath) ? p : ConstantLoadPath.new(p)} - end - - def root() self end - - def path() [] end - - # Load the source file at the given file path - def load_file!(file_path) - require_dependency(file_path) - end - - # Erase all items in this module - def clear! - constants.each do |name| - Object.send(:remove_const, name) if Object.const_defined?(name) && Object.const_get(name).object_id == self.const_get(name).object_id - self.send(:remove_const, name) - end - end - end - - # This object defines a path from which Constants can be loaded. - class ConstantLoadPath #:nodoc: - # Create a new load path with the filesystem path - def initialize(root) @root = root end - - # Return nil if the path does not exist, or the path to a directory - # if the path leads to a module, or the path to a file if it leads to an object. - def filesystem_path(path, allow_module=true) - fs_path = [@root] - fs_path += path[0..-2].map {|name| const_name_to_module_name name} - - if allow_module - result = File.join(fs_path, const_name_to_module_name(path.last)) - return result if File.directory? result # Return the module path if one exists - end - - result = File.join(fs_path, const_name_to_file_name(path.last)) - - File.file?(result) ? result : nil - end - - def const_name_to_file_name(name) - name.to_s.underscore + '.rb' - end - - def const_name_to_module_name(name) - name.to_s.underscore - end - end -end - -Object.send(:define_method, :require_or_load) { |file_name| Dependencies.require_or_load(file_name) } unless Object.respond_to?(:require_or_load) -Object.send(:define_method, :require_dependency) { |file_name| Dependencies.depend_on(file_name) } unless Object.respond_to?(:require_dependency) -Object.send(:define_method, :require_association) { |file_name| Dependencies.associate_with(file_name) } unless Object.respond_to?(:require_association) - -class Module #:nodoc: - # Rename the original handler so we can chain it to the new one - alias :rails_original_const_missing :const_missing - - # Use const_missing to autoload associations so we don't have to - # require_association when using single-table inheritance. - def const_missing(class_id) - if Object.const_defined?(:Controllers) and Object::Controllers.const_available?(class_id) - return Object::Controllers.const_get(class_id) - end - - file_name = class_id.to_s.demodulize.underscore - begin - require_dependency(file_name) - raise NameError.new("uninitialized constant #{class_id}") unless Object.const_defined?(class_id) - return Object.const_get(class_id) - rescue MissingSourceFile => e - # Convert the exception to a NameError only if the file we are looking for is the missing one. - raise unless e.is_missing? file_name - raise NameError.new("uninitialized constant #{class_id}").copy_blame!(e) - end - end -end - -class Object #:nodoc: - def load(file, *extras) - super(file, *extras) - rescue Object => exception - exception.blame_file! file - raise - end - - def require(file, *extras) - super(file, *extras) - rescue Object => exception - exception.blame_file! file - raise - end -end - -# Add file-blaming to exceptions -class Exception #:nodoc: - def blame_file!(file) - (@blamed_files ||= []).unshift file - end - - def blamed_files - @blamed_files ||= [] - end - - def describe_blame - return nil if blamed_files.empty? - "This error occured while loading the following files:\n #{blamed_files.join "\n "}" - end - - def copy_blame!(exc) - @blamed_files = exc.blamed_files.clone - self - end -end diff --git a/tracks/vendor/rails/activesupport/lib/active_support/inflections.rb b/tracks/vendor/rails/activesupport/lib/active_support/inflections.rb deleted file mode 100644 index 18fa4c33..00000000 --- a/tracks/vendor/rails/activesupport/lib/active_support/inflections.rb +++ /dev/null @@ -1,53 +0,0 @@ -Inflector.inflections do |inflect| - inflect.plural /$/, 's' - inflect.plural /s$/i, 's' - inflect.plural /(ax|test)is$/i, '\1es' - inflect.plural /(octop|vir)us$/i, '\1i' - inflect.plural /(alias|status)$/i, '\1es' - inflect.plural /(bu)s$/i, '\1ses' - inflect.plural /(buffal|tomat)o$/i, '\1oes' - inflect.plural /([ti])um$/i, '\1a' - inflect.plural /sis$/i, 'ses' - inflect.plural /(?:([^f])fe|([lr])f)$/i, '\1\2ves' - inflect.plural /(hive)$/i, '\1s' - inflect.plural /([^aeiouy]|qu)y$/i, '\1ies' - inflect.plural /([^aeiouy]|qu)ies$/i, '\1y' - inflect.plural /(x|ch|ss|sh)$/i, '\1es' - inflect.plural /(matr|vert|ind)ix|ex$/i, '\1ices' - inflect.plural /([m|l])ouse$/i, '\1ice' - inflect.plural /^(ox)$/i, '\1en' - inflect.plural /(quiz)$/i, '\1zes' - - inflect.singular /s$/i, '' - inflect.singular /(n)ews$/i, '\1ews' - inflect.singular /([ti])a$/i, '\1um' - inflect.singular /((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$/i, '\1\2sis' - inflect.singular /(^analy)ses$/i, '\1sis' - inflect.singular /([^f])ves$/i, '\1fe' - inflect.singular /(hive)s$/i, '\1' - inflect.singular /(tive)s$/i, '\1' - inflect.singular /([lr])ves$/i, '\1f' - inflect.singular /([^aeiouy]|qu)ies$/i, '\1y' - inflect.singular /(s)eries$/i, '\1eries' - inflect.singular /(m)ovies$/i, '\1ovie' - inflect.singular /(x|ch|ss|sh)es$/i, '\1' - inflect.singular /([m|l])ice$/i, '\1ouse' - inflect.singular /(bus)es$/i, '\1' - inflect.singular /(o)es$/i, '\1' - inflect.singular /(shoe)s$/i, '\1' - inflect.singular /(cris|ax|test)es$/i, '\1is' - inflect.singular /([octop|vir])i$/i, '\1us' - inflect.singular /(alias|status)es$/i, '\1' - inflect.singular /^(ox)en/i, '\1' - inflect.singular /(vert|ind)ices$/i, '\1ex' - inflect.singular /(matr)ices$/i, '\1ix' - inflect.singular /(quiz)zes$/i, '\1' - - inflect.irregular 'person', 'people' - inflect.irregular 'man', 'men' - inflect.irregular 'child', 'children' - inflect.irregular 'sex', 'sexes' - inflect.irregular 'move', 'moves' - - inflect.uncountable %w( equipment information rice money species series fish sheep ) -end diff --git a/tracks/vendor/rails/activesupport/lib/active_support/inflector.rb b/tracks/vendor/rails/activesupport/lib/active_support/inflector.rb deleted file mode 100644 index 2e69b74c..00000000 --- a/tracks/vendor/rails/activesupport/lib/active_support/inflector.rb +++ /dev/null @@ -1,166 +0,0 @@ -require 'singleton' - -# The Inflector transforms words from singular to plural, class names to table names, modularized class names to ones without, -# and class names to foreign keys. The default inflections for pluralization, singularization, and uncountable words are kept -# in inflections.rb. -module Inflector - # A singleton instance of this class is yielded by Inflector.inflections, which can then be used to specify additional - # inflection rules. Examples: - # - # Inflector.inflections do |inflect| - # inflect.plural /^(ox)$/i, '\1\2en' - # inflect.singular /^(ox)en/i, '\1' - # - # inflect.irregular 'octopus', 'octopi' - # - # inflect.uncountable "equipment" - # end - # - # New rules are added at the top. So in the example above, the irregular rule for octopus will now be the first of the - # pluralization and singularization rules that is runs. This guarantees that your rules run before any of the rules that may - # already have been loaded. - class Inflections - include Singleton - - attr_reader :plurals, :singulars, :uncountables - - def initialize - @plurals, @singulars, @uncountables = [], [], [] - end - - # Specifies a new pluralization rule and its replacement. The rule can either be a string or a regular expression. - # The replacement should always be a string that may include references to the matched data from the rule. - def plural(rule, replacement) - @plurals.insert(0, [rule, replacement]) - end - - # Specifies a new singularization rule and its replacement. The rule can either be a string or a regular expression. - # The replacement should always be a string that may include references to the matched data from the rule. - def singular(rule, replacement) - @singulars.insert(0, [rule, replacement]) - end - - # Specifies a new irregular that applies to both pluralization and singularization at the same time. This can only be used - # for strings, not regular expressions. You simply pass the irregular in singular and plural form. - # - # Examples: - # irregular 'octopus', 'octopi' - # irregular 'person', 'people' - def irregular(singular, plural) - plural(Regexp.new("(#{singular[0,1]})#{singular[1..-1]}$", "i"), '\1' + plural[1..-1]) - singular(Regexp.new("(#{plural[0,1]})#{plural[1..-1]}$", "i"), '\1' + singular[1..-1]) - end - - # Add uncountable words that shouldn't be attempted inflected. - # - # Examples: - # uncountable "money" - # uncountable "money", "information" - # uncountable %w( money information rice ) - def uncountable(*words) - (@uncountables << words).flatten! - end - - # Clears the loaded inflections within a given scope (default is :all). Give the scope as a symbol of the inflection type, - # the options are: :plurals, :singulars, :uncountables - # - # Examples: - # clear :all - # clear :plurals - def clear(scope = :all) - case scope - when :all - @plurals, @singulars, @uncountables = [], [], [] - else - instance_variable_set "@#{scope}", [] - end - end - end - - extend self - - def inflections - if block_given? - yield Inflections.instance - else - Inflections.instance - end - end - - def pluralize(word) - result = word.to_s.dup - - if inflections.uncountables.include?(result.downcase) - result - else - inflections.plurals.each { |(rule, replacement)| break if result.gsub!(rule, replacement) } - result - end - end - - def singularize(word) - result = word.to_s.dup - - if inflections.uncountables.include?(result.downcase) - result - else - inflections.singulars.each { |(rule, replacement)| break if result.gsub!(rule, replacement) } - result - end - end - - def camelize(lower_case_and_underscored_word) - lower_case_and_underscored_word.to_s.gsub(/\/(.?)/) { "::" + $1.upcase }.gsub(/(^|_)(.)/) { $2.upcase } - end - - def titleize(word) - humanize(underscore(word)).gsub(/\b([a-z])/) { $1.capitalize } - end - - def underscore(camel_cased_word) - camel_cased_word.to_s.gsub(/::/, '/').gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').gsub(/([a-z\d])([A-Z])/,'\1_\2').downcase - end - - def humanize(lower_case_and_underscored_word) - lower_case_and_underscored_word.to_s.gsub(/_id$/, "").gsub(/_/, " ").capitalize - end - - def demodulize(class_name_in_module) - class_name_in_module.to_s.gsub(/^.*::/, '') - end - - def tableize(class_name) - pluralize(underscore(class_name)) - end - - def classify(table_name) - camelize(singularize(table_name)) - end - - def foreign_key(class_name, separate_class_name_and_id_with_underscore = true) - underscore(demodulize(class_name)) + (separate_class_name_and_id_with_underscore ? "_id" : "id") - end - - def constantize(camel_cased_word) - raise NameError, "#{camel_cased_word.inspect} is not a valid constant name!" unless - camel_cased_word.split("::").all? { |part| /^[A-Z]\w*$/ =~ part } - - camel_cased_word = "::#{camel_cased_word}" unless camel_cased_word[0, 2] == '::' - Object.module_eval(camel_cased_word, __FILE__, __LINE__) - end - - def ordinalize(number) - if (11..13).include?(number.to_i % 100) - "#{number}th" - else - case number.to_i % 10 - when 1: "#{number}st" - when 2: "#{number}nd" - when 3: "#{number}rd" - else "#{number}th" - end - end - end -end - -require File.dirname(__FILE__) + '/inflections' diff --git a/tracks/vendor/rails/activesupport/lib/active_support/module_attribute_accessors.rb b/tracks/vendor/rails/activesupport/lib/active_support/module_attribute_accessors.rb deleted file mode 100644 index 3d466e44..00000000 --- a/tracks/vendor/rails/activesupport/lib/active_support/module_attribute_accessors.rb +++ /dev/null @@ -1,57 +0,0 @@ -# Extends the module object with module and instance accessors for class attributes, -# just like the native attr* accessors for instance attributes. -class Module # :nodoc: - def mattr_reader(*syms) - syms.each do |sym| - class_eval <<-EOS - if ! defined? @@#{sym.id2name} - @@#{sym.id2name} = nil - end - - def self.#{sym.id2name} - @@#{sym} - end - - def #{sym.id2name} - @@#{sym} - end - - def call_#{sym.id2name} - case @@#{sym.id2name} - when Symbol then send(@@#{sym}) - when Proc then @@#{sym}.call(self) - when String then @@#{sym} - else nil - end - end - EOS - end - end - - def mattr_writer(*syms) - syms.each do |sym| - class_eval <<-EOS - if ! defined? @@#{sym.id2name} - @@#{sym.id2name} = nil - end - - def self.#{sym.id2name}=(obj) - @@#{sym.id2name} = obj - end - - def self.set_#{sym.id2name}(obj) - @@#{sym.id2name} = obj - end - - def #{sym.id2name}=(obj) - @@#{sym} = obj - end - EOS - end - end - - def mattr_accessor(*syms) - mattr_reader(*syms) - mattr_writer(*syms) - end -end \ No newline at end of file diff --git a/tracks/vendor/rails/activesupport/lib/active_support/ordered_options.rb b/tracks/vendor/rails/activesupport/lib/active_support/ordered_options.rb deleted file mode 100644 index ed5d4d31..00000000 --- a/tracks/vendor/rails/activesupport/lib/active_support/ordered_options.rb +++ /dev/null @@ -1,31 +0,0 @@ -class OrderedOptions < Array #:nodoc: - def []=(key, value) - key = key.to_sym - - if pair = find_pair(key) - pair.pop - pair << value - else - self << [key, value] - end - end - - def [](key) - pair = find_pair(key.to_sym) - pair ? pair.last : nil - end - - def method_missing(name, *args) - if name.to_s =~ /(.*)=$/ - self[$1.to_sym] = args.first - else - self[name] - end - end - - private - def find_pair(key) - self.each { |i| return i if i.first == key } - return false - end -end \ No newline at end of file diff --git a/tracks/vendor/rails/activesupport/lib/active_support/values/time_zone.rb b/tracks/vendor/rails/activesupport/lib/active_support/values/time_zone.rb deleted file mode 100644 index 3aa135c2..00000000 --- a/tracks/vendor/rails/activesupport/lib/active_support/values/time_zone.rb +++ /dev/null @@ -1,180 +0,0 @@ -# A value object representing a time zone. A time zone is simply a named -# offset (in seconds) from GMT. Note that two time zone objects are only -# equivalent if they have both the same offset, and the same name. -# -# A TimeZone instance may be used to convert a Time value to the corresponding -# time zone. -# -# The class also includes #all, which returns a list of all TimeZone objects. -class TimeZone - include Comparable - - attr_reader :name, :utc_offset - - # Create a new TimeZone object with the given name and offset. The offset is - # the number of seconds that this time zone is offset from UTC (GMT). Seconds - # were chosen as the offset unit because that is the unit that Ruby uses - # to represent time zone offsets (see Time#utc_offset). - def initialize(name, utc_offset) - @name = name - @utc_offset = utc_offset - end - - # Returns the offset of this time zone as a formatted string, of the - # format "+HH:MM". If the offset is zero, this returns the empty - # string. If +colon+ is false, a colon will not be inserted into the - # result. - def formatted_offset( colon=true ) - return "" if utc_offset == 0 - sign = (utc_offset < 0 ? -1 : 1) - hours = utc_offset.abs / 3600 - minutes = (utc_offset.abs % 3600) / 60 - "%+03d%s%02d" % [ hours * sign, colon ? ":" : "", minutes ] - end - - # Compute and return the current time, in the time zone represented by - # +self+. - def now - adjust(Time.now) - end - - # Return the current date in this time zone. - def today - now.to_date - end - - # Adjust the given time to the time zone represented by +self+. - def adjust(time) - time = time.to_time - time + utc_offset - time.utc_offset - end - - # Reinterprets the given time value as a time in the current time - # zone, and then adjusts it to return the corresponding time in the - # local time zone. - def unadjust(time) - time = Time.local(*time.to_time.to_a) - time - utc_offset + time.utc_offset - end - - # Compare this time zone to the parameter. The two are comapred first on - # their offsets, and then by name. - def <=>(zone) - result = (utc_offset <=> zone.utc_offset) - result = (name <=> zone.name) if result == 0 - result - end - - # Returns a textual representation of this time zone. - def to_s - "(GMT#{formatted_offset}) #{name}" - end - - @@zones = nil - - class << self - # Create a new TimeZone instance with the given name and offset. - def create(name, offset) - zone = allocate - zone.send :initialize, name, offset - zone - end - - # Return a TimeZone instance with the given name, or +nil+ if no - # such TimeZone instance exists. (This exists to support the use of - # this class with the #composed_of macro.) - def new(name) - self[name] - end - - # Return an array of all TimeZone objects. There are multiple TimeZone - # objects per time zone, in many cases, to make it easier for users to - # find their own time zone. - def all - unless @@zones - @@zones = [] - [[-43_200, "International Date Line West" ], - [-39_600, "Midway Island", "Samoa" ], - [-36_000, "Hawaii" ], - [-32_400, "Alaska" ], - [-28_800, "Pacific Time (US & Canada)", "Tijuana" ], - [-25_200, "Mountain Time (US & Canada)", "Chihuahua", "La Paz", - "Mazatlan", "Arizona" ], - [-21_600, "Central Time (US & Canada)", "Saskatchewan", "Guadalajara", - "Mexico City", "Monterrey", "Central America" ], - [-18_000, "Eastern Time (US & Canada)", "Indiana (East)", "Bogota", - "Lima", "Quito" ], - [-14_400, "Atlantic Time (Canada)", "Caracas", "La Paz", "Santiago" ], - [-12_600, "Newfoundland" ], - [-10_800, "Brasilia", "Buenos Aires", "Georgetown", "Greenland" ], - [ -7_200, "Mid-Atlantic" ], - [ -3_600, "Azores", "Cape Verde Is." ], - [ 0, "Dublin", "Edinburgh", "Lisbon", "London", "Casablanca", - "Monrovia" ], - [ 3_600, "Belgrade", "Bratislava", "Budapest", "Ljubljana", "Prague", - "Sarajevo", "Skopje", "Warsaw", "Zagreb", "Brussels", - "Copenhagen", "Madrid", "Paris", "Amsterdam", "Berlin", - "Bern", "Rome", "Stockholm", "Vienna", - "West Central Africa" ], - [ 7_200, "Bucharest", "Cairo", "Helsinki", "Kyev", "Riga", "Sofia", - "Tallinn", "Vilnius", "Athens", "Istanbul", "Minsk", - "Jerusalem", "Harare", "Pretoria" ], - [ 10_800, "Moscow", "St. Petersburg", "Volgograd", "Kuwait", "Riyadh", - "Nairobi", "Baghdad" ], - [ 12_600, "Tehran" ], - [ 14_400, "Abu Dhabi", "Muscat", "Baku", "Tbilisi", "Yerevan" ], - [ 16_200, "Kabul" ], - [ 18_000, "Ekaterinburg", "Islamabad", "Karachi", "Tashkent" ], - [ 19_800, "Chennai", "Kolkata", "Mumbai", "New Delhi" ], - [ 20_700, "Kathmandu" ], - [ 21_600, "Astana", "Dhaka", "Sri Jayawardenepura", "Almaty", - "Novosibirsk" ], - [ 23_400, "Rangoon" ], - [ 25_200, "Bangkok", "Hanoi", "Jakarta", "Krasnoyarsk" ], - [ 28_800, "Beijing", "Chongqing", "Hong Kong", "Urumqi", - "Kuala Lumpur", "Singapore", "Taipei", "Perth", "Irkutsk", - "Ulaan Bataar" ], - [ 32_400, "Seoul", "Osaka", "Sapporo", "Tokyo", "Yakutsk" ], - [ 34_200, "Darwin", "Adelaide" ], - [ 36_000, "Canberra", "Melbourne", "Sydney", "Brisbane", "Hobart", - "Vladivostok", "Guam", "Port Moresby" ], - [ 39_600, "Magadan", "Solomon Is.", "New Caledonia" ], - [ 43_200, "Fiji", "Kamchatka", "Marshall Is.", "Auckland", - "Wellington" ], - [ 46_800, "Nuku'alofa" ]]. - each do |offset, *places| - places.each { |place| @@zones << create(place, offset).freeze } - end - @@zones.sort! - end - @@zones - end - - # Locate a specific time zone object. If the argument is a string, it - # is interpreted to mean the name of the timezone to locate. If it is a - # numeric value it is either the hour offset, or the second offset, of the - # timezone to find. (The first one with that offset will be returned.) - # Returns +nil+ if no such time zone is known to the system. - def [](arg) - case arg - when String - all.find { |z| z.name == arg } - when Numeric - arg *= 3600 if arg.abs <= 13 - all.find { |z| z.utc_offset == arg.to_i } - else - raise ArgumentError, "invalid argument to TimeZone[]: #{arg.inspect}" - end - end - - # A regular expression that matches the names of all time zones in - # the USA. - US_ZONES = /US|Arizona|Indiana|Hawaii|Alaska/ - - # A convenience method for returning a collection of TimeZone objects - # for time zones in the USA. - def us_zones - all.find_all { |z| z.name =~ US_ZONES } - end - end -end diff --git a/tracks/vendor/rails/activesupport/lib/active_support/version.rb b/tracks/vendor/rails/activesupport/lib/active_support/version.rb deleted file mode 100644 index 6b3cff2e..00000000 --- a/tracks/vendor/rails/activesupport/lib/active_support/version.rb +++ /dev/null @@ -1,9 +0,0 @@ -module ActiveSupport - module VERSION #:nodoc: - MAJOR = 1 - MINOR = 2 - TINY = 5 - - STRING = [MAJOR, MINOR, TINY].join('.') - end -end diff --git a/tracks/vendor/rails/activesupport/lib/active_support/whiny_nil.rb b/tracks/vendor/rails/activesupport/lib/active_support/whiny_nil.rb deleted file mode 100644 index 61cbe98e..00000000 --- a/tracks/vendor/rails/activesupport/lib/active_support/whiny_nil.rb +++ /dev/null @@ -1,38 +0,0 @@ -# Extensions to nil which allow for more helpful error messages for -# people who are new to rails. -# -# The aim is to ensure that when users pass nil to methods where that isn't -# appropriate, instead of NoMethodError and the name of some method used -# by the framework users will see a message explaining what type of object -# was expected. - -class NilClass - WHINERS = [ ::ActiveRecord::Base, ::Array ] - - @@method_class_map = Hash.new - - WHINERS.each do |klass| - methods = klass.public_instance_methods - public_instance_methods - methods.each do |method| - @@method_class_map[method.to_sym] = klass - end - end - - def id - raise RuntimeError, "Called id for nil, which would mistakenly be 4 -- if you really wanted the id of nil, use object_id", caller - end - - private - def method_missing(method, *args, &block) - raise_nil_warning_for @@method_class_map[method], method, caller - end - - def raise_nil_warning_for(klass = nil, selector = nil, with_caller = nil) - message = "You have a nil object when you didn't expect it!" - message << "\nYou might have expected an instance of #{klass}." if klass - message << "\nThe error occured while evaluating nil.#{selector}" if selector - - raise NoMethodError, message, with_caller || caller - end -end - diff --git a/tracks/vendor/rails/railties/CHANGELOG b/tracks/vendor/rails/railties/CHANGELOG deleted file mode 100644 index 9cd6f7d2..00000000 --- a/tracks/vendor/rails/railties/CHANGELOG +++ /dev/null @@ -1,865 +0,0 @@ -*1.0.0* (December 13th, 2005) - -* Update to script.aculo.us 1.5.0 final (equals 1.5.0_rc6) [Thomas Fuchs] - -* Update to Prototype 1.4.0 final [Sam Stephenson] - -* Update instructions on how to find and install generators. #3172. [Chad Fowler] - -* Generator looks in vendor/generators also. [Chad Fowler] - -* Generator copies files in binary mode. #3156 [minimudboy@gmail.com] - - -*0.14.4 (RC5)* (December 7th, 2005) - -* Add builtin/ to the gemspec. Closes #3047. [Nicholas Seckar, Sam Stephenson] - -* Run initialize_logger in script/lighttpd to ensure the log file exists before tailing it. [Sam Stephenson] - -* Make load_fixtures include csv fixtures. #3053. [me@mdaines.com] - -* Fix freeze_gems so that the latest rails version is dumped by default. [Nicholas Seckar] - -* Model generator: correct relative path to test_helper in unit test. [Jeremy Kemper] - -* Make the db_schema_dump task honor the SCHEMA environment variable if present the way db_schema_import does. #2931. [Blair Zajac] - -* Make help for the console command more explicit about how to specify the desired environment in which to run the console. #2911. [anonymous] - -* PostgreSQL: the purge_test_database Rake task shouldn't explicitly specify the template0 template when creating a fresh test database. #2964 [dreamer3@gmail.com] - -* Introducing the session_migration generator. Creates an add_session_table migration. Allows generator to specify migrations directory. #2958, #2960 [Rick Olson] - -* Update to Prototype 1.4.0_rc4. Closes #2943 (old Array.prototype.reverse behavior can be obtained by passing false as an argument). [Sam Stephenson] - -* Eliminate nil from newly generated logfiles. #2927 [Blair Zajac ] - -* Update to Prototype 1.4.0_rc3. Closes #1893, #2505, #2550, #2748, #2783. [Sam Stephenson] - -* Rename Version constant to VERSION. #2802 [Marcel Molina Jr.] - -* Update to latest script.aculo.us version (as of [3031]) - -* SQLite: the clone_structure_to_test and purge_test_database Rake tasks should always use the test environment. #2846 [Rick Olson] - -* Make sure that legacy db tasks also reference :database for SQLite #2830 [kazuhiko@fdiary.net] - -* Pass __FILE__ when evaluating plugins' init.rb. #2817 [james.adam@gmail.com] - -* Better svn status matching for generators. #2814 [François Beausoleil , Blair Zajac ] - -* Don't reload routes until plugins have been loaded so they have a chance to extend the routing capabilities [DHH] - -* Don't detach or fork for script/server tailing [Nicholas Seckar] - -* Changed all script/* to use #!/usr/bin/env ruby instead of hard-coded Ruby path. public/dispatcher.* still uses the hard-coded path for compatibility with web servers that don't have Ruby in path [DHH] - -* Force RAILS_ENV to be "test" when running tests, so that ENV["RAILS_ENV"] = "production" in config/environment.rb doesn't wreck havok [DHH] #2660 - -* Correct versioning in :freeze_gems Rake task. #2778 [jakob@mentalized.net, Jeremy Kemper] - -* Added an omnipresent RailsInfoController with a properties action that delivers an HTML rendering of Rails::Info (but only when local_request? is true). Added a new default index.html which fetches this with Ajax. [Sam Stephenson] - - -*0.14.3 (RC4)* (November 7th, 2005) - -* Add 'add_new_scripts' rake task for adding new rails scripts to script/* [Jamis Buck] - -* Remove bogus hyphen from script/process/reaper calls to 'ps'. #2767 [anonymous] - -* Copy lighttpd.conf when it is first needed, instead of on app creation [Jamis Buck] - -* Use require_library_or_gem 'fcgi' in script/server [Sam Stephenson] - -* Added default lighttpd config in config/lighttpd.conf and added a default runner for lighttpd in script/server (works like script/server, but using lighttpd and FastCGI). It will use lighttpd if available, otherwise WEBrick. You can force either or using 'script/server lighttpd' or 'script/server webrick' [DHH] - -* New configuration option config.plugin_paths which may be a single path like the default 'vendor/plugins' or an array of paths: ['vendor/plugins', 'lib/plugins']. [Jeremy Kemper] - -* Plugins are discovered in nested paths, so you can organize your plugins directory as you like. [Jeremy Kemper] - -* Refactor load_plugin from load_plugins. #2757 [alex.r.moon@gmail.com] - -* Make use of silence_stderr in script/lighttpd, script/plugin, and Rails::Info [Sam Stephenson] - -* Enable HTTP installation of plugins when svn isn't avaialable. Closes #2661. [Chad Fowler] - -* Added script/about to display formatted Rails::Info output [Sam Stephenson] - -* Added Rails::Info to catalog assorted information about a Rails application's environment [Sam Stephenson] - -* Tail the logfile when running script/server lighttpd in the foreground [Sam Stephenson] - -* Try to guess the port number from config/lighttpd.conf in script/server lighttpd [Sam Stephenson] - -* Don't reap spawn-fcgi. #2727 [matthew@walker.wattle.id.au] - -* Reaper knows how to find processes even if the dispatch path is very long. #2711 [matthew@walker.wattle.id.au] - -* Make fcgi handler respond to TERM signals with an explicit exit [Jamis Buck] - -* Added demonstration of fixture use to the test case generated by the model generator [DHH] - -* If specified, pass PostgreSQL client character encoding to createdb. #2703 [Kazuhiko ] - -* Catch CGI multipart parse errors. Wrap dispatcher internals in a failsafe response handler. [Jeremy Kemper] - -* The freeze_gems Rake task accepts the VERSION environment variable to decide which version of Rails to pull into vendor/rails. [Chad Fowler, Jeremy Kemper] - -* Removed script.aculo.us.js, builder.js and slider.js (preperation for move of scriptaculous extensions to plugins, core scriptaculous will remain in Railties) [Thomas Fuchs] - -* The freeze_edge Rake task does smarter svn detection and can export a specific revision by passing the REVISION environment variable. For example: rake freeze_edge REVISION=1234. #2663 [Rick Olson] - -* Comment database.yml and include PostgreSQL and SQLite examples. [Jeremy Kemper] - -* Improve script/plugin on Windows. #2646 [Chad Fowler] - -* The *_plugindoc Rake tasks look deeper into the plugins' lib directories. #2652 [bellis@deepthought.org] - -* The PostgreSQL :db_structure_dump Rake task limits its dump to the schema search path in database.yml. [Anatol Pomozov ] - -* Add task to generate rdoc for all installed plugins. [Marcel Molina] - -* Update script.aculo.us to V1.5_rc4 [Thomas Fuchs] - -* Add default Mac + DarwinPorts MySQL socket locations to the app generator. [Jeremy Kemper] - -* Migrations may be destroyed: script/destroy migration foo. #2635 [Charles M. Gerungan , Jamis Buck, Jeremy Kemper] - -* Added that plugins can carry generators and that generator stub files can be created along with new plugins using script/generate plugin --with-generator [DHH] - -* Removed app/apis as a default empty dir since its automatically created when using script/generate web_service [DHH] - -* Added script/plugin to manage plugins (install, remove, list, etc) [Ryan Tomayko] - -* Added test_plugins task: Run the plugin tests in vendor/plugins/**/test (or specify with PLUGIN=name) [DHH] - -* Added plugin generator to create a stub structure for a new plugin in vendor/plugins (see "script/generate plugin" for help) [DHH] - -* Fixed scaffold generator when started with only 1 parameter #2609 [self@mattmower.com] - -* rake should run functional tests even if the unit tests have failures [Jim Weirich] - -* Back off cleanpath to be symlink friendly. Closes #2533 [Nicholas Seckar] - -* Load rake task files in alphabetical order so you can build dependencies and count on them #2554 [Blair Zajac] - - -*0.14.2 (RC3)* (October 26th, 2005) - -* Constants set in the development/test/production environment file are set in Object - -* Scaffold generator pays attention to the controller name. #2562 [self@mattmower.com] - -* Include tasks from vendor/plugins/*/tasks in the Rakefile #2545 [Rick Olson] - - -*0.14.1 (RC2)* (October 19th, 2005) - -* Don't clean RAILS_ROOT on windows - -* Remove trailing '/' from RAILS_ROOT [Nicholas Seckar] - -* Upgraded to Active Record 1.12.1 and Action Pack 1.10.1 - - -*0.14.0 (RC1)* (October 16th, 2005) - -* Moved generator folder from RAILS_ROOT/generators to RAILS_ROOT/lib/generators [Tobias Luetke] - -* Fix rake dev and related commands [Nicholas Seckar] - -* The rails command tries to deduce your MySQL socket by running `mysql_config ---socket`. If it fails, default to /path/to/your/mysql.sock - -* Made the rails command use the application name for database names in the tailored database.yml file. Example: "rails ~/projects/blog" will use "blog_development" instead of "rails_development". [Florian Weber] - -* Added Rails framework freezing tasks: freeze_gems (freeze to current gems), freeze_edge (freeze to Rails SVN trunk), unfreeze_rails (float with newest gems on system) - -* Added update_javascripts task which will fetch all the latest js files from your current rails install. Use after updating rails. [Tobias Luetke] - -* Added cleaning of RAILS_ROOT to useless elements such as '../non-dot-dot/'. Provides cleaner backtraces and error messages. [Nicholas Seckar] - -* Made the instantiated/transactional fixtures settings be controlled through Rails::Initializer. Transactional and non-instantiated fixtures are default from now on. [Florian Weber] - -* Support using different database adapters for development and test with ActiveRecord::Base.schema_format = :ruby [Sam Stephenson] - -* Make webrick work with session(:off) - -* Add --version, -v option to the Rails command. Closes #1840. [stancell] - -* Update Prototype to V1.4.0_pre11, script.aculo.us to V1.5_rc3 [2504] and fix the rails generator to include the new .js files [Thomas Fuchs] - -* Make the generator skip a file if it already exists and is identical to the new file. - -* Add experimental plugin support #2335 - -* Made Rakefile aware of new .js files in script.aculo.us [Thomas Fuchs] - -* Make table_name and controller_name in generators honor AR::Base.pluralize_table_names. #1216 #2213 [kazuhiko@fdiary.net] - -* Clearly label functional and unit tests in rake stats output. #2297 [lasse.koskela@gmail.com] - -* Make the migration generator only check files ending in *.rb when calculating the next file name #2317 [Chad Fowler] - -* Added prevention of duplicate migrations from the generator #2240 [fbeausoleil@ftml.net] - -* Add db_schema_dump and db_schema_import rake tasks to work with the new ActiveRecord::SchemaDumper (for dumping a schema to and reading a schema from a ruby file). - -* Reformed all the config/environments/* files to conform to the new Rails::Configuration approach. Fully backwards compatible. - -* Added create_sessions_table, drop_sessions_table, and purge_sessions_table as rake tasks for databases that supports migrations (MySQL, PostgreSQL, SQLite) to get a table for use with CGI::Session::ActiveRecordStore - -* Added dump of schema version to the db_structure_dump task for databases that support migrations #1835 [Rick Olson] - -* Fixed script/profiler for Ruby 1.8.2 #1863 [Rick Olson] - -* Fixed clone_structure_to_test task for SQLite #1864 [jon@burningbush.us] - -* Added -m/--mime-types option to the WEBrick server, so you can specify a Apache-style mime.types file to load #2059 [ask@develooper.com] - -* Added -c/--svn option to the generator that'll add new files and remove destroyed files using svn add/revert/remove as appropriate #2064 [kevin.clark@gmail.com] - -* Added -c/--charset option to WEBrick server, so you can specify a default charset (which without changes is UTF-8) #2084 [wejn@box.cz] - -* Make the default stats task extendable by modifying the STATS_DIRECTORIES constant - -* Allow the selected environment to define RAILS_DEFAULT_LOGGER, and have Rails::Initializer use it if it exists. - -* Moved all the shared tasks from Rakefile into Rails, so that the Rakefile is empty and doesn't require updating. - -* Added Rails::Initializer and Rails::Configuration to abstract all of the common setup out of config/environment.rb (uses config/boot.rb to bootstrap the initializer and paths) - -* Fixed the scaffold generator to fail right away if the database isn't accessible instead of in mid-air #1169 [Chad Fowler] - -* Corrected project-local generator location in scripts.rb #2010 [Michael Schuerig] - -* Don't require the environment just to clear the logs #2093 [Scott Barron] - -* Make the default rakefile read *.rake files from config/tasks (for easy extension of the rakefile by e.g. generators) - -* Only load breakpoint in development mode and when BREAKPOINT_SERVER_PORT is defined. - -* Allow the --toggle-spin switch on process/reaper to be negated - -* Replace render_partial with render :partial in scaffold generator [Nicholas Seckar] - -* Added -w flag to ps in process/reaper #1934 [Scott Barron] - -* Allow ERb in the database.yml file (just like with fixtures), so you can pull out the database configuration in environment variables #1822 [Duane Johnson] - -* Added convenience controls for FCGI processes (especially when managed remotely): spinner, spawner, and reaper. They reside in script/process. More details can be had by calling them with -h/--help. - -* Added load_fixtures task to the Rakefile, which will load all the fixtures into the database for the current environment #1791 [Marcel Molina] - -* Added an empty robots.txt to public/, so that web servers asking for it won't trigger a dynamic call, like favicon.ico #1738 [michael@schubert] - -* Dropped the 'immediate close-down' of FCGI processes since it didn't work consistently and produced bad responses when it didn't. So now a TERM ensures exit after the next request (just as if the process is handling a request when it receives the signal). This means that you'll have to 'nudge' all FCGI processes with a request in order to ensure that they have all reloaded. This can be done by something like ./script/process/repear --nudge 'http://www.myapp.com' --instances 10, which will load the myapp site 10 times (and thus hit all of the 10 FCGI processes once, enough to shut down). - - -*0.13.1* (11 July, 2005) - -* Look for app-specific generators in RAILS_ROOT/generators rather than the clunky old RAILS_ROOT/script/generators. Nobody really uses this feature except for the unit tests, so it's a negligible-impact change. If you want to work with third-party generators, drop them in ~/.rails/generators or simply install gems. - -* Fixed that each request with the WEBrick adapter would open a new database connection #1685 [Sam Stephenson] - -* Added support for SQL Server in the database rake tasks #1652 [ken.barker@gmail.com] Note: osql and scptxfr may need to be installed on your development environment. This involves getting the .exes and a .rll (scptxfr) from a production SQL Server (not developer level SQL Server). Add their location to your Environment PATH and you are all set. - -* Added a VERSION parameter to the migrate task that allows you to do "rake migrate VERSION=34" to migrate to the 34th version traveling up or down depending on the current version - -* Extend Ruby version check to include RUBY_RELEASE_DATE >= '2005-12-25', the final Ruby 1.8.2 release #1674 [court3nay@gmail.com] - -* Improved documentation for environment config files #1625 [court3nay@gmail.com] - - -*0.13.0* (6 July, 2005) - -* Changed the default logging level in config/environment.rb to INFO for production (so SQL statements won't be logged) - -* Added migration generator: ./script/generate migration add_system_settings - -* Added "migrate" as rake task to execute all the pending migrations from db/migrate - -* Fixed that model generator would make fixtures plural, even if ActiveRecord::Base.pluralize_table_names was false #1185 [Marcel Molina] - -* Added a DOCTYPE of HTML transitional to the HTML files generated by Rails #1124 [Michael Koziarski] - -* SIGTERM also gracefully exits dispatch.fcgi. Ignore SIGUSR1 on Windows. - -* Add the option to manually manage garbage collection in the FastCGI dispatcher. Set the number of requests between GC runs in your public/dispatch.fcgi [skaes@web.de] - -* Allow dynamic application reloading for dispatch.fcgi processes by sending a SIGHUP. If the process is currently handling a request, the request will be allowed to complete first. This allows production fcgi's to be reloaded without having to restart them. - -* RailsFCGIHandler (dispatch.fcgi) no longer tries to explicitly flush $stdout (CgiProcess#out always calls flush) - -* Fixed rakefile actions against PostgreSQL when the password is all numeric #1462 [michael@schubert.cx] - -* ActionMailer::Base subclasses are reloaded with the other rails components #1262 - -* Made the WEBrick adapter not use a mutex around action performance if ActionController::Base.allow_concurrency is true (default is false) - -* Fixed that mailer generator generated fixtures/plural while units expected fixtures/singular #1457 [Scott Barron] - -* Added a 'whiny nil' that's aim to ensure that when users pass nil to methods where that isn't appropriate, instead of NoMethodError? and the name of some method used by the framework users will see a message explaining what type of object was expected. Only active in test and development environments by default #1209 [Michael Koziarski] - -* Fixed the test_helper.rb to be safe for requiring controllers from multiple spots, like app/controllers/article_controller.rb and app/controllers/admin/article_controller.rb, without reloading the environment twice #1390 [Nicholas Seckar] - -* Fixed Webrick to escape + characters in URL's the same way that lighttpd and apache do #1397 [Nicholas Seckar] - -* Added -e/--environment option to script/runner #1408 [fbeausoleil@ftml.net] - -* Modernize the scaffold generator to use the simplified render and test methods and to change style from @params["id"] to params[:id]. #1367 - -* Added graceful exit from pressing CTRL-C during the run of the rails command #1150 [Caleb Tennis] - -* Allow graceful exits for dispatch.fcgi processes by sending a SIGUSR1. If the process is currently handling a request, the request will be allowed to complete and then will terminate itself. If a request is not being handled, the process is terminated immediately (via #exit). This basically works like restart graceful on Apache. [Jamis Buck] - -* Made dispatch.fcgi more robust by catching fluke errors and retrying unless its a permanent condition. [Jamis Buck] - -* Added console --profile for profiling an IRB session #1154 [Jeremy Kemper] - -* Changed console_sandbox into console --sandbox #1154 [Jeremy Kemper] - - -*0.12.1* (20th April, 2005) - -* Upgraded to Active Record 1.10.1, Action Pack 1.8.1, Action Mailer 0.9.1, Action Web Service 0.7.1 - - -*0.12.0* (19th April, 2005) - -* Fixed that purge_test_database would use database settings from the development environment when recreating the test database #1122 [rails@cogentdude.com] - -* Added script/benchmarker to easily benchmark one or more statement a number of times from within the environment. Examples: - - # runs the one statement 10 times - script/benchmarker 10 'Person.expensive_method(10)' - - # pits the two statements against each other with 50 runs each - script/benchmarker 50 'Person.expensive_method(10)' 'Person.cheap_method(10)' - -* Added script/profiler to easily profile a single statement from within the environment. Examples: - - script/profiler 'Person.expensive_method(10)' - script/profiler 'Person.expensive_method(10)' 10 # runs the statement 10 times - -* Added Rake target clear_logs that'll truncate all the *.log files in log/ to zero #1079 [Lucas Carlson] - -* Added lazy typing for generate, such that ./script/generate cn == ./script/generate controller and the likes #1051 [k@v2studio.com] - -* Fixed that ownership is brought over in pg_dump during tests for PostgreSQL #1060 [pburleson@gmail.com] - -* Upgraded to Active Record 1.10.0, Action Pack 1.8.0, Action Mailer 0.9.0, Action Web Service 0.7.0, Active Support 1.0.4 - - -*0.11.1* (27th March, 2005) - -* Fixed the dispatch.fcgi use of a logger - -* Upgraded to Active Record 1.9.1, Action Pack 1.7.0, Action Mailer 0.8.1, Action Web Service 0.6.2, Active Support 1.0.3 - - -*0.11.0* (22th March, 2005) - -* Removed SCRIPT_NAME from the WEBrick environment to prevent conflicts with PATH_INFO #896 [Nicholas Seckar] - -* Removed ?$1 from the dispatch.f/cgi redirect line to get rid of 'complete/path/from/request.html' => nil being in the @params now that the ENV["REQUEST_URI"] is used to determine the path #895 [dblack/Nicholas Seckar] - -* Added additional error handling to the FastCGI dispatcher to catch even errors taking down the entire process - -* Improved the generated scaffold code a lot to take advantage of recent Rails developments #882 [Tobias Luetke] - -* Combined the script/environment.rb used for gems and regular files version. If vendor/rails/* has all the frameworks, then files version is used, otherwise gems #878 [Nicholas Seckar] - -* Changed .htaccess to allow dispatch.* to be called from a sub-directory as part of the push with Action Pack to make Rails work on non-vhost setups #826 [Nicholas Seckar/Tobias Luetke] - -* Added script/runner which can be used to run code inside the environment by eval'ing the first parameter. Examples: - - ./script/runner 'ReminderService.deliver' - ./script/runner 'Mailer.receive(STDIN.read)' - - This makes it easier to do CRON and postfix scripts without actually making a script just to trigger 1 line of code. - -* Fixed webrick_server cookie handling to allow multiple cookes to be set at once #800, #813 [dave@cherryville.org] - -* Fixed the Rakefile's interaction with postgresql to: - - 1. Use PGPASSWORD and PGHOST in the environment to fix prompting for - passwords when connecting to a remote db and local socket connections. - 2. Add a '-x' flag to pg_dump which stops it dumping privileges #807 [rasputnik] - 3. Quote the user name and use template0 when dumping so the functions doesn't get dumped too #855 [pburleson] - 4. Use the port if available #875 [madrobby] - -* Upgraded to Active Record 1.9.0, Action Pack 1.6.0, Action Mailer 0.8.0, Action Web Service 0.6.1, Active Support 1.0.2 - - -*0.10.1* (7th March, 2005) - -* Fixed rake stats to ignore editor backup files like model.rb~ #791 [skanthak] - -* Added exception shallowing if the DRb server can't be started (not worth making a fuss about to distract new users) #779 [Tobias Luetke] - -* Added an empty favicon.ico file to the public directory of new applications (so the logs are not spammed by its absence) - -* Fixed that scaffold generator new template should use local variable instead of instance variable #778 [Dan Peterson] - -* Allow unit tests to run on a remote server for PostgreSQL #781 [adamm@galacticasoftware.com] - -* Added web_service generator (run ./script/generate web_service for help) #776 [Leon Bredt] - -* Added app/apis and components to code statistics report #729 [Scott Barron] - -* Fixed WEBrick server to use ABSOLUTE_RAILS_ROOT instead of working_directory #687 [Nicholas Seckar] - -* Fixed rails_generator to be usable without RubyGems #686 [Cristi BALAN] - -* Fixed -h/--help for generate and destroy generators #331 - -* Added begin/rescue around the FCGI dispatcher so no uncaught exceptions can bubble up to kill the process (logs to log/fastcgi.crash.log) - -* Fixed that association#count would produce invalid sql when called sequentialy #659 [kanis@comcard.de] - -* Fixed test/mocks/testing to the correct test/mocks/test #740 - -* Added early failure if the Ruby version isn't 1.8.2 or above #735 - -* Removed the obsolete -i/--index option from the WEBrick servlet #743 - -* Upgraded to Active Record 1.8.0, Action Pack 1.5.1, Action Mailer 0.7.1, Action Web Service 0.6.0, Active Support 1.0.1 - - -*0.10.0* (24th February, 2005) - -* Changed default IP binding for WEBrick from 127.0.0.1 to 0.0.0.0 so that the server is accessible both locally and remotely #696 [Marcel] - -* Fixed that script/server -d was broken so daemon mode couldn't be used #687 [Nicholas Seckar] - -* Upgraded to breakpoint 92 which fixes: - - * overload IRB.parse_opts(), fixes #443 - => breakpoints in tests work even when running them via rake - * untaint handlers, might fix an issue discussed on the Rails ML - * added verbose mode to breakpoint_client - * less noise caused by breakpoint_client by default - * ignored TerminateLineInput exception in signal handler - => quiet exit on Ctrl-C - -* Added support for independent components residing in /components. Example: - - Controller: components/list/items_controller.rb - (holds a List::ItemsController class with uses_component_template_root called) - - Model : components/list/item.rb - (namespace is still shared, so an Item model in app/models will take precedence) - - Views : components/list/items/show.rhtml - - -* Added --sandbox option to script/console that'll roll back all changes made to the database when you quit #672 [Jeremy Kemper] - -* Added 'recent' as a rake target that'll run tests for files that changed in the last 10 minutes #612 [Jeremy Kemper] - -* Changed script/console to default to development environment and drop --no-inspect #650 [Jeremy Kemper] - -* Added that the 'fixture :posts' syntax can be used for has_and_belongs_to_many fixtures where a model doesn't exist #572 [Jeremy Kemper] - -* Added that running test_units and test_functional now performs the clone_structure_to_test as well #566 [rasputnik] - -* Added new generator framework that informs about its doings on generation and enables updating and destruction of generated artifacts. See the new script/destroy and script/update for more details #487 [Jeremy Kemper] - -* Added Action Web Service as a new add-on framework for Action Pack [Leon Bredt] - -* Added Active Support as an independent utility and standard library extension bundle - -* Upgraded to Active Record 1.7.0, Action Pack 1.5.0, Action Mailer 0.7.0 - - -*0.9.5* (January 25th, 2005) - -* Fixed dependency reloading by switching to a remove_const approach where all Active Records, Active Record Observers, and Action Controllers are reloading by undefining their classes. This enables you to remove methods in all three types and see the change reflected immediately and it fixes #539. This also means that only those three types of classes will benefit from the const_missing and reloading approach. If you want other classes (like some in lib/) to reload, you must use require_dependency to do it. - -* Added Florian Gross' latest version of Breakpointer and friends that fixes a variaty of bugs #441 [Florian Gross] - -* Fixed skeleton Rakefile to work with sqlite3 out of the box #521 [rasputnik] - -* Fixed that script/breakpointer didn't get the Ruby path rewritten as the other scripts #523 [brandt@kurowski.net] - -* Fixed handling of syntax errors in models that had already been succesfully required once in the current interpreter - -* Fixed that models that weren't referenced in associations weren't being reloaded in the development mode by reinstating the reload - -* Fixed that generate scaffold would produce bad functional tests - -* Fixed that FCGI can also display SyntaxErrors - -* Upgraded to Active Record 1.6.0, Action Pack 1.4.0 - - -*0.9.4.1* (January 18th, 2005) - -* Added 5-second timeout to WordNet alternatives on creating reserved-word models #501 [Marcel Molina] - -* Fixed binding of caller #496 [Alexey] - -* Upgraded to Active Record 1.5.1, Action Pack 1.3.1, Action Mailer 0.6.1 - - -*0.9.4* (January 17th, 2005) - -* Added that ApplicationController will catch a ControllerNotFound exception if someone attempts to access a url pointing to an unexisting controller [Tobias Luetke] - -* Flipped code-to-test ratio around to be more readable #468 [Scott Baron] - -* Fixed log file permissions to be 666 instead of 777 (so they're not executable) #471 [Lucas Carlson] - -* Fixed that auto reloading would some times not work or would reload the models twice #475 [Tobias Luetke] - -* Added rewrite rules to deal with caching to public/.htaccess - -* Added the option to specify a controller name to "generate scaffold" and made the default controller name the plural form of the model. - -* Added that rake clone_structure_to_test, db_structure_dump, and purge_test_database tasks now pick up the source database to use from - RAILS_ENV instead of just forcing development #424 [Tobias Luetke] - -* Fixed script/console to work with Windows (that requires the use of irb.bat) #418 [octopod] - -* Fixed WEBrick servlet slowdown over time by restricting the load path reloading to mod_ruby - -* Removed Fancy Indexing as a default option on the WEBrick servlet as it made it harder to use various caching schemes - -* Upgraded to Active Record 1.5, Action Pack 1.3, Action Mailer 0.6 - - -*0.9.3* (January 4th, 2005) - -* Added support for SQLite in the auto-dumping/importing of schemas for development -> test #416 - -* Added automated rewriting of the shebang lines on installs through the gem rails command #379 [Manfred Stienstra] - -* Added ActionMailer::Base.deliver_method = :test to the test environment so that mail objects are available in ActionMailer::Base.deliveries - for functional testing. - -* Added protection for creating a model through the generators with a name of an existing class, like Thread or Date. - It'll even offer you a synonym using wordnet.princeton.edu as a look-up. No, I'm not kidding :) [Florian Gross] - -* Fixed dependency management to happen in a unified fashion for Active Record and Action Pack using the new Dependencies module. This means that - the environment options needs to change from: - - Before in development.rb: - ActionController::Base.reload_dependencies = true   - ActiveRecord::Base.reload_associations     = true - - Now in development.rb: - Dependencies.mechanism = :load - - Before in production.rb and test.rb: - ActionController::Base.reload_dependencies = false - ActiveRecord::Base.reload_associations     = false - - Now in production.rb and test.rb: - Dependencies.mechanism = :require - -* Fixed problems with dependency caching and controller hierarchies on Ruby 1.8.2 in development mode #351 - -* Fixed that generated action_mailers doesnt need to require the action_mailer since thats already done in the environment #382 [Lucas Carlson] - -* Upgraded to Action Pack 1.2.0 and Active Record 1.4.0 - - -*0.9.2* - -* Fixed CTRL-C exists from the Breakpointer to be a clean affair without error dumping [Kent Sibilev] - -* Fixed "rake stats" to work with sub-directories in models and controllers and to report the code to test ration [Scott Baron] - -* Added that Active Record associations are now reloaded instead of cleared to work with the new const_missing hook in Active Record. - -* Added graceful handling of an inaccessible log file by redirecting output to STDERR with a warning #330 [rainmkr] - -* Added support for a -h/--help parameter in the generator #331 [Ulysses] - -* Fixed that File.expand_path in config/environment.rb would fail when dealing with symlinked public directories [mjobin] - -* Upgraded to Action Pack 1.1.0 and Active Record 1.3.0 - - -*0.9.1* - -* Upgraded to Action Pack 1.0.1 for important bug fix - -* Updated gem dependencies - - -*0.9.0* - -* Renamed public/dispatch.servlet to script/server -- it wasn't really dispatching anyway as its delegating calls to public/dispatch.rb - -* Renamed AbstractApplicationController and abstract_application.rb to ApplicationController and application.rb, so that it will be possible - for the framework to automatically pick up on app/views/layouts/application.rhtml and app/helpers/application.rb - -* Added script/console that makes it even easier to start an IRB session for interacting with the domain model. Run with no-args to - see help. - -* Added breakpoint support through the script/breakpointer client. This means that you can break out of execution at any point in - the code, investigate and change the model, AND then resume execution! Example: - - class WeblogController < ActionController::Base - def index - @posts = Post.find_all - breakpoint "Breaking out from the list" - end - end - - So the controller will accept the action, run the first line, then present you with a IRB prompt in the breakpointer window. - Here you can do things like: - - Executing breakpoint "Breaking out from the list" at .../webrick_server.rb:16 in 'breakpoint' - - >> @posts.inspect - => "[#nil, \"body\"=>nil, \"id\"=>\"1\"}>, - #\"Rails you know!\", \"body\"=>\"Only ten..\", \"id\"=>\"2\"}>]" - >> @posts.first.title = "hello from a breakpoint" - => "hello from a breakpoint" - - ...and even better is that you can examine how your runtime objects actually work: - - >> f = @posts.first - => #nil, "body"=>nil, "id"=>"1"}> - >> f. - Display all 152 possibilities? (y or n) - - Finally, when you're ready to resume execution, you press CTRL-D - -* Changed environments to be configurable through an environment variable. By default, the environment is "development", but you - can change that and set your own by configuring the Apache vhost with a string like (mod_env must be available on the server): - - SetEnv RAILS_ENV production - - ...if you're using WEBrick, you can pick the environment to use with the command-line parameters -e/--environment, like this: - - ruby public/dispatcher.servlet -e production - -* Added a new default environment called "development", which leaves the production environment to be tuned exclusively for that. - -* Added a start_server in the root of the Rails application to make it even easier to get started - -* Fixed public/.htaccess to use RewriteBase and share the same rewrite rules for all the dispatch methods - -* Fixed webrick_server to handle requests in a serialized manner (the Rails reloading infrastructure is not thread-safe) - -* Added support for controllers in directories. So you can have: - - app/controllers/account_controller.rb # URL: /account/ - app/controllers/admin/account_controller.rb # URL: /admin/account/ - - NOTE: You need to update your public/.htaccess with the new rules to pick it up - -* Added reloading for associations and dependencies under cached environments like FastCGI and mod_ruby. This makes it possible to use - those environments for development. This is turned on by default, but can be turned off with - ActiveRecord::Base.reload_associations = false and ActionController::Base.reload_dependencies = false in production environments. - -* Added support for sub-directories in app/models. So now you can have something like Basecamp with: - - app/models/accounting - app/models/project - app/models/participants - app/models/settings - - It's poor man's namespacing, but only for file-system organization. You still require files just like before. - Nothing changes inside the files themselves. - - -* Fixed a few references in the tests generated by new_mailer [Jeremy Kemper] - -* Added support for mocks in testing with test/mocks - -* Cleaned up the environments a bit and added global constant RAILS_ROOT - - -*0.8.5* (9) - -* Made dev-util available to all tests, so you can insert breakpoints in any test case to get an IRB prompt at that point [Jeremy Kemper]: - - def test_complex_stuff - @david.projects << @new_project - breakpoint "Let's have a closer look at @david" - end - - You need to install dev-utils yourself for this to work ("gem install dev-util"). - -* Added shared generator behavior so future upgrades should be possible without manually copying over files [Jeremy Kemper] - -* Added the new helper style to both controller and helper templates [Jeremy Kemper] - -* Added new_crud generator for creating a model and controller at the same time with explicit scaffolding [Jeremy Kemper] - -* Added configuration of Test::Unit::TestCase.fixture_path to test_helper to concide with the new AR fixtures style - -* Fixed that new_model was generating singular table/fixture names - -* Upgraded to Action Mailer 0.4.0 - -* Upgraded to Action Pack 0.9.5 - -* Upgraded to Active Record 1.1.0 - - -*0.8.0 (15)* - -* Removed custom_table_name option for new_model now that the Inflector is as powerful as it is - -* Changed the default rake action to just do testing and separate API generation and coding statistics into a "doc" task. - -* Fixed WEBrick dispatcher to handle missing slashes in the URLs gracefully [alexey] - -* Added user option for all postgresql tool calls in the rakefile [elvstone] - -* Fixed problem with running "ruby public/dispatch.servlet" instead of "cd public; ruby dispatch.servlet" [alexey] - -* Fixed WEBrick server so that it no longer hardcodes the ruby interpreter used to "ruby" but will get the one used based - on the Ruby runtime configuration. [Marcel Molina Jr.] - -* Fixed Dispatcher so it'll route requests to magic_beans to MagicBeansController/magic_beans_controller.rb [Caio Chassot] - -* "new_controller MagicBeans" and "new_model SubscriptionPayments" will now both behave properly as they use the new Inflector. - -* Fixed problem with MySQL foreign key constraint checks in Rake :clone_production_structure_to_test target [Andreas Schwarz] - -* Changed WEBrick server to by default be auto-reloading, which is slower but makes source changes instant. - Class compilation cache can be turned on with "-c" or "--cache-classes". - -* Added "-b/--binding" option to WEBrick dispatcher to bind the server to a specific IP address (default: 127.0.0.1) [Kevin Temp] - -* dispatch.fcgi now DOESN'T set FCGI_PURE_RUBY as it was slowing things down for now reason [Andreas Schwarz] - -* Added new_mailer generator to work with Action Mailer - -* Included new framework: Action Mailer 0.3 - -* Upgraded to Action Pack 0.9.0 - -* Upgraded to Active Record 1.0.0 - - -*0.7.0* - -* Added an optional second argument to the new_model script that allows the programmer to specify the table name, - which will used to generate a custom table_name method in the model and will also be used in the creation of fixtures. - [Kevin Radloff] - -* script/new_model now turns AccountHolder into account_holder instead of accountholder [Kevin Radloff] - -* Fixed the faulty handleing of static files with WEBrick [Andreas Schwarz] - -* Unified function_test_helper and unit_test_helper into test_helper - -* Fixed bug with the automated production => test database dropping on PostgreSQL [dhawkins] - -* create_fixtures in both the functional and unit test helper now turns off the log during fixture generation - and can generate more than one fixture at a time. Which makes it possible for assignments like: - - @people, @projects, @project_access, @companies, @accounts = - create_fixtures "people", "projects", "project_access", "companies", "accounts" - -* Upgraded to Action Pack 0.8.5 (locally-scoped variables, partials, advanced send_file) - -* Upgraded to Active Record 0.9.5 (better table_name guessing, cloning, find_all_in_collection) - - -*0.6.5* - -* No longer specifies a template for rdoc, so it'll use whatever is default (you can change it in the rakefile) - -* The new_model generator will now use the same rules for plural wordings as Active Record - (so Category will give categories, not categorys) [Kevin Radloff] - -* dispatch.fcgi now sets FCGI_PURE_RUBY to true to ensure that it's the Ruby version that's loaded [danp] - -* Made the GEM work with Windows - -* Fixed bug where mod_ruby would "forget" the load paths added when switching between controllers - -* PostgreSQL are now supported for the automated production => test database dropping [Kevin Radloff] - -* Errors thrown by the dispatcher are now properly handled in FCGI. - -* Upgraded to Action Pack 0.8.0 (lots and lots and lots of fixes) - -* Upgraded to Active Record 0.9.4 (a bunch of fixes) - - -*0.6.0* - -* Added AbstractionApplicationController as a superclass for all controllers generated. This class can be used - to carry filters and methods that are to be shared by all. It has an accompanying ApplicationHelper that all - controllers will also automatically have available. - -* Added environments that can be included from any script to get the full Active Record and Action Controller - context running. This can be used by maintenance scripts or to interact with the model through IRB. Example: - - require 'config/environments/production' - - for account in Account.find_all - account.recalculate_interests - end - - A short migration script for an account model that had it's interest calculation strategy changed. - -* Accessing the index of a controller with "/weblog" will now redirect to "/weblog/" (only on Apache, not WEBrick) - -* Simplified the default Apache config so even remote requests are served off CGI as a default. - You'll now have to do something specific to activate mod_ruby and FCGI (like using the force urls). - This should make it easier for new comers that start on an external server. - -* Added more of the necessary Apache options to .htaccess to make it easier to setup - -* Upgraded to Action Pack 0.7.9 (lots of fixes) - -* Upgraded to Active Record 0.9.3 (lots of fixes) - - -*0.5.7* - -* Fixed bug in the WEBrick dispatcher that prevented it from getting parameters from the URL - (through GET requests or otherwise) - -* Added lib in root as a place to store app specific libraries - -* Added lib and vendor to load_path, so anything store within can be loaded directly. - Hence lib/redcloth.rb can be loaded with require "redcloth" - -* Upgraded to Action Pack 0.7.8 (lots of fixes) - -* Upgraded to Active Record 0.9.2 (minor upgrade) - - -*0.5.6* - -* Upgraded to Action Pack 0.7.7 (multipart form fix) - -* Updated the generated template stubs to valid XHTML files - -* Ensure that controllers generated are capitalized, so "new_controller TodoLists" - gives the same as "new_controller Todolists" and "new_controller todolists". - - -*0.5.5* - -* Works on Windows out of the box! (Dropped symlinks) - -* Added webrick dispatcher: Try "ruby public/dispatch.servlet --help" [Florian Gross] - -* Report errors about initialization to browser (instead of attempting to use uninitialized logger) - -* Upgraded to Action Pack 0.7.6 - -* Upgraded to Active Record 0.9.1 - -* Added distinct 500.html instead of reusing 404.html - -* Added MIT license - - -*0.5.0* - -* First public release diff --git a/tracks/vendor/rails/railties/MIT-LICENSE b/tracks/vendor/rails/railties/MIT-LICENSE deleted file mode 100644 index 5919c288..00000000 --- a/tracks/vendor/rails/railties/MIT-LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -Copyright (c) 2004 David Heinemeier Hansson - -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. \ No newline at end of file diff --git a/tracks/vendor/rails/railties/README b/tracks/vendor/rails/railties/README deleted file mode 100644 index cd9d0ffe..00000000 --- a/tracks/vendor/rails/railties/README +++ /dev/null @@ -1,153 +0,0 @@ -== Welcome to Rails - -Rails is a web-application and persistence framework that includes everything -needed to create database-backed web-applications according to the -Model-View-Control pattern of separation. This pattern splits the view (also -called the presentation) into "dumb" templates that are primarily responsible -for inserting pre-built data in between HTML tags. The model contains the -"smart" domain objects (such as Account, Product, Person, Post) that holds all -the business logic and knows how to persist themselves to a database. The -controller handles the incoming requests (such as Save New Account, Update -Product, Show Post) by manipulating the model and directing data to the view. - -In Rails, the model is handled by what's called an object-relational mapping -layer entitled Active Record. This layer allows you to present the data from -database rows as objects and embellish these data objects with business logic -methods. You can read more about Active Record in -link:files/vendor/rails/activerecord/README.html. - -The controller and view are handled by the Action Pack, which handles both -layers by its two parts: Action View and Action Controller. These two layers -are bundled in a single package due to their heavy interdependence. This is -unlike the relationship between the Active Record and Action Pack that is much -more separate. Each of these packages can be used independently outside of -Rails. You can read more about Action Pack in -link:files/vendor/rails/actionpack/README.html. - - -== Getting started - -1. Run the WEBrick servlet: ruby script/server (run with --help for options) - ...or if you have lighttpd installed: ruby script/lighttpd (it's faster) -2. Go to http://localhost:3000/ and get "Congratulations, you've put Ruby on Rails!" -3. Follow the guidelines on the "Congratulations, you've put Ruby on Rails!" screen - - -== Example for Apache conf - - - ServerName rails - DocumentRoot /path/application/public/ - ErrorLog /path/application/log/server.log - - - Options ExecCGI FollowSymLinks - AllowOverride all - Allow from all - Order allow,deny - - - -NOTE: Be sure that CGIs can be executed in that directory as well. So ExecCGI -should be on and ".cgi" should respond. All requests from 127.0.0.1 go -through CGI, so no Apache restart is necessary for changes. All other requests -go through FCGI (or mod_ruby), which requires a restart to show changes. - - -== Debugging Rails - -Have "tail -f" commands running on both the server.log, production.log, and -test.log files. Rails will automatically display debugging and runtime -information to these files. Debugging info will also be shown in the browser -on requests from 127.0.0.1. - - -== Breakpoints - -Breakpoint support is available through the script/breakpointer client. This -means that you can break out of execution at any point in the code, investigate -and change the model, AND then resume execution! Example: - - class WeblogController < ActionController::Base - def index - @posts = Post.find_all - breakpoint "Breaking out from the list" - end - end - -So the controller will accept the action, run the first line, then present you -with a IRB prompt in the breakpointer window. Here you can do things like: - -Executing breakpoint "Breaking out from the list" at .../webrick_server.rb:16 in 'breakpoint' - - >> @posts.inspect - => "[#nil, \"body\"=>nil, \"id\"=>\"1\"}>, - #\"Rails you know!\", \"body\"=>\"Only ten..\", \"id\"=>\"2\"}>]" - >> @posts.first.title = "hello from a breakpoint" - => "hello from a breakpoint" - -...and even better is that you can examine how your runtime objects actually work: - - >> f = @posts.first - => #nil, "body"=>nil, "id"=>"1"}> - >> f. - Display all 152 possibilities? (y or n) - -Finally, when you're ready to resume execution, you press CTRL-D - - -== Console - -You can interact with the domain model by starting the console through script/console. -Here you'll have all parts of the application configured, just like it is when the -application is running. You can inspect domain models, change values, and save to the -database. Starting the script without arguments will launch it in the development environment. -Passing an argument will specify a different environment, like console production. - - -== Description of contents - -app - Holds all the code that's specific to this particular application. - -app/controllers - Holds controllers that should be named like weblog_controller.rb for - automated URL mapping. All controllers should descend from - ActionController::Base. - -app/models - Holds models that should be named like post.rb. - Most models will descend from ActiveRecord::Base. - -app/views - Holds the template files for the view that should be named like - weblog/index.rhtml for the WeblogController#index action. All views use eRuby - syntax. This directory can also be used to keep stylesheets, images, and so on - that can be symlinked to public. - -app/helpers - Holds view helpers that should be named like weblog_helper.rb. - -config - Configuration files for the Rails environment, the routing map, the database, and other dependencies. - -components - Self-contained mini-applications that can bundle together controllers, models, and views. - -lib - Application specific libraries. Basically, any kind of custom code that doesn't - belong under controllers, models, or helpers. This directory is in the load path. - -public - The directory available for the web server. Contains subdirectories for images, stylesheets, - and javascripts. Also contains the dispatchers and the default HTML files. - -script - Helper scripts for automation and generation. - -test - Unit and functional tests along with fixtures. - -vendor - External libraries that the application depends on. Also includes the plugins subdirectory. - This directory is in the load path. diff --git a/tracks/vendor/rails/railties/Rakefile b/tracks/vendor/rails/railties/Rakefile deleted file mode 100644 index 446a4456..00000000 --- a/tracks/vendor/rails/railties/Rakefile +++ /dev/null @@ -1,422 +0,0 @@ -require 'rake' -require 'rake/testtask' -require 'rake/rdoctask' -require 'rake/gempackagetask' -require 'rake/contrib/rubyforgepublisher' - -require 'date' -require 'rbconfig' - -require File.join(File.dirname(__FILE__), 'lib', 'rails_version') - -PKG_BUILD = ENV['PKG_BUILD'] ? '.' + ENV['PKG_BUILD'] : '' -PKG_NAME = 'rails' -PKG_VERSION = Rails::VERSION::STRING + PKG_BUILD -PKG_FILE_NAME = "#{PKG_NAME}-#{PKG_VERSION}" -PKG_DESTINATION = ENV["RAILS_PKG_DESTINATION"] || "../#{PKG_NAME}" - -RELEASE_NAME = "REL #{PKG_VERSION}" - -RUBY_FORGE_PROJECT = "rails" -RUBY_FORGE_USER = "webster132" - - -# Rake::TestTask.new("test") do |t| -# t.libs << 'test' -# t.pattern = 'test/*_test.rb' -# t.verbose = true -# end - - -BASE_DIRS = %w( app config/environments components db doc log lib lib/tasks public script script/performance script/process test vendor vendor/plugins ) -APP_DIRS = %w( models controllers helpers views views/layouts ) -PUBLIC_DIRS = %w( images javascripts stylesheets ) -TEST_DIRS = %w( fixtures unit functional mocks mocks/development mocks/test ) - -LOG_FILES = %w( server.log development.log test.log production.log ) -HTML_FILES = %w( 404.html 500.html index.html robots.txt favicon.ico images/rails.png - javascripts/prototype.js - javascripts/effects.js javascripts/dragdrop.js javascripts/controls.js ) -BIN_FILES = %w( about breakpointer console destroy generate performance/benchmarker performance/profiler process/reaper process/spawner process/spinner runner server plugin ) - -VENDOR_LIBS = %w( actionpack activerecord actionmailer activesupport actionwebservice railties ) - - -desc "Generates a fresh Rails package with documentation" -task :fresh_rails => [ :clean, :make_dir_structure, :initialize_file_stubs, :copy_vendor_libraries, :copy_ties_content, :generate_documentation ] - -desc "Generates a fresh Rails package using GEMs with documentation" -task :fresh_gem_rails => [ :clean, :make_dir_structure, :initialize_file_stubs, :copy_ties_content, :copy_gem_environment ] - -desc "Generates a fresh Rails package without documentation (faster)" -task :fresh_rails_without_docs => [ :clean, :make_dir_structure, :initialize_file_stubs, :copy_vendor_libraries, :copy_ties_content ] - -desc "Generates a fresh Rails package without documentation (faster)" -task :fresh_rails_without_docs_using_links => [ :clean, :make_dir_structure, :initialize_file_stubs, :link_vendor_libraries, :copy_ties_content ] - -desc "Generates minimal Rails package using symlinks" -task :dev => [ :clean, :make_dir_structure, :initialize_file_stubs, :link_vendor_libraries, :copy_ties_content ] - -desc "Packages the fresh Rails package with documentation" -task :package => [ :clean, :fresh_rails ] do - system %{cd ..; tar -czvf #{PKG_NAME}-#{PKG_VERSION}.tgz #{PKG_NAME}} - system %{cd ..; zip -r #{PKG_NAME}-#{PKG_VERSION}.zip #{PKG_NAME}} -end - -task :clean do - rm_rf PKG_DESTINATION -end - -# Get external spinoffs ------------------------------------------------------------------- - -desc "Updates railties to the latest version of the javascript spinoffs" -task :update_js do - for js in %w( prototype controls dragdrop effects slider ) - rm "html/javascripts/#{js}.js" - cp "./../actionpack/lib/action_view/helpers/javascripts/#{js}.js", "html/javascripts" - end -end - -# Make directory structure ---------------------------------------------------------------- - -def make_dest_dirs(dirs, path = nil) - mkdir_p dirs.map { |dir| File.join(PKG_DESTINATION, path, dir) } -end - -desc "Make the directory structure for the new Rails application" -task :make_dir_structure => [ :make_base_dirs, :make_app_dirs, :make_public_dirs, :make_test_dirs ] - -task(:make_base_dirs) { make_dest_dirs BASE_DIRS } -task(:make_app_dirs) { make_dest_dirs APP_DIRS, 'app' } -task(:make_public_dirs) { make_dest_dirs PUBLIC_DIRS, 'public' } -task(:make_test_dirs) { make_dest_dirs TEST_DIRS, 'test' } - - -# Initialize file stubs ------------------------------------------------------------------- - -desc "Initialize empty file stubs (such as for logging)" -task :initialize_file_stubs => [ :initialize_log_files ] - -task :initialize_log_files do - log_dir = File.join(PKG_DESTINATION, 'log') - chmod 0777, log_dir - LOG_FILES.each do |log_file| - log_path = File.join(log_dir, log_file) - touch log_path - chmod 0666, log_path - end -end - - -# Copy Vendors ---------------------------------------------------------------------------- - -desc "Copy in all the Rails packages to vendor" -task :copy_vendor_libraries do - mkdir File.join(PKG_DESTINATION, 'vendor', 'rails') - VENDOR_LIBS.each { |dir| cp_r File.join('..', dir), File.join(PKG_DESTINATION, 'vendor', 'rails', dir) } -end - -desc "Link in all the Rails packages to vendor" -task :link_vendor_libraries do - mkdir File.join(PKG_DESTINATION, 'vendor', 'rails') - VENDOR_LIBS.each { |dir| ln_s File.join('..', '..', '..', dir), File.join(PKG_DESTINATION, 'vendor', 'rails', dir) } -end - - -# Copy Ties Content ----------------------------------------------------------------------- - -# :link_apache_config -desc "Make copies of all the default content of ties" -task :copy_ties_content => [ - :copy_rootfiles, :copy_dispatches, :copy_html_files, :copy_application, - :copy_configs, :copy_binfiles, :copy_test_helpers, :copy_app_doc_readme ] - -task :copy_dispatches do - copy_with_rewritten_ruby_path("dispatches/dispatch.rb", "#{PKG_DESTINATION}/public/dispatch.rb") - chmod 0755, "#{PKG_DESTINATION}/public/dispatch.rb" - - copy_with_rewritten_ruby_path("dispatches/dispatch.rb", "#{PKG_DESTINATION}/public/dispatch.cgi") - chmod 0755, "#{PKG_DESTINATION}/public/dispatch.cgi" - - copy_with_rewritten_ruby_path("dispatches/dispatch.fcgi", "#{PKG_DESTINATION}/public/dispatch.fcgi") - chmod 0755, "#{PKG_DESTINATION}/public/dispatch.fcgi" - - # copy_with_rewritten_ruby_path("dispatches/gateway.cgi", "#{PKG_DESTINATION}/public/gateway.cgi") - # chmod 0755, "#{PKG_DESTINATION}/public/gateway.cgi" -end - -task :copy_html_files do - HTML_FILES.each { |file| cp File.join('html', file), File.join(PKG_DESTINATION, 'public', file) } -end - -task :copy_application do - cp "helpers/application.rb", "#{PKG_DESTINATION}/app/controllers/application.rb" - cp "helpers/application_helper.rb", "#{PKG_DESTINATION}/app/helpers/application_helper.rb" -end - -task :copy_configs do - app_name = "rails" - socket = nil - require 'erb' - File.open("#{PKG_DESTINATION}/config/database.yml", 'w') {|f| f.write ERB.new(IO.read("configs/database.yml"), nil, '-').result(binding)} - - cp "configs/routes.rb", "#{PKG_DESTINATION}/config/routes.rb" - - cp "configs/apache.conf", "#{PKG_DESTINATION}/public/.htaccess" - - cp "environments/boot.rb", "#{PKG_DESTINATION}/config/boot.rb" - cp "environments/environment.rb", "#{PKG_DESTINATION}/config/environment.rb" - cp "environments/production.rb", "#{PKG_DESTINATION}/config/environments/production.rb" - cp "environments/development.rb", "#{PKG_DESTINATION}/config/environments/development.rb" - cp "environments/test.rb", "#{PKG_DESTINATION}/config/environments/test.rb" -end - -task :copy_binfiles do - BIN_FILES.each do |file| - dest_file = File.join(PKG_DESTINATION, 'script', file) - copy_with_rewritten_ruby_path(File.join('bin', file), dest_file) - chmod 0755, dest_file - end -end - -task :copy_rootfiles do - cp "fresh_rakefile", "#{PKG_DESTINATION}/Rakefile" - cp "README", "#{PKG_DESTINATION}/README" - cp "CHANGELOG", "#{PKG_DESTINATION}/CHANGELOG" -end - -task :copy_test_helpers do - cp "helpers/test_helper.rb", "#{PKG_DESTINATION}/test/test_helper.rb" -end - -task :copy_app_doc_readme do - cp "doc/README_FOR_APP", "#{PKG_DESTINATION}/doc/README_FOR_APP" -end - -task :link_apache_config do - chdir(File.join(PKG_DESTINATION, 'config')) { - ln_s "../public/.htaccess", "apache.conf" - } -end - -def copy_with_rewritten_ruby_path(src_file, dest_file) - ruby = File.join(Config::CONFIG['bindir'], Config::CONFIG['ruby_install_name']) - - File.open(dest_file, 'w') do |df| - File.open(src_file) do |sf| - line = sf.gets - if (line =~ /#!.+ruby\s*/) != nil - df.puts("#!#{ruby}") - else - df.puts(line) - end - df.write(sf.read) - end - end -end - - -# Generate documentation ------------------------------------------------------------------ - -desc "Generate documentation for the framework and for the empty application" -task :generate_documentation => [ :generate_app_doc, :generate_rails_framework_doc ] - -task :generate_rails_framework_doc do - system %{cd #{PKG_DESTINATION}; rake apidoc} -end - -task :generate_app_doc do - File.cp "doc/README_FOR_APP", "#{PKG_DESTINATION}/doc/README_FOR_APP" - system %{cd #{PKG_DESTINATION}; rake appdoc} -end - -Rake::RDocTask.new { |rdoc| - rdoc.rdoc_dir = 'doc' - rdoc.title = "Railties -- Gluing the Engine to the Rails" - rdoc.options << '--line-numbers --inline-source --accessor cattr_accessor=object' - rdoc.template = "#{ENV['template']}.rb" if ENV['template'] - rdoc.rdoc_files.include('README', 'CHANGELOG') - rdoc.rdoc_files.include('lib/*.rb') - rdoc.rdoc_files.include('lib/rails_generator/*.rb') - rdoc.rdoc_files.include('lib/commands/**/*.rb') -} - -# Generate GEM ---------------------------------------------------------------------------- - -task :copy_gem_environment do - cp "environments/environment.rb", "#{PKG_DESTINATION}/config/environment.rb" - chmod 0755, dest_file -end - - -PKG_FILES = FileList[ - '[a-zA-Z]*', - 'bin/**/*', - 'builtin/**/*', - 'configs/**/*', - 'doc/**/*', - 'dispatches/**/*', - 'environments/**/*', - 'helpers/**/*', - 'generators/**/*', - 'html/**/*', - 'lib/**/*' -] - -spec = Gem::Specification.new do |s| - s.name = 'rails' - s.version = PKG_VERSION - s.summary = "Web-application framework with template engine, control-flow layer, and ORM." - s.description = <<-EOF - Rails is a framework for building web-application using CGI, FCGI, mod_ruby, or WEBrick - on top of either MySQL, PostgreSQL, SQLite, DB2, SQL Server, or Oracle with eRuby- or Builder-based templates. - EOF - - s.add_dependency('rake', '>= 0.6.2') - s.add_dependency('activesupport', '= 1.2.5' + PKG_BUILD) - s.add_dependency('activerecord', '= 1.13.2' + PKG_BUILD) - s.add_dependency('actionpack', '= 1.11.2' + PKG_BUILD) - s.add_dependency('actionmailer', '= 1.1.5' + PKG_BUILD) - s.add_dependency('actionwebservice', '= 1.0.0' + PKG_BUILD) - - s.rdoc_options << '--exclude' << '.' - s.has_rdoc = false - - s.files = PKG_FILES.to_a.delete_if {|f| f.include?('.svn')} - s.require_path = 'lib' - - s.bindir = "bin" # Use these for applications. - s.executables = ["rails"] - s.default_executable = "rails" - - s.author = "David Heinemeier Hansson" - s.email = "david@loudthinking.com" - s.homepage = "http://www.rubyonrails.org" - s.rubyforge_project = "rails" -end - -Rake::GemPackageTask.new(spec) do |pkg| -end - - -# Publishing ------------------------------------------------------- -desc "Publish the API documentation" -task :pgem => [:gem] do - Rake::SshFilePublisher.new("davidhh@wrath.rubyonrails.org", "public_html/gems/gems", "pkg", "#{PKG_FILE_NAME}.gem").upload - `ssh davidhh@wrath.rubyonrails.org './gemupdate.sh'` -end - -desc "Publish the release files to RubyForge." -task :release => [:gem] do - files = ["gem"].map { |ext| "pkg/#{PKG_FILE_NAME}.#{ext}" } - - if RUBY_FORGE_PROJECT then - require 'net/http' - require 'open-uri' - - project_uri = "http://rubyforge.org/projects/#{RUBY_FORGE_PROJECT}/" - project_data = open(project_uri) { |data| data.read } - group_id = project_data[/[?&]group_id=(\d+)/, 1] - raise "Couldn't get group id" unless group_id - - # This echos password to shell which is a bit sucky - if ENV["RUBY_FORGE_PASSWORD"] - password = ENV["RUBY_FORGE_PASSWORD"] - else - print "#{RUBY_FORGE_USER}@rubyforge.org's password: " - password = STDIN.gets.chomp - end - - login_response = Net::HTTP.start("rubyforge.org", 80) do |http| - data = [ - "login=1", - "form_loginname=#{RUBY_FORGE_USER}", - "form_pw=#{password}" - ].join("&") - http.post("/account/login.php", data) - end - - cookie = login_response["set-cookie"] - raise "Login failed" unless cookie - headers = { "Cookie" => cookie } - - release_uri = "http://rubyforge.org/frs/admin/?group_id=#{group_id}" - release_data = open(release_uri, headers) { |data| data.read } - package_id = release_data[/[?&]package_id=(\d+)/, 1] - raise "Couldn't get package id" unless package_id - - first_file = true - release_id = "" - - files.each do |filename| - basename = File.basename(filename) - file_ext = File.extname(filename) - file_data = File.open(filename, "rb") { |file| file.read } - - puts "Releasing #{basename}..." - - release_response = Net::HTTP.start("rubyforge.org", 80) do |http| - release_date = Time.now.strftime("%Y-%m-%d %H:%M") - type_map = { - ".zip" => "3000", - ".tgz" => "3110", - ".gz" => "3110", - ".gem" => "1400" - }; type_map.default = "9999" - type = type_map[file_ext] - boundary = "rubyqMY6QN9bp6e4kS21H4y0zxcvoor" - - query_hash = if first_file then - { - "group_id" => group_id, - "package_id" => package_id, - "release_name" => RELEASE_NAME, - "release_date" => release_date, - "type_id" => type, - "processor_id" => "8000", # Any - "release_notes" => "", - "release_changes" => "", - "preformatted" => "1", - "submit" => "1" - } - else - { - "group_id" => group_id, - "release_id" => release_id, - "package_id" => package_id, - "step2" => "1", - "type_id" => type, - "processor_id" => "8000", # Any - "submit" => "Add This File" - } - end - - query = "?" + query_hash.map do |(name, value)| - [name, URI.encode(value)].join("=") - end.join("&") - - data = [ - "--" + boundary, - "Content-Disposition: form-data; name=\"userfile\"; filename=\"#{basename}\"", - "Content-Type: application/octet-stream", - "Content-Transfer-Encoding: binary", - "", file_data, "" - ].join("\x0D\x0A") - - release_headers = headers.merge( - "Content-Type" => "multipart/form-data; boundary=#{boundary}" - ) - - target = first_file ? "/frs/admin/qrs.php" : "/frs/admin/editrelease.php" - http.post(target + query, data, release_headers) - end - - if first_file then - release_id = release_response.body[/release_id=(\d+)/, 1] - raise("Couldn't get release id") unless release_id - end - - first_file = false - end - end -end diff --git a/tracks/vendor/rails/railties/bin/about b/tracks/vendor/rails/railties/bin/about deleted file mode 100644 index 7b07d46a..00000000 --- a/tracks/vendor/rails/railties/bin/about +++ /dev/null @@ -1,3 +0,0 @@ -#!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../config/boot' -require 'commands/about' \ No newline at end of file diff --git a/tracks/vendor/rails/railties/bin/breakpointer b/tracks/vendor/rails/railties/bin/breakpointer deleted file mode 100644 index 64af76ed..00000000 --- a/tracks/vendor/rails/railties/bin/breakpointer +++ /dev/null @@ -1,3 +0,0 @@ -#!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../config/boot' -require 'commands/breakpointer' \ No newline at end of file diff --git a/tracks/vendor/rails/railties/bin/console b/tracks/vendor/rails/railties/bin/console deleted file mode 100644 index 42f28f7d..00000000 --- a/tracks/vendor/rails/railties/bin/console +++ /dev/null @@ -1,3 +0,0 @@ -#!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../config/boot' -require 'commands/console' \ No newline at end of file diff --git a/tracks/vendor/rails/railties/bin/destroy b/tracks/vendor/rails/railties/bin/destroy deleted file mode 100644 index fa0e6fcd..00000000 --- a/tracks/vendor/rails/railties/bin/destroy +++ /dev/null @@ -1,3 +0,0 @@ -#!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../config/boot' -require 'commands/destroy' \ No newline at end of file diff --git a/tracks/vendor/rails/railties/bin/generate b/tracks/vendor/rails/railties/bin/generate deleted file mode 100644 index ef976e09..00000000 --- a/tracks/vendor/rails/railties/bin/generate +++ /dev/null @@ -1,3 +0,0 @@ -#!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../config/boot' -require 'commands/generate' \ No newline at end of file diff --git a/tracks/vendor/rails/railties/bin/performance/benchmarker b/tracks/vendor/rails/railties/bin/performance/benchmarker deleted file mode 100644 index c842d35d..00000000 --- a/tracks/vendor/rails/railties/bin/performance/benchmarker +++ /dev/null @@ -1,3 +0,0 @@ -#!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../config/boot' -require 'commands/performance/benchmarker' diff --git a/tracks/vendor/rails/railties/bin/performance/profiler b/tracks/vendor/rails/railties/bin/performance/profiler deleted file mode 100644 index d855ac8b..00000000 --- a/tracks/vendor/rails/railties/bin/performance/profiler +++ /dev/null @@ -1,3 +0,0 @@ -#!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../config/boot' -require 'commands/performance/profiler' diff --git a/tracks/vendor/rails/railties/bin/plugin b/tracks/vendor/rails/railties/bin/plugin deleted file mode 100644 index 26ca64c0..00000000 --- a/tracks/vendor/rails/railties/bin/plugin +++ /dev/null @@ -1,3 +0,0 @@ -#!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../config/boot' -require 'commands/plugin' \ No newline at end of file diff --git a/tracks/vendor/rails/railties/bin/process/reaper b/tracks/vendor/rails/railties/bin/process/reaper deleted file mode 100644 index c77f0453..00000000 --- a/tracks/vendor/rails/railties/bin/process/reaper +++ /dev/null @@ -1,3 +0,0 @@ -#!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../config/boot' -require 'commands/process/reaper' diff --git a/tracks/vendor/rails/railties/bin/process/spawner b/tracks/vendor/rails/railties/bin/process/spawner deleted file mode 100644 index 7118f398..00000000 --- a/tracks/vendor/rails/railties/bin/process/spawner +++ /dev/null @@ -1,3 +0,0 @@ -#!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../config/boot' -require 'commands/process/spawner' diff --git a/tracks/vendor/rails/railties/bin/process/spinner b/tracks/vendor/rails/railties/bin/process/spinner deleted file mode 100644 index 6816b32e..00000000 --- a/tracks/vendor/rails/railties/bin/process/spinner +++ /dev/null @@ -1,3 +0,0 @@ -#!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../../config/boot' -require 'commands/process/spinner' diff --git a/tracks/vendor/rails/railties/bin/rails b/tracks/vendor/rails/railties/bin/rails deleted file mode 100644 index 54417750..00000000 --- a/tracks/vendor/rails/railties/bin/rails +++ /dev/null @@ -1,21 +0,0 @@ -min_release = "1.8.2 (2004-12-25)" -ruby_release = "#{RUBY_VERSION} (#{RUBY_RELEASE_DATE})" -if ruby_release < min_release - abort <<-end_message - - Rails requires Ruby version #{min_release} or later. - You're running #{ruby_release}; please upgrade to continue. - - end_message -end - -Signal.trap("INT") { puts; exit } - -require File.dirname(__FILE__) + '/../lib/rails_version' -abort "Rails #{Rails::VERSION::STRING}" if %w(--version -v).include? ARGV.first - -require File.dirname(__FILE__) + '/../lib/rails_generator' - -require 'rails_generator/scripts/generate' -Rails::Generator::Base.use_application_sources! -Rails::Generator::Scripts::Generate.new.run(ARGV, :generator => 'app') diff --git a/tracks/vendor/rails/railties/bin/runner b/tracks/vendor/rails/railties/bin/runner deleted file mode 100644 index ccc30f9d..00000000 --- a/tracks/vendor/rails/railties/bin/runner +++ /dev/null @@ -1,3 +0,0 @@ -#!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../config/boot' -require 'commands/runner' \ No newline at end of file diff --git a/tracks/vendor/rails/railties/bin/server b/tracks/vendor/rails/railties/bin/server deleted file mode 100644 index dfabcb88..00000000 --- a/tracks/vendor/rails/railties/bin/server +++ /dev/null @@ -1,3 +0,0 @@ -#!/usr/bin/env ruby -require File.dirname(__FILE__) + '/../config/boot' -require 'commands/server' \ No newline at end of file diff --git a/tracks/vendor/rails/railties/builtin/controllers/rails_info_controller.rb b/tracks/vendor/rails/railties/builtin/controllers/rails_info_controller.rb deleted file mode 100644 index ca2801e0..00000000 --- a/tracks/vendor/rails/railties/builtin/controllers/rails_info_controller.rb +++ /dev/null @@ -1,11 +0,0 @@ -module Controllers #:nodoc: - class RailsInfoController < ApplicationController - def properties - if local_request? - render :inline => Rails::Info.to_html - else - render :text => '

    For security purposes, this information is only available to local requests.

    ', :status => 500 - end - end - end -end \ No newline at end of file diff --git a/tracks/vendor/rails/railties/configs/apache.conf b/tracks/vendor/rails/railties/configs/apache.conf deleted file mode 100644 index d3c99834..00000000 --- a/tracks/vendor/rails/railties/configs/apache.conf +++ /dev/null @@ -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" \ No newline at end of file diff --git a/tracks/vendor/rails/railties/configs/database.yml b/tracks/vendor/rails/railties/configs/database.yml deleted file mode 100644 index c282a174..00000000 --- a/tracks/vendor/rails/railties/configs/database.yml +++ /dev/null @@ -1,85 +0,0 @@ -# MySQL (default setup). Versions 4.1 and 5.0 are recommended. -# -# Get the fast C bindings: -# gem install mysql -# (on OS X: gem install mysql -- --include=/usr/local/lib) -# And be sure to use new-style password hashing: -# http://dev.mysql.com/doc/refman/5.0/en/old-client.html -development: - adapter: mysql - database: <%= app_name %>_development - username: root - password: -<%= " socket: #{socket}" if socket %> - - # Connect on a TCP socket. If omitted, the adapter will connect on the - # domain socket given by socket instead. - #host: localhost - #port: 3306 - -# Warning: The database defined as 'test' will be erased and -# re-generated from your development database when you run 'rake'. -# Do not set this db to the same as development or production. -test: - adapter: mysql - database: <%= app_name %>_test - username: root - password: -<%= " socket: #{socket}" if socket %> - -production: - adapter: mysql - database: <%= app_name %>_production - username: root - password: -<%= " socket: #{socket}" if socket %> - - -# PostgreSQL versions 7.4 - 8.1 -# -# Get the C bindings: -# gem install postgres -# or use the pure-Ruby bindings on Windows: -# gem install postgres-pr -postgresql_example: - adapter: postgresql - database: <%= app_name %>_development - username: <%= app_name %> - password: - - # Connect on a TCP socket. Omitted by default since the client uses a - # domain socket that doesn't need configuration. - #host: remote-database - #port: 5432 - - # Schema search path. The server defaults to $user,public - #schema_search_path: myapp,sharedapp,public - - # Character set encoding. The server defaults to sql_ascii. - #encoding: UTF8 - - # Minimum log levels, in increasing order: - # debug5, debug4, debug3, debug2, debug1, - # info, notice, warning, error, log, fatal, or panic - # The server defaults to notice. - #min_messages: warning - - -# SQLite version 2.x -# gem install sqlite-ruby -sqlite_example: - adapter: sqlite - database: db/development.sqlite2 - - -# SQLite version 3.x -# gem install sqlite3-ruby -sqlite3_example: - adapter: sqlite3 - database: db/development.sqlite3 - - -# In-memory SQLite 3 database. Useful for tests. -sqlite3_in_memory_example: - adapter: sqlite3 - database: ":memory:" \ No newline at end of file diff --git a/tracks/vendor/rails/railties/configs/empty.log b/tracks/vendor/rails/railties/configs/empty.log deleted file mode 100644 index e69de29b..00000000 diff --git a/tracks/vendor/rails/railties/configs/lighttpd.conf b/tracks/vendor/rails/railties/configs/lighttpd.conf deleted file mode 100644 index 3577360f..00000000 --- a/tracks/vendor/rails/railties/configs/lighttpd.conf +++ /dev/null @@ -1,40 +0,0 @@ -# Default configuration file for the lighttpd web server -# Start using ./script/server lighttpd - -server.port = 3000 - -server.modules = ( "mod_rewrite", "mod_accesslog", "mod_fastcgi" ) -server.error-handler-404 = "/dispatch.fcgi" -server.document-root = "public/" - -server.errorlog = "log/lighttpd.error.log" -accesslog.filename = "log/lighttpd.access.log" - -url.rewrite = ( "^/$" => "index.html", "^([^.]+)$" => "$1.html" ) - -# Change *-procs to 2 if you need to use Upload Progress or other tasks that -# *need* to execute a second request while the first is still pending. -fastcgi.server = ( ".fcgi" => - ( "localhost" => - ( - "min-procs" => 1, - "max-procs" => 1, - "socket" => "log/fcgi.socket", - "bin-path" => "public/dispatch.fcgi", - "bin-environment" => ( "RAILS_ENV" => "development" ) - ) - ) -) - -mimetype.assign = ( - ".css" => "text/css", - ".gif" => "image/gif", - ".htm" => "text/html", - ".html" => "text/html", - ".jpeg" => "image/jpeg", - ".jpg" => "image/jpeg", - ".js" => "text/javascript", - ".png" => "image/png", - ".swf" => "application/x-shockwave-flash", - ".txt" => "text/plain" -) diff --git a/tracks/vendor/rails/railties/configs/routes.rb b/tracks/vendor/rails/railties/configs/routes.rb deleted file mode 100644 index 0b6d80a1..00000000 --- a/tracks/vendor/rails/railties/configs/routes.rb +++ /dev/null @@ -1,19 +0,0 @@ -ActionController::Routing::Routes.draw do |map| - # Add your own custom routes here. - # The priority is based upon order of creation: first created -> highest priority. - - # Here's a sample route: - # map.connect 'products/:id', :controller => 'catalog', :action => 'view' - # Keep in mind you can assign values other than :controller and :action - - # You can have the root of your site routed by hooking up '' - # -- just remember to delete public/index.html. - # map.connect '', :controller => "welcome" - - # Allow downloading Web Service WSDL as a file with an extension - # instead of a file named 'wsdl' - map.connect ':controller/service.wsdl', :action => 'wsdl' - - # Install the default route as the lowest priority. - map.connect ':controller/:action/:id' -end diff --git a/tracks/vendor/rails/railties/dispatches/dispatch.fcgi b/tracks/vendor/rails/railties/dispatches/dispatch.fcgi deleted file mode 100644 index 65188f38..00000000 --- a/tracks/vendor/rails/railties/dispatches/dispatch.fcgi +++ /dev/null @@ -1,24 +0,0 @@ -#!/usr/local/bin/ruby -# -# You may specify the path to the FastCGI crash log (a log of unhandled -# exceptions which forced the FastCGI instance to exit, great for debugging) -# and the number of requests to process before running garbage collection. -# -# By default, the FastCGI crash log is RAILS_ROOT/log/fastcgi.crash.log -# and the GC period is nil (turned off). A reasonable number of requests -# could range from 10-100 depending on the memory footprint of your app. -# -# Example: -# # Default log path, normal GC behavior. -# RailsFCGIHandler.process! -# -# # Default log path, 50 requests between GC. -# RailsFCGIHandler.process! nil, 50 -# -# # Custom log path, normal GC behavior. -# RailsFCGIHandler.process! '/var/log/myapp_fcgi_crash.log' -# -require File.dirname(__FILE__) + "/../config/environment" -require 'fcgi_handler' - -RailsFCGIHandler.process! diff --git a/tracks/vendor/rails/railties/dispatches/dispatch.rb b/tracks/vendor/rails/railties/dispatches/dispatch.rb deleted file mode 100644 index 9b5ae760..00000000 --- a/tracks/vendor/rails/railties/dispatches/dispatch.rb +++ /dev/null @@ -1,10 +0,0 @@ -#!/usr/local/bin/ruby - -require File.dirname(__FILE__) + "/../config/environment" unless defined?(RAILS_ROOT) - -# If you're using RubyGems and mod_ruby, this require should be changed to an absolute path one, like: -# "/usr/local/lib/ruby/gems/1.8/gems/rails-0.8.0/lib/dispatcher" -- otherwise performance is severely impaired -require "dispatcher" - -ADDITIONAL_LOAD_PATHS.reverse.each { |dir| $:.unshift(dir) if File.directory?(dir) } if defined?(Apache::RubyRun) -Dispatcher.dispatch \ No newline at end of file diff --git a/tracks/vendor/rails/railties/dispatches/gateway.cgi b/tracks/vendor/rails/railties/dispatches/gateway.cgi deleted file mode 100644 index d21bf099..00000000 --- a/tracks/vendor/rails/railties/dispatches/gateway.cgi +++ /dev/null @@ -1,97 +0,0 @@ -#!/usr/local/bin/ruby - -require 'drb' - -# This file includes an experimental gateway CGI implementation. It will work -# only on platforms which support both fork and sockets. -# -# To enable it edit public/.htaccess and replace dispatch.cgi with gateway.cgi. -# -# Next, create the directory log/drb_gateway and grant the apache user rw access -# to said directory. -# -# On the next request to your server, the gateway tracker should start up, along -# with a few listener processes. This setup should provide you with much better -# speeds than dispatch.cgi. -# -# Keep in mind that the first request made to the server will be slow, as the -# tracker and listeners will have to load. Also, the tracker and listeners will -# shutdown after a period if inactivity. You can set this value below -- the -# default is 90 seconds. - -TrackerSocket = File.expand_path(File.join(File.dirname(__FILE__), '../log/drb_gateway/tracker.sock')) -DieAfter = 90 # Seconds -Listeners = 3 - -def message(s) - $stderr.puts "gateway.cgi: #{s}" if ENV && ENV["DEBUG_GATEWAY"] -end - -def listener_socket(number) - File.expand_path(File.join(File.dirname(__FILE__), "../log/drb_gateway/listener_#{number}.sock")) -end - -unless File.exists? TrackerSocket - message "Starting tracker and #{Listeners} listeners" - fork do - Process.setsid - STDIN.reopen "/dev/null" - STDOUT.reopen "/dev/null", "a" - - root = File.expand_path(File.dirname(__FILE__) + '/..') - - message "starting tracker" - fork do - ARGV.clear - ARGV << TrackerSocket << Listeners.to_s << DieAfter.to_s - load File.join(root, 'script', 'tracker') - end - - message "starting listeners" - require File.join(root, 'config/environment.rb') - Listeners.times do |number| - fork do - ARGV.clear - ARGV << listener_socket(number) << DieAfter.to_s - load File.join(root, 'script', 'listener') - end - end - end - - message "waiting for tracker and listener to arise..." - ready = false - 10.times do - sleep 0.5 - break if (ready = File.exists?(TrackerSocket) && File.exists?(listener_socket(0))) - end - - if ready - message "tracker and listener are ready" - else - message "Waited 5 seconds, listener and tracker not ready... dropping request" - Kernel.exit 1 - end -end - -DRb.start_service - -message "connecting to tracker" -tracker = DRbObject.new_with_uri("drbunix:#{TrackerSocket}") - -input = $stdin.read -$stdin.close - -env = ENV.inspect - -output = nil -tracker.with_listener do |number| - message "connecting to listener #{number}" - socket = listener_socket(number) - listener = DRbObject.new_with_uri("drbunix:#{socket}") - output = listener.process(env, input) - message "listener #{number} has finished, writing output" -end - -$stdout.write output -$stdout.flush -$stdout.close \ No newline at end of file diff --git a/tracks/vendor/rails/railties/doc/README_FOR_APP b/tracks/vendor/rails/railties/doc/README_FOR_APP deleted file mode 100644 index ac6c1491..00000000 --- a/tracks/vendor/rails/railties/doc/README_FOR_APP +++ /dev/null @@ -1,2 +0,0 @@ -Use this README file to introduce your application and point to useful places in the API for learning more. -Run "rake appdoc" to generate API documentation for your models and controllers. \ No newline at end of file diff --git a/tracks/vendor/rails/railties/environments/boot.rb b/tracks/vendor/rails/railties/environments/boot.rb deleted file mode 100644 index 9fcd50fe..00000000 --- a/tracks/vendor/rails/railties/environments/boot.rb +++ /dev/null @@ -1,19 +0,0 @@ -# Don't change this file. Configuration is done in config/environment.rb and config/environments/*.rb - -unless defined?(RAILS_ROOT) - root_path = File.join(File.dirname(__FILE__), '..') - unless RUBY_PLATFORM =~ /mswin32/ - require 'pathname' - root_path = Pathname.new(root_path).cleanpath(true).to_s - end - RAILS_ROOT = root_path -end - -if File.directory?("#{RAILS_ROOT}/vendor/rails") - require "#{RAILS_ROOT}/vendor/rails/railties/lib/initializer" -else - require 'rubygems' - require 'initializer' -end - -Rails::Initializer.run(:set_load_path) diff --git a/tracks/vendor/rails/railties/environments/development.rb b/tracks/vendor/rails/railties/environments/development.rb deleted file mode 100644 index 04b77920..00000000 --- a/tracks/vendor/rails/railties/environments/development.rb +++ /dev/null @@ -1,19 +0,0 @@ -# Settings specified here will take precedence over those in config/environment.rb - -# In the development environment your application's code is reloaded on -# every request. This slows down response time but is perfect for development -# since you don't have to restart the webserver when you make code changes. -config.cache_classes = false - -# 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 - -# Don't care if the mailer can't send -config.action_mailer.raise_delivery_errors = false diff --git a/tracks/vendor/rails/railties/environments/environment.rb b/tracks/vendor/rails/railties/environments/environment.rb deleted file mode 100644 index fe987e24..00000000 --- a/tracks/vendor/rails/railties/environments/environment.rb +++ /dev/null @@ -1,53 +0,0 @@ -# Be sure to restart your web server when you modify this file. - -# Uncomment below to force Rails into production mode when -# you don't control web/app server and can't set it the proper way -# ENV['RAILS_ENV'] ||= 'production' - -# Bootstrap the Rails environment, frameworks, and default configuration -require File.join(File.dirname(__FILE__), 'boot') - -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, :action_mailer ] - - # Add additional load paths for your own custom dirs - # config.load_paths += %W( #{RAILS_ROOT}/extras ) - - # Force all environments to use the same logger level - # (by default production uses :info, the others :debug) - # config.log_level = :debug - - # 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 - - # Enable page/fragment caching by setting a file-based store - # (remember to create the caching directory and make it readable to the application) - # config.action_controller.fragment_cache_store = :file_store, "#{RAILS_ROOT}/cache" - - # Activate observers that should always be running - # config.active_record.observers = :cacher, :garbage_collector - - # Make Active Record use UTC-base instead of local time - # config.active_record.default_timezone = :utc - - # Use Active Record's schema dumper instead of SQL when creating the test database - # (enables use of different database adapters for development and test environments) - # config.active_record.schema_format = :ruby - - # See Rails::Configuration for more options -end - -# Add new inflection rules using the following format -# (all these examples are active by default): -# Inflector.inflections do |inflect| -# inflect.plural /^(ox)$/i, '\1en' -# inflect.singular /^(ox)en/i, '\1' -# inflect.irregular 'person', 'people' -# inflect.uncountable %w( fish sheep ) -# end - -# Include your application configuration below \ No newline at end of file diff --git a/tracks/vendor/rails/railties/environments/production.rb b/tracks/vendor/rails/railties/environments/production.rb deleted file mode 100644 index c9a4396c..00000000 --- a/tracks/vendor/rails/railties/environments/production.rb +++ /dev/null @@ -1,19 +0,0 @@ -# Settings specified here will take precedence over those in config/environment.rb - -# The production environment is meant for finished, "live" apps. -# Code is not reloaded between requests -config.cache_classes = true - -# Use a different logger for distributed setups -# config.logger = SyslogLogger.new - - -# Full error reports are disabled and caching is turned on -config.action_controller.consider_all_requests_local = false -config.action_controller.perform_caching = true - -# Enable serving of images, stylesheets, and javascripts from an asset server -# config.action_controller.asset_host = "http://assets.example.com" - -# Disable delivery errors if you bad email addresses should just be ignored -# config.action_mailer.raise_delivery_errors = false diff --git a/tracks/vendor/rails/railties/environments/test.rb b/tracks/vendor/rails/railties/environments/test.rb deleted file mode 100644 index 6a4cddbd..00000000 --- a/tracks/vendor/rails/railties/environments/test.rb +++ /dev/null @@ -1,19 +0,0 @@ -# Settings specified here will take precedence over those in config/environment.rb - -# The test environment is used exclusively to run your application's -# test suite. You never need to work with it otherwise. Remember that -# your test database is "scratch space" for the test suite and is wiped -# and recreated between test runs. Don't rely on the data there! -config.cache_classes = true - -# Log error messages when you accidentally call methods on nil. -config.whiny_nils = true - -# Show full error reports and disable caching -config.action_controller.consider_all_requests_local = true -config.action_controller.perform_caching = false - -# Tell ActionMailer not to deliver emails to the real world. -# The :test delivery method accumulates sent emails in the -# ActionMailer::Base.deliveries array. -config.action_mailer.delivery_method = :test \ No newline at end of file diff --git a/tracks/vendor/rails/railties/fresh_rakefile b/tracks/vendor/rails/railties/fresh_rakefile deleted file mode 100644 index cffd19f0..00000000 --- a/tracks/vendor/rails/railties/fresh_rakefile +++ /dev/null @@ -1,10 +0,0 @@ -# Add your own tasks in files placed in lib/tasks ending in .rake, -# for example lib/tasks/switchtower.rake, and they will automatically be available to Rake. - -require(File.join(File.dirname(__FILE__), 'config', 'boot')) - -require 'rake' -require 'rake/testtask' -require 'rake/rdoctask' - -require 'tasks/rails' \ No newline at end of file diff --git a/tracks/vendor/rails/railties/helpers/application.rb b/tracks/vendor/rails/railties/helpers/application.rb deleted file mode 100644 index 537de40d..00000000 --- a/tracks/vendor/rails/railties/helpers/application.rb +++ /dev/null @@ -1,4 +0,0 @@ -# Filters added to this controller will be run for all controllers in the application. -# Likewise, all the methods added will be available for all controllers. -class ApplicationController < ActionController::Base -end \ No newline at end of file diff --git a/tracks/vendor/rails/railties/helpers/application_helper.rb b/tracks/vendor/rails/railties/helpers/application_helper.rb deleted file mode 100644 index 22a7940e..00000000 --- a/tracks/vendor/rails/railties/helpers/application_helper.rb +++ /dev/null @@ -1,3 +0,0 @@ -# Methods added to this helper will be available to all templates in the application. -module ApplicationHelper -end diff --git a/tracks/vendor/rails/railties/helpers/test_helper.rb b/tracks/vendor/rails/railties/helpers/test_helper.rb deleted file mode 100644 index a299c7f6..00000000 --- a/tracks/vendor/rails/railties/helpers/test_helper.rb +++ /dev/null @@ -1,28 +0,0 @@ -ENV["RAILS_ENV"] = "test" -require File.expand_path(File.dirname(__FILE__) + "/../config/environment") -require 'test_help' - -class Test::Unit::TestCase - # Transactional fixtures accelerate your tests by wrapping each test method - # in a transaction that's rolled back on completion. This ensures that the - # test database remains unchanged so your fixtures don't have to be reloaded - # between every test method. Fewer database queries means faster tests. - # - # Read Mike Clark's excellent walkthrough at - # http://clarkware.com/cgi/blosxom/2005/10/24#Rails10FastTesting - # - # Every Active Record database supports transactions except MyISAM tables - # in MySQL. Turn off transactional fixtures in this case; however, if you - # don't care one way or the other, switching from MyISAM to InnoDB tables - # is recommended. - self.use_transactional_fixtures = true - - # Instantiated fixtures are slow, but give you @david where otherwise you - # would need people(:david). If you don't want to migrate your existing - # test cases which use the @david style and don't mind the speed hit (each - # instantiated fixtures translates to a database query per test method), - # then set this back to true. - self.use_instantiated_fixtures = false - - # Add more helper methods to be used by all tests here... -end diff --git a/tracks/vendor/rails/railties/html/404.html b/tracks/vendor/rails/railties/html/404.html deleted file mode 100644 index 0e184561..00000000 --- a/tracks/vendor/rails/railties/html/404.html +++ /dev/null @@ -1,8 +0,0 @@ - - - -

    File not found

    -

    Change this error message for pages not found in public/404.html

    - - \ No newline at end of file diff --git a/tracks/vendor/rails/railties/html/500.html b/tracks/vendor/rails/railties/html/500.html deleted file mode 100644 index a1001a00..00000000 --- a/tracks/vendor/rails/railties/html/500.html +++ /dev/null @@ -1,8 +0,0 @@ - - - -

    Application error (Apache)

    -

    Change this error message for exceptions thrown outside of an action (like in Dispatcher setups or broken Ruby code) in public/500.html

    - - \ No newline at end of file diff --git a/tracks/vendor/rails/railties/html/favicon.ico b/tracks/vendor/rails/railties/html/favicon.ico deleted file mode 100644 index e69de29b..00000000 diff --git a/tracks/vendor/rails/railties/html/images/rails.png b/tracks/vendor/rails/railties/html/images/rails.png deleted file mode 100644 index b8441f18..00000000 Binary files a/tracks/vendor/rails/railties/html/images/rails.png and /dev/null differ diff --git a/tracks/vendor/rails/railties/html/index.html b/tracks/vendor/rails/railties/html/index.html deleted file mode 100644 index 1f5e62bb..00000000 --- a/tracks/vendor/rails/railties/html/index.html +++ /dev/null @@ -1,277 +0,0 @@ - - - - - Ruby on Rails: Welcome aboard - - - - - - -
    - - -
    - - - - -
    -

    Getting started

    -

    Here’s how to get rolling:

    - -
      -
    1. -

      Create your databases and edit config/database.yml

      -

      Rails needs to know your login and password.

      -
    2. - -
    3. -

      Use script/generate to create your models and controllers

      -

      To see all available options, run it without parameters.

      -
    4. - -
    5. -

      Set up a default route and remove or rename this file

      -

      Routes are setup in config/routes.rb.

      -
    6. -
    -
    -
    - - -
    - - \ No newline at end of file diff --git a/tracks/vendor/rails/railties/html/javascripts/controls.js b/tracks/vendor/rails/railties/html/javascripts/controls.js deleted file mode 100644 index 9742b691..00000000 --- a/tracks/vendor/rails/railties/html/javascripts/controls.js +++ /dev/null @@ -1,750 +0,0 @@ -// Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) -// (c) 2005 Ivan Krstic (http://blogs.law.harvard.edu/ivan) -// (c) 2005 Jon Tirsen (http://www.tirsen.com) -// Contributors: -// Richard Livsey -// Rahul Bhargava -// Rob Wills -// -// See scriptaculous.js for full license. - -// 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. - -var Autocompleter = {} -Autocompleter.Base = function() {}; -Autocompleter.Base.prototype = { - baseInitialize: function(element, update, options) { - this.element = $(element); - this.update = $(update); - this.hasFocus = false; - this.changed = false; - this.active = false; - this.index = 0; - this.entryCount = 0; - - 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); - - 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 && - (navigator.appVersion.indexOf('MSIE')>0) && - (navigator.userAgent.indexOf('Opera')<0) && - (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); - 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(navigator.appVersion.indexOf('AppleWebKit')>0) Event.stop(event); - return; - case Event.KEY_DOWN: - this.markNext(); - this.render(); - if(navigator.appVersion.indexOf('AppleWebKit')>0) Event.stop(event); - return; - } - else - if(event.keyCode==Event.KEY_TAB || event.keyCode==Event.KEY_RETURN) - return; - - this.changed = true; - this.hasFocus = true; - - if(this.observer) clearTimeout(this.observer); - this.observer = - setTimeout(this.onObserverEvent.bind(this), this.options.frequency*1000); - }, - - 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; - }, - - markNext: function() { - if(this.index < this.entryCount-1) this.index++ - else this.index = 0; - }, - - 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 = Element.collectTextNodesIgnoreClass(selectedElement, 'informal'); - var lastTokenPos = this.findLastToken(); - if (lastTokenPos != -1) { - var newValue = this.element.value.substr(0, lastTokenPos + 1); - var whitespace = this.element.value.substr(lastTokenPos + 1).match(/^\s+/); - if (whitespace) - newValue += whitespace[0]; - this.element.value = newValue + value; - } else { - this.element.value = 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.firstChild); - - if(this.update.firstChild && this.update.firstChild.childNodes) { - this.entryCount = - this.update.firstChild.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; - 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; - if(this.getToken().length>=this.options.minChars) { - this.startIndicator(); - this.getUpdatedChoices(); - } else { - this.active = false; - this.hide(); - } - }, - - getToken: function() { - var tokenPos = this.findLastToken(); - if (tokenPos != -1) - var ret = this.element.value.substr(tokenPos + 1).replace(/^\s+/,'').replace(/\s+$/,''); - else - var ret = this.element.value; - - return /\n/.test(ret) ? '' : ret; - }, - - findLastToken: function() { - var lastTokenPos = -1; - - for (var i=0; i lastTokenPos) - lastTokenPos = thisTokenPos; - } - return lastTokenPos; - } -} - -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() { - 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 -// -// see documentation on http://wiki.script.aculo.us/scriptaculous/show/Ajax.InPlaceEditor - -// 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(); -Ajax.InPlaceEditor.defaultHighlightColor = "#FFFF99"; -Ajax.InPlaceEditor.prototype = { - initialize: function(element, url, options) { - this.url = url; - this.element = $(element); - - this.options = Object.extend({ - okText: "ok", - cancelText: "cancel", - savingText: "Saving...", - clickToEditText: "Click to edit", - okText: "ok", - rows: 1, - onComplete: function(transport, element) { - new Effect.Highlight(element, {startcolor: this.options.highlightcolor}); - }, - onFailure: function(transport) { - alert("Error communicating with the server: " + transport.responseText.stripTags()); - }, - callback: function(form) { - return Form.serialize(form); - }, - handleLineBreaks: true, - loadingText: 'Loading...', - savingClassName: 'inplaceeditor-saving', - loadingClassName: 'inplaceeditor-loading', - formClassName: 'inplaceeditor-form', - highlightcolor: Ajax.InPlaceEditor.defaultHighlightColor, - highlightendcolor: "#FFFFFF", - externalControl: null, - ajaxOptions: {} - }, options || {}); - - if(!this.options.formId && this.element.id) { - this.options.formId = this.element.id + "-inplaceeditor"; - if ($(this.options.formId)) { - // there's already a form with that name, don't specify an id - this.options.formId = null; - } - } - - if (this.options.externalControl) { - this.options.externalControl = $(this.options.externalControl); - } - - this.originalBackground = Element.getStyle(this.element, 'background-color'); - if (!this.originalBackground) { - this.originalBackground = "transparent"; - } - - this.element.title = this.options.clickToEditText; - - this.onclickListener = this.enterEditMode.bindAsEventListener(this); - this.mouseoverListener = this.enterHover.bindAsEventListener(this); - this.mouseoutListener = this.leaveHover.bindAsEventListener(this); - Event.observe(this.element, 'click', this.onclickListener); - Event.observe(this.element, 'mouseover', this.mouseoverListener); - Event.observe(this.element, 'mouseout', this.mouseoutListener); - if (this.options.externalControl) { - Event.observe(this.options.externalControl, 'click', this.onclickListener); - Event.observe(this.options.externalControl, 'mouseover', this.mouseoverListener); - Event.observe(this.options.externalControl, 'mouseout', this.mouseoutListener); - } - }, - enterEditMode: function(evt) { - if (this.saving) return; - if (this.editing) return; - this.editing = true; - this.onEnterEditMode(); - if (this.options.externalControl) { - Element.hide(this.options.externalControl); - } - Element.hide(this.element); - this.createForm(); - this.element.parentNode.insertBefore(this.form, this.element); - Field.scrollFreeActivate(this.editField); - // stop the event to avoid a page refresh in Safari - if (evt) { - Event.stop(evt); - } - return false; - }, - createForm: function() { - this.form = document.createElement("form"); - this.form.id = this.options.formId; - Element.addClassName(this.form, this.options.formClassName) - this.form.onsubmit = this.onSubmit.bind(this); - - this.createEditField(); - - if (this.options.textarea) { - var br = document.createElement("br"); - this.form.appendChild(br); - } - - okButton = document.createElement("input"); - okButton.type = "submit"; - okButton.value = this.options.okText; - this.form.appendChild(okButton); - - cancelLink = document.createElement("a"); - cancelLink.href = "#"; - cancelLink.appendChild(document.createTextNode(this.options.cancelText)); - cancelLink.onclick = this.onclickCancel.bind(this); - this.form.appendChild(cancelLink); - }, - hasHTMLLineBreaks: function(string) { - if (!this.options.handleLineBreaks) return false; - return string.match(/
    /i); - }, - convertHTMLLineBreaks: function(string) { - return string.replace(/
    /gi, "\n").replace(//gi, "\n").replace(/<\/p>/gi, "\n").replace(/

    /gi, ""); - }, - createEditField: function() { - var text; - if(this.options.loadTextURL) { - text = this.options.loadingText; - } else { - text = this.getText(); - } - - if (this.options.rows == 1 && !this.hasHTMLLineBreaks(text)) { - this.options.textarea = false; - var textField = document.createElement("input"); - textField.type = "text"; - textField.name = "value"; - textField.value = text; - textField.style.backgroundColor = this.options.highlightcolor; - var size = this.options.size || this.options.cols || 0; - if (size != 0) textField.size = size; - this.editField = textField; - } else { - this.options.textarea = true; - var textArea = document.createElement("textarea"); - textArea.name = "value"; - textArea.value = this.convertHTMLLineBreaks(text); - textArea.rows = this.options.rows; - textArea.cols = this.options.cols || 40; - this.editField = textArea; - } - - if(this.options.loadTextURL) { - this.loadExternalText(); - } - this.form.appendChild(this.editField); - }, - getText: function() { - return this.element.innerHTML; - }, - loadExternalText: function() { - Element.addClassName(this.form, this.options.loadingClassName); - this.editField.disabled = true; - new Ajax.Request( - this.options.loadTextURL, - Object.extend({ - asynchronous: true, - onComplete: this.onLoadedExternalText.bind(this) - }, this.options.ajaxOptions) - ); - }, - onLoadedExternalText: function(transport) { - Element.removeClassName(this.form, this.options.loadingClassName); - this.editField.disabled = false; - this.editField.value = transport.responseText.stripTags(); - }, - onclickCancel: function() { - this.onComplete(); - this.leaveEditMode(); - return false; - }, - onFailure: function(transport) { - this.options.onFailure(transport); - if (this.oldInnerHTML) { - this.element.innerHTML = this.oldInnerHTML; - this.oldInnerHTML = null; - } - return false; - }, - onSubmit: function() { - // onLoading resets these so we need to save them away for the Ajax call - var form = this.form; - var value = this.editField.value; - - // do this first, sometimes the ajax call returns before we get a chance to switch on Saving... - // which means this will actually switch on Saving... *after* we've left edit mode causing Saving... - // to be displayed indefinitely - this.onLoading(); - - new Ajax.Updater( - { - success: this.element, - // don't update on failure (this could be an option) - failure: null - }, - this.url, - Object.extend({ - parameters: this.options.callback(form, value), - onComplete: this.onComplete.bind(this), - onFailure: this.onFailure.bind(this) - }, this.options.ajaxOptions) - ); - // stop the event to avoid a page refresh in Safari - if (arguments.length > 1) { - Event.stop(arguments[0]); - } - return false; - }, - onLoading: function() { - this.saving = true; - this.removeForm(); - this.leaveHover(); - this.showSaving(); - }, - showSaving: function() { - this.oldInnerHTML = this.element.innerHTML; - this.element.innerHTML = this.options.savingText; - Element.addClassName(this.element, this.options.savingClassName); - this.element.style.backgroundColor = this.originalBackground; - Element.show(this.element); - }, - removeForm: function() { - if(this.form) { - if (this.form.parentNode) Element.remove(this.form); - this.form = null; - } - }, - enterHover: function() { - if (this.saving) return; - this.element.style.backgroundColor = this.options.highlightcolor; - if (this.effect) { - this.effect.cancel(); - } - Element.addClassName(this.element, this.options.hoverClassName) - }, - leaveHover: function() { - if (this.options.backgroundColor) { - this.element.style.backgroundColor = this.oldBackground; - } - Element.removeClassName(this.element, this.options.hoverClassName) - if (this.saving) return; - this.effect = new Effect.Highlight(this.element, { - startcolor: this.options.highlightcolor, - endcolor: this.options.highlightendcolor, - restorecolor: this.originalBackground - }); - }, - leaveEditMode: function() { - Element.removeClassName(this.element, this.options.savingClassName); - this.removeForm(); - this.leaveHover(); - this.element.style.backgroundColor = this.originalBackground; - Element.show(this.element); - if (this.options.externalControl) { - Element.show(this.options.externalControl); - } - this.editing = false; - this.saving = false; - this.oldInnerHTML = null; - this.onLeaveEditMode(); - }, - onComplete: function(transport) { - this.leaveEditMode(); - this.options.onComplete.bind(this)(transport, this.element); - }, - onEnterEditMode: function() {}, - onLeaveEditMode: function() {}, - dispose: function() { - if (this.oldInnerHTML) { - this.element.innerHTML = this.oldInnerHTML; - } - this.leaveEditMode(); - Event.stopObserving(this.element, 'click', this.onclickListener); - Event.stopObserving(this.element, 'mouseover', this.mouseoverListener); - Event.stopObserving(this.element, 'mouseout', this.mouseoutListener); - if (this.options.externalControl) { - Event.stopObserving(this.options.externalControl, 'click', this.onclickListener); - Event.stopObserving(this.options.externalControl, 'mouseover', this.mouseoverListener); - Event.stopObserving(this.options.externalControl, 'mouseout', this.mouseoutListener); - } - } -}; - -// 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)); - } -}; \ No newline at end of file diff --git a/tracks/vendor/rails/railties/html/javascripts/dragdrop.js b/tracks/vendor/rails/railties/html/javascripts/dragdrop.js deleted file mode 100644 index 92d1f731..00000000 --- a/tracks/vendor/rails/railties/html/javascripts/dragdrop.js +++ /dev/null @@ -1,584 +0,0 @@ -// Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) -// -// See scriptaculous.js for full license. - -/*--------------------------------------------------------------------------*/ - -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 - }, arguments[1] || {}); - - // cache containers - if(options.containment) { - options._containers = []; - var containment = options.containment; - if((typeof containment == 'object') && - (containment.constructor == Array)) { - 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); - }, - - isContained: function(element, drop) { - var parentNode = element.parentNode; - return drop._containers.detect(function(c) { return parentNode == 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; - - if(this.last_active) this.deactivate(this.last_active); - this.drops.each( function(drop) { - if(Droppables.isAffected(point, element, drop)) { - if(drop.onHover) - drop.onHover(element, drop.element, Position.overlap(drop.overlap, drop.element)); - if(drop.greedy) { - Droppables.activate(drop); - throw $break; - } - } - }); - }, - - 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); - }, - - 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) { - window.focus(); // allows keypress events if window isn't currently focused, fails for Safari - this.activeDraggable = draggable; - }, - - deactivate: function(draggbale) { - 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.activeDraggable) return; - this._lastPointer = null; - this.activeDraggable.endDrag(event); - }, - - 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); - }); - }, - - _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.prototype = { - initialize: function(element) { - var options = Object.extend({ - handle: false, - starteffect: function(element) { - new Effect.Opacity(element, {duration:0.2, from:1.0, to:0.7}); - }, - reverteffect: function(element, top_offset, left_offset) { - var dur = Math.sqrt(Math.abs(top_offset^2)+Math.abs(left_offset^2))*0.02; - element._revert = new Effect.MoveBy(element, -top_offset, -left_offset, {duration:dur}); - }, - endeffect: function(element) { - new Effect.Opacity(element, {duration:0.2, from:0.7, to:1.0}); - }, - zindex: 1000, - revert: false, - snap: false // false, or xy or [x,y] or function(x,y){ return [x,y] } - }, arguments[1] || {}); - - this.element = $(element); - - if(options.handle && (typeof options.handle == 'string')) - this.handle = Element.childrenWithClassName(this.element, options.handle)[0]; - if(!this.handle) this.handle = $(options.handle); - if(!this.handle) this.handle = this.element; - - Element.makePositioned(this.element); // fix IE - - this.delta = this.currentDelta(); - 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(this.element.style.left || '0'), - parseInt(this.element.style.top || '0')]); - }, - - initDrag: function(event) { - if(Event.isLeftClick(event)) { - // abort on form elements, fixes a Firefox issue - var src = Event.element(event); - if(src.tagName && ( - src.tagName=='INPUT' || - src.tagName=='SELECT' || - src.tagName=='BUTTON' || - src.tagName=='TEXTAREA')) return; - - if(this.element._revert) { - this.element._revert.cancel(); - this.element._revert = null; - } - - 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.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); - Position.absolutize(this.element); - this.element.parentNode.insertBefore(this._clone, this.element); - } - - Draggables.notify('onStart', this, event); - if(this.options.starteffect) this.options.starteffect(this.element); - }, - - updateDrag: function(event, pointer) { - if(!this.dragging) this.startDrag(event); - Position.prepare(); - Droppables.show(pointer, this.element); - Draggables.notify('onDrag', this, event); - this.draw(pointer); - if(this.options.change) this.options.change(this); - - // fix AppleWebKit rendering - if(navigator.appVersion.indexOf('AppleWebKit')>0) window.scrollBy(0,0); - Event.stop(event); - }, - - finishDrag: function(event, success) { - this.dragging = false; - - if(this.options.ghosting) { - Position.relativize(this.element); - Element.remove(this._clone); - this._clone = null; - } - - if(success) Droppables.fire(event, this.element); - Draggables.notify('onEnd', this, event); - - var revert = this.options.revert; - if(revert && typeof revert == 'function') revert = revert(this.element); - - var d = this.currentDelta(); - if(revert && this.options.reverteffect) { - 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.finishDrag(event, true); - Event.stop(event); - }, - - draw: function(point) { - var pos = Position.cumulativeOffset(this.element); - var d = this.currentDelta(); - pos[0] -= d[0]; pos[1] -= d[1]; - - var p = [0,1].map(function(i){ return (point[i]-pos[i]-this.offset[i]) }.bind(this)); - - if(this.options.snap) { - if(typeof this.options.snap == 'function') { - p = this.options.snap(p[0],p[1]); - } else { - if(this.options.snap instanceof Array) { - p = p.map( function(v, i) { - return Math.round(v/this.options.snap[i])*this.options.snap[i] }.bind(this)) - } else { - p = p.map( function(v) { - return Math.round(v/this.options.snap)*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 - } -} - -/*--------------------------------------------------------------------------*/ - -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 = { - sortables: new Array(), - - options: function(element){ - element = $(element); - return this.sortables.detect(function(s) { return s.element == element }); - }, - - destroy: function(element){ - element = $(element); - this.sortables.findAll(function(s) { return s.element == element }).each(function(s){ - Draggables.removeObserver(s.element); - s.droppables.each(function(d){ Droppables.remove(d) }); - s.draggables.invoke('destroy'); - }); - this.sortables = this.sortables.reject(function(s) { return s.element == element }); - }, - - create: function(element) { - element = $(element); - var options = Object.extend({ - element: element, - tag: 'li', // assumes li children, override with tag: 'tagname' - dropOnEmpty: false, - tree: false, // fixme: unimplemented - 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, - hoverclass: null, - ghosting: false, - format: null, - 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, - 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, - hoverclass: options.hoverclass, - onHover: Sortable.onHover, - greedy: !options.dropOnEmpty - } - - // fix for gecko engine - Element.cleanWhitespace(element); - - options.draggables = []; - options.droppables = []; - - // make it so - - // drop on empty handling - if(options.dropOnEmpty) { - Droppables.add(element, - {containment: options.containment, onHover: Sortable.onEmptyHover, greedy: false}); - options.droppables.push(element); - } - - (this.findElements(element, options) || []).each( function(e) { - // handles are per-draggable - var handle = options.handle ? - Element.childrenWithClassName(e, options.handle)[0] : e; - options.draggables.push( - new Draggable(e, Object.extend(options_for_draggable, { handle: handle }))); - Droppables.add(e, options_for_droppable); - options.droppables.push(e); - }); - - // keep reference - this.sortables.push(options); - - // for onupdate - Draggables.addObserver(new SortableObserver(element, options.onUpdate)); - - }, - - // return all suitable-for-sortable elements in a guaranteed order - findElements: function(element, options) { - if(!element.hasChildNodes()) return null; - var elements = []; - $A(element.childNodes).each( function(e) { - if(e.tagName && e.tagName.toUpperCase()==options.tag.toUpperCase() && - (!options.only || (Element.hasClassName(e, options.only)))) - elements.push(e); - if(options.tree) { - var grandchildren = this.findElements(e, options); - if(grandchildren) elements.push(grandchildren); - } - }); - - return (elements.length>0 ? elements.flatten() : null); - }, - - onHover: function(element, dropon, overlap) { - 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) { - if(element.parentNode!=dropon) { - var oldParentNode = element.parentNode; - dropon.appendChild(element); - Sortable.options(oldParentNode).onChange(element); - Sortable.options(dropon).onChange(element); - } - }, - - unmark: function() { - if(Sortable._marker) Element.hide(Sortable._marker); - }, - - 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') || document.createElement('DIV'); - Element.hide(Sortable._marker); - Element.addClassName(Sortable._marker, 'dropmarker'); - Sortable._marker.style.position = 'absolute'; - document.getElementsByTagName("body").item(0).appendChild(Sortable._marker); - } - var offsets = Position.cumulativeOffset(dropon); - Sortable._marker.style.left = offsets[0] + 'px'; - Sortable._marker.style.top = offsets[1] + 'px'; - - if(position=='after') - if(sortable.overlap == 'horizontal') - Sortable._marker.style.left = (offsets[0]+dropon.clientWidth) + 'px'; - else - Sortable._marker.style.top = (offsets[1]+dropon.clientHeight) + 'px'; - - Element.show(Sortable._marker); - }, - - serialize: function(element) { - element = $(element); - var sortableOptions = this.options(element); - var options = Object.extend({ - tag: sortableOptions.tag, - only: sortableOptions.only, - name: element.id, - format: sortableOptions.format || /^[^_]*_(.*)$/ - }, arguments[1] || {}); - return $(this.findElements(element, options) || []).map( function(item) { - return (encodeURIComponent(options.name) + "[]=" + - encodeURIComponent(item.id.match(options.format) ? item.id.match(options.format)[1] : '')); - }).join("&"); - } -} \ No newline at end of file diff --git a/tracks/vendor/rails/railties/html/javascripts/effects.js b/tracks/vendor/rails/railties/html/javascripts/effects.js deleted file mode 100644 index 414398ce..00000000 --- a/tracks/vendor/rails/railties/html/javascripts/effects.js +++ /dev/null @@ -1,854 +0,0 @@ -// Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) -// Contributors: -// Justin Palmer (http://encytemedia.com/) -// Mark Pilgrim (http://diveintomark.org/) -// Martin Bialasinki -// -// See scriptaculous.js for full license. - -/* ------------- element ext -------------- */ - -// 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.collectTextNodesIgnoreClass = function(element, ignoreclass) { - var children = $(element).childNodes; - var text = ''; - var classtest = new RegExp('^([^ ]+ )*' + ignoreclass+ '( [^ ]+)*$','i'); - - for (var i = 0; i < children.length; i++) { - if(children[i].nodeType==3) { - text+=children[i].nodeValue; - } else { - if((!children[i].className.match(classtest)) && children[i].hasChildNodes()) - text += Element.collectTextNodesIgnoreClass(children[i], ignoreclass); - } - } - - return text; -} - -Element.setStyle = function(element, style) { - element = $(element); - for(k in style) element.style[k.camelize()] = style[k]; -} - -Element.setContentZoom = function(element, percent) { - Element.setStyle(element, {fontSize: (percent/100) + 'em'}); - if(navigator.appVersion.indexOf('AppleWebKit')>0) window.scrollBy(0,0); -} - -Element.getOpacity = function(element){ - var opacity; - if (opacity = Element.getStyle(element, 'opacity')) - return parseFloat(opacity); - if (opacity = (Element.getStyle(element, 'filter') || '').match(/alpha\(opacity=(.*)\)/)) - if(opacity[1]) return parseFloat(opacity[1]) / 100; - return 1.0; -} - -Element.setOpacity = function(element, value){ - element= $(element); - if (value == 1){ - Element.setStyle(element, { opacity: - (/Gecko/.test(navigator.userAgent) && !/Konqueror|Safari|KHTML/.test(navigator.userAgent)) ? - 0.999999 : null }); - if(/MSIE/.test(navigator.userAgent)) - Element.setStyle(element, {filter: Element.getStyle(element,'filter').replace(/alpha\([^\)]*\)/gi,'')}); - } else { - if(value < 0.00001) value = 0; - Element.setStyle(element, {opacity: value}); - if(/MSIE/.test(navigator.userAgent)) - Element.setStyle(element, - { filter: Element.getStyle(element,'filter').replace(/alpha\([^\)]*\)/gi,'') + - 'alpha(opacity='+value*100+')' }); - } -} - -Element.getInlineOpacity = function(element){ - return $(element).style.opacity || ''; -} - -Element.childrenWithClassName = function(element, className) { - return $A($(element).getElementsByTagName('*')).select( - function(c) { return Element.hasClassName(c, className) }); -} - -Array.prototype.call = function() { - var args = arguments; - this.each(function(f){ f.apply(this, args) }); -} - -/*--------------------------------------------------------------------------*/ - -var Effect = { - tagifyText: function(element) { - var tagifyStyle = 'position:relative'; - if(/MSIE/.test(navigator.userAgent)) tagifyStyle += ';zoom:1'; - element = $(element); - $A(element.childNodes).each( function(child) { - if(child.nodeType==3) { - child.nodeValue.toArray().each( function(character) { - element.insertBefore( - Builder.node('span',{style: tagifyStyle}, - character == ' ' ? String.fromCharCode(160) : character), - child); - }); - Element.remove(child); - } - }); - }, - multiple: function(element, effect) { - var elements; - if(((typeof element == 'object') || - (typeof element == 'function')) && - (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 })); - }); - } -}; - -var Effect2 = Effect; // deprecated - -/* ------------- transitions ------------- */ - -Effect.Transitions = {} - -Effect.Transitions.linear = function(pos) { - return pos; -} -Effect.Transitions.sinoidal = function(pos) { - return (-Math.cos(pos*Math.PI)/2) + 0.5; -} -Effect.Transitions.reverse = function(pos) { - return 1-pos; -} -Effect.Transitions.flicker = function(pos) { - return ((-Math.cos(pos*Math.PI)/4) + 0.75) + Math.random()/4; -} -Effect.Transitions.wobble = function(pos) { - return (-Math.cos(pos*Math.PI*(9*pos))/2) + 0.5; -} -Effect.Transitions.pulse = function(pos) { - return (Math.floor(pos*10) % 2 == 0 ? - (pos*10-Math.floor(pos*10)) : 1-(pos*10-Math.floor(pos*10))); -} -Effect.Transitions.none = function(pos) { - return 0; -} -Effect.Transitions.full = function(pos) { - return 1; -} - -/* ------------- core effects ------------- */ - -Effect.Queue = { - effects: [], - _each: function(iterator) { - this.effects._each(iterator); - }, - interval: null, - add: function(effect) { - var timestamp = new Date().getTime(); - - switch(effect.options.queue) { - 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 'end': - // start effect after last queued effect has finished - timestamp = this.effects.pluck('finishOn').max() || timestamp; - break; - } - - effect.startOn += timestamp; - effect.finishOn += timestamp; - this.effects.push(effect); - if(!this.interval) - this.interval = setInterval(this.loop.bind(this), 40); - }, - 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(); - this.effects.invoke('loop', timePos); - } -} -Object.extend(Effect.Queue, Enumerable); - -Effect.Base = function() {}; -Effect.Base.prototype = { - position: null, - setOptions: function(options) { - this.options = Object.extend({ - transition: Effect.Transitions.sinoidal, - duration: 1.0, // seconds - fps: 25.0, // max. 25fps due to Effect.Queue implementation - sync: false, // true for combining - from: 0.0, - to: 1.0, - delay: 0.0, - queue: 'parallel' - }, options || {}); - }, - start: function(options) { - this.setOptions(options || {}); - this.currentFrame = 0; - this.state = 'idle'; - this.startOn = this.options.delay*1000; - this.finishOn = this.startOn + (this.options.duration*1000); - this.event('beforeStart'); - if(!this.options.sync) Effect.Queue.add(this); - }, - loop: function(timePos) { - if(timePos >= 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.finishOn - this.startOn); - var frame = Math.round(pos * this.options.fps * this.options.duration); - if(frame > this.currentFrame) { - this.render(pos); - this.currentFrame = frame; - } - } - }, - render: function(pos) { - if(this.state == 'idle') { - this.state = 'running'; - this.event('beforeSetup'); - if(this.setup) this.setup(); - this.event('afterSetup'); - } - if(this.state == 'running') { - if(this.options.transition) pos = this.options.transition(pos); - pos *= (this.options.to-this.options.from); - pos += this.options.from; - this.position = pos; - this.event('beforeUpdate'); - if(this.update) this.update(pos); - this.event('afterUpdate'); - } - }, - cancel: function() { - if(!this.options.sync) Effect.Queue.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() { - return '#'; - } -} - -Effect.Parallel = Class.create(); -Object.extend(Object.extend(Effect.Parallel.prototype, Effect.Base.prototype), { - 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.Opacity = Class.create(); -Object.extend(Object.extend(Effect.Opacity.prototype, Effect.Base.prototype), { - initialize: function(element) { - this.element = $(element); - // make this work on IE on elements without 'layout' - if(/MSIE/.test(navigator.userAgent) && (!this.element.hasLayout)) - Element.setStyle(this.element, {zoom: 1}); - var options = Object.extend({ - from: Element.getOpacity(this.element) || 0.0, - to: 1.0 - }, arguments[1] || {}); - this.start(options); - }, - update: function(position) { - Element.setOpacity(this.element, position); - } -}); - -Effect.MoveBy = Class.create(); -Object.extend(Object.extend(Effect.MoveBy.prototype, Effect.Base.prototype), { - initialize: function(element, toTop, toLeft) { - this.element = $(element); - this.toTop = toTop; - this.toLeft = toLeft; - this.start(arguments[3]); - }, - setup: function() { - // Bug in Opera: Opera returns the "real" position of a static element or - // relative element that does not have top/left explicitly set. - // ==> Always set top and left for position relative elements in your stylesheets - // (to 0 if you do not need them) - Element.makePositioned(this.element); - this.originalTop = parseFloat(Element.getStyle(this.element,'top') || '0'); - this.originalLeft = parseFloat(Element.getStyle(this.element,'left') || '0'); - }, - update: function(position) { - Element.setStyle(this.element, { - top: this.toTop * position + this.originalTop + 'px', - left: this.toLeft * position + this.originalLeft + 'px' - }); - } -}); - -Effect.Scale = Class.create(); -Object.extend(Object.extend(Effect.Scale.prototype, Effect.Base.prototype), { - initialize: function(element, percent) { - this.element = $(element) - 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 = Element.getStyle(this.element,'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 = Element.getStyle(this.element,'font-size') || '100%'; - ['em','px','%'].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) - Element.setStyle(this.element, {fontSize: this.fontSize * currentScale + this.fontSizeType }); - this.setDimensions(this.dims[0] * currentScale, this.dims[1] * currentScale); - }, - finish: function(position) { - if (this.restoreAfterFinish) Element.setStyle(this.element, this.originalStyle); - }, - setDimensions: function(height, width) { - var d = {}; - if(this.options.scaleX) d.width = width + 'px'; - if(this.options.scaleY) d.height = height + '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'; - } - } - Element.setStyle(this.element, d); - } -}); - -Effect.Highlight = Class.create(); -Object.extend(Object.extend(Effect.Highlight.prototype, Effect.Base.prototype), { - initialize: function(element) { - this.element = $(element); - var options = Object.extend({ startcolor: '#ffff99' }, arguments[1] || {}); - this.start(options); - }, - setup: function() { - // Prevent executing on elements not in the layout flow - if(Element.getStyle(this.element, 'display')=='none') { this.cancel(); return; } - // Disable background image during the effect - this.oldStyle = { - backgroundImage: Element.getStyle(this.element, 'background-image') }; - Element.setStyle(this.element, {backgroundImage: 'none'}); - if(!this.options.endcolor) - this.options.endcolor = Element.getStyle(this.element, 'background-color').parseColor('#ffffff'); - if(!this.options.restorecolor) - this.options.restorecolor = Element.getStyle(this.element, '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) { - Element.setStyle(this.element,{backgroundColor: $R(0,2).inject('#',function(m,v,i){ - return m+(Math.round(this._base[i]+(this._delta[i]*position)).toColorPart()); }.bind(this)) }); - }, - finish: function() { - Element.setStyle(this.element, Object.extend(this.oldStyle, { - backgroundColor: this.options.restorecolor - })); - } -}); - -Effect.ScrollTo = Class.create(); -Object.extend(Object.extend(Effect.ScrollTo.prototype, Effect.Base.prototype), { - initialize: function(element) { - this.element = $(element); - this.start(arguments[1] || {}); - }, - setup: function() { - Position.prepare(); - var offsets = Position.cumulativeOffset(this.element); - if(this.options.offset) offsets[1] += this.options.offset; - var max = window.innerHeight ? - window.height - window.innerHeight : - document.body.scrollHeight - - (document.documentElement.clientHeight ? - document.documentElement.clientHeight : document.body.clientHeight); - this.scrollStart = Position.deltaY; - this.delta = (offsets[1] > max ? max : offsets[1]) - this.scrollStart; - }, - update: function(position) { - Position.prepare(); - window.scrollTo(Position.deltaX, - this.scrollStart + (position*this.delta)); - } -}); - -/* ------------- combination effects ------------- */ - -Effect.Fade = function(element) { - var oldOpacity = Element.getInlineOpacity(element); - var options = Object.extend({ - from: Element.getOpacity(element) || 1.0, - to: 0.0, - afterFinishInternal: function(effect) { with(Element) { - if(effect.options.to!=0) return; - hide(effect.element); - setStyle(effect.element, {opacity: oldOpacity}); }} - }, arguments[1] || {}); - return new Effect.Opacity(element,options); -} - -Effect.Appear = function(element) { - var options = Object.extend({ - from: (Element.getStyle(element, 'display') == 'none' ? 0.0 : Element.getOpacity(element) || 0.0), - to: 1.0, - beforeSetup: function(effect) { with(Element) { - setOpacity(effect.element, effect.options.from); - show(effect.element); }} - }, arguments[1] || {}); - return new Effect.Opacity(element,options); -} - -Effect.Puff = function(element) { - element = $(element); - var oldStyle = { opacity: Element.getInlineOpacity(element), position: Element.getStyle(element, 'position') }; - 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) { with(Element) { - setStyle(effect.effects[0].element, {position: 'absolute'}); }}, - afterFinishInternal: function(effect) { with(Element) { - hide(effect.effects[0].element); - setStyle(effect.effects[0].element, oldStyle); }} - }, arguments[1] || {}) - ); -} - -Effect.BlindUp = function(element) { - element = $(element); - Element.makeClipping(element); - return new Effect.Scale(element, 0, - Object.extend({ scaleContent: false, - scaleX: false, - restoreAfterFinish: true, - afterFinishInternal: function(effect) { with(Element) { - [hide, undoClipping].call(effect.element); }} - }, arguments[1] || {}) - ); -} - -Effect.BlindDown = function(element) { - element = $(element); - var oldHeight = Element.getStyle(element, 'height'); - var elementDimensions = Element.getDimensions(element); - 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) { with(Element) { - makeClipping(effect.element); - setStyle(effect.element, {height: '0px'}); - show(effect.element); - }}, - afterFinishInternal: function(effect) { with(Element) { - undoClipping(effect.element); - setStyle(effect.element, {height: oldHeight}); - }} - }, arguments[1] || {}) - ); -} - -Effect.SwitchOff = function(element) { - element = $(element); - var oldOpacity = Element.getInlineOpacity(element); - return new Effect.Appear(element, { - 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) { with(Element) { - [makePositioned,makeClipping].call(effect.element); - }}, - afterFinishInternal: function(effect) { with(Element) { - [hide,undoClipping,undoPositioned].call(effect.element); - setStyle(effect.element, {opacity: oldOpacity}); - }} - }) - } - }); -} - -Effect.DropOut = function(element) { - element = $(element); - var oldStyle = { - top: Element.getStyle(element, 'top'), - left: Element.getStyle(element, 'left'), - opacity: Element.getInlineOpacity(element) }; - return new Effect.Parallel( - [ new Effect.MoveBy(element, 100, 0, { sync: true }), - new Effect.Opacity(element, { sync: true, to: 0.0 }) ], - Object.extend( - { duration: 0.5, - beforeSetup: function(effect) { with(Element) { - makePositioned(effect.effects[0].element); }}, - afterFinishInternal: function(effect) { with(Element) { - [hide, undoPositioned].call(effect.effects[0].element); - setStyle(effect.effects[0].element, oldStyle); }} - }, arguments[1] || {})); -} - -Effect.Shake = function(element) { - element = $(element); - var oldStyle = { - top: Element.getStyle(element, 'top'), - left: Element.getStyle(element, 'left') }; - return new Effect.MoveBy(element, 0, 20, - { duration: 0.05, afterFinishInternal: function(effect) { - new Effect.MoveBy(effect.element, 0, -40, - { duration: 0.1, afterFinishInternal: function(effect) { - new Effect.MoveBy(effect.element, 0, 40, - { duration: 0.1, afterFinishInternal: function(effect) { - new Effect.MoveBy(effect.element, 0, -40, - { duration: 0.1, afterFinishInternal: function(effect) { - new Effect.MoveBy(effect.element, 0, 40, - { duration: 0.1, afterFinishInternal: function(effect) { - new Effect.MoveBy(effect.element, 0, -20, - { duration: 0.05, afterFinishInternal: function(effect) { with(Element) { - undoPositioned(effect.element); - setStyle(effect.element, oldStyle); - }}}) }}) }}) }}) }}) }}); -} - -Effect.SlideDown = function(element) { - element = $(element); - Element.cleanWhitespace(element); - // SlideDown need to have the content of the element wrapped in a container element with fixed height! - var oldInnerBottom = Element.getStyle(element.firstChild, 'bottom'); - var elementDimensions = Element.getDimensions(element); - 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) { with(Element) { - makePositioned(effect.element); - makePositioned(effect.element.firstChild); - if(window.opera) setStyle(effect.element, {top: ''}); - makeClipping(effect.element); - setStyle(effect.element, {height: '0px'}); - show(element); }}, - afterUpdateInternal: function(effect) { with(Element) { - setStyle(effect.element.firstChild, {bottom: - (effect.dims[0] - effect.element.clientHeight) + 'px' }); }}, - afterFinishInternal: function(effect) { with(Element) { - undoClipping(effect.element); - undoPositioned(effect.element.firstChild); - undoPositioned(effect.element); - setStyle(effect.element.firstChild, {bottom: oldInnerBottom}); }} - }, arguments[1] || {}) - ); -} - -Effect.SlideUp = function(element) { - element = $(element); - Element.cleanWhitespace(element); - var oldInnerBottom = Element.getStyle(element.firstChild, 'bottom'); - return new Effect.Scale(element, 0, - Object.extend({ scaleContent: false, - scaleX: false, - scaleMode: 'box', - scaleFrom: 100, - restoreAfterFinish: true, - beforeStartInternal: function(effect) { with(Element) { - makePositioned(effect.element); - makePositioned(effect.element.firstChild); - if(window.opera) setStyle(effect.element, {top: ''}); - makeClipping(effect.element); - show(element); }}, - afterUpdateInternal: function(effect) { with(Element) { - setStyle(effect.element.firstChild, {bottom: - (effect.dims[0] - effect.element.clientHeight) + 'px' }); }}, - afterFinishInternal: function(effect) { with(Element) { - [hide, undoClipping].call(effect.element); - undoPositioned(effect.element.firstChild); - undoPositioned(effect.element); - setStyle(effect.element.firstChild, {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) { with(Element) { - makeClipping(effect.element); }}, - afterFinishInternal: function(effect) { with(Element) { - hide(effect.element); - undoClipping(effect.element); }} - }); -} - -Effect.Grow = function(element) { - element = $(element); - var options = Object.extend({ - direction: 'center', - moveTransistion: 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(element) }; - - var dims = Element.getDimensions(element); - 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.MoveBy(element, initialMoveY, initialMoveX, { - duration: 0.01, - beforeSetup: function(effect) { with(Element) { - hide(effect.element); - makeClipping(effect.element); - makePositioned(effect.element); - }}, - afterFinishInternal: function(effect) { - new Effect.Parallel( - [ new Effect.Opacity(effect.element, { sync: true, to: 1.0, from: 0.0, transition: options.opacityTransition }), - new Effect.MoveBy(effect.element, moveY, moveX, { 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) { with(Element) { - setStyle(effect.effects[0].element, {height: '0px'}); - show(effect.effects[0].element); }}, - afterFinishInternal: function(effect) { with(Element) { - [undoClipping, undoPositioned].call(effect.effects[0].element); - setStyle(effect.effects[0].element, oldStyle); }} - }, options) - ) - } - }); -} - -Effect.Shrink = function(element) { - element = $(element); - var options = Object.extend({ - direction: 'center', - moveTransistion: 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(element) }; - - var dims = Element.getDimensions(element); - 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.MoveBy(element, moveY, moveX, { sync: true, transition: options.moveTransition }) - ], Object.extend({ - beforeStartInternal: function(effect) { with(Element) { - [makePositioned, makeClipping].call(effect.effects[0].element) }}, - afterFinishInternal: function(effect) { with(Element) { - [hide, undoClipping, undoPositioned].call(effect.effects[0].element); - setStyle(effect.effects[0].element, oldStyle); }} - }, options) - ); -} - -Effect.Pulsate = function(element) { - element = $(element); - var options = arguments[1] || {}; - var oldOpacity = Element.getInlineOpacity(element); - var transition = options.transition || Effect.Transitions.sinoidal; - var reverser = function(pos){ return transition(1-Effect.Transitions.pulse(pos)) }; - reverser.bind(transition); - return new Effect.Opacity(element, - Object.extend(Object.extend({ duration: 3.0, from: 0, - afterFinishInternal: function(effect) { Element.setStyle(effect.element, {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(element); - 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) { with(Element) { - [hide, undoClipping].call(effect.element); - setStyle(effect.element, oldStyle); - }} }); - }}, arguments[1] || {})); -} diff --git a/tracks/vendor/rails/railties/html/javascripts/prototype.js b/tracks/vendor/rails/railties/html/javascripts/prototype.js deleted file mode 100644 index e9ccd3c8..00000000 --- a/tracks/vendor/rails/railties/html/javascripts/prototype.js +++ /dev/null @@ -1,1785 +0,0 @@ -/* Prototype JavaScript framework, version 1.4.0 - * (c) 2005 Sam Stephenson - * - * THIS FILE IS AUTOMATICALLY GENERATED. When sending patches, please diff - * against the source tree, available from the Prototype darcs repository. - * - * Prototype is freely distributable under the terms of an MIT-style license. - * - * For details, see the Prototype web site: http://prototype.conio.net/ - * -/*--------------------------------------------------------------------------*/ - -var Prototype = { - Version: '1.4.0', - ScriptFragment: '(?:)((\n|\r|.)*?)(?:<\/script>)', - - emptyFunction: function() {}, - K: function(x) {return x} -} - -var Class = { - create: function() { - return function() { - this.initialize.apply(this, arguments); - } - } -} - -var Abstract = new Object(); - -Object.extend = function(destination, source) { - for (property in source) { - destination[property] = source[property]; - } - return destination; -} - -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; - } -} - -Function.prototype.bind = function() { - var __method = this, args = $A(arguments), object = args.shift(); - return function() { - return __method.apply(object, args.concat($A(arguments))); - } -} - -Function.prototype.bindAsEventListener = function(object) { - var __method = this; - return function(event) { - return __method.call(object, event || window.event); - } -} - -Object.extend(Number.prototype, { - toColorPart: function() { - var digits = this.toString(16); - if (this < 16) return '0' + digits; - return digits; - }, - - succ: function() { - return this + 1; - }, - - times: function(iterator) { - $R(0, this, true).each(iterator); - return this; - } -}); - -var Try = { - these: function() { - var returnValue; - - for (var i = 0; i < arguments.length; i++) { - var lambda = arguments[i]; - try { - returnValue = lambda(); - break; - } catch (e) {} - } - - return returnValue; - } -} - -/*--------------------------------------------------------------------------*/ - -var PeriodicalExecuter = Class.create(); -PeriodicalExecuter.prototype = { - initialize: function(callback, frequency) { - this.callback = callback; - this.frequency = frequency; - this.currentlyExecuting = false; - - this.registerCallback(); - }, - - registerCallback: function() { - setInterval(this.onTimerEvent.bind(this), this.frequency * 1000); - }, - - onTimerEvent: function() { - if (!this.currentlyExecuting) { - try { - this.currentlyExecuting = true; - this.callback(); - } finally { - this.currentlyExecuting = false; - } - } - } -} - -/*--------------------------------------------------------------------------*/ - -function $() { - var elements = new Array(); - - for (var i = 0; i < arguments.length; i++) { - var element = arguments[i]; - if (typeof element == 'string') - element = document.getElementById(element); - - if (arguments.length == 1) - return element; - - elements.push(element); - } - - return elements; -} -Object.extend(String.prototype, { - 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(eval); - }, - - escapeHTML: function() { - var div = document.createElement('div'); - var text = document.createTextNode(this); - div.appendChild(text); - return div.innerHTML; - }, - - unescapeHTML: function() { - var div = document.createElement('div'); - div.innerHTML = this.stripTags(); - return div.childNodes[0] ? div.childNodes[0].nodeValue : ''; - }, - - toQueryParams: function() { - var pairs = this.match(/^\??(.*)$/)[1].split('&'); - return pairs.inject({}, function(params, pairString) { - var pair = pairString.split('='); - params[pair[0]] = pair[1]; - return params; - }); - }, - - toArray: function() { - return this.split(''); - }, - - camelize: function() { - var oStringList = this.split('-'); - if (oStringList.length == 1) return oStringList[0]; - - var camelizedString = this.indexOf('-') == 0 - ? oStringList[0].charAt(0).toUpperCase() + oStringList[0].substring(1) - : oStringList[0]; - - for (var i = 1, len = oStringList.length; i < len; i++) { - var s = oStringList[i]; - camelizedString += s.charAt(0).toUpperCase() + s.substring(1); - } - - return camelizedString; - }, - - inspect: function() { - return "'" + this.replace('\\', '\\\\').replace("'", '\\\'') + "'"; - } -}); - -String.prototype.parseQuery = String.prototype.toQueryParams; - -var $break = new Object(); -var $continue = new Object(); - -var Enumerable = { - each: function(iterator) { - var index = 0; - try { - this._each(function(value) { - try { - iterator(value, index++); - } catch (e) { - if (e != $continue) throw e; - } - }); - } catch (e) { - if (e != $break) throw e; - } - }, - - all: function(iterator) { - var result = true; - this.each(function(value, index) { - result = result && !!(iterator || Prototype.K)(value, index); - if (!result) throw $break; - }); - return result; - }, - - any: function(iterator) { - var result = true; - this.each(function(value, index) { - if (result = !!(iterator || Prototype.K)(value, index)) - throw $break; - }); - return result; - }, - - collect: function(iterator) { - var results = []; - this.each(function(value, index) { - results.push(iterator(value, index)); - }); - return results; - }, - - detect: function (iterator) { - var result; - this.each(function(value, index) { - if (iterator(value, index)) { - result = value; - throw $break; - } - }); - return result; - }, - - findAll: function(iterator) { - var results = []; - this.each(function(value, index) { - if (iterator(value, index)) - results.push(value); - }); - return results; - }, - - grep: function(pattern, iterator) { - var results = []; - this.each(function(value, index) { - var stringValue = value.toString(); - if (stringValue.match(pattern)) - results.push((iterator || Prototype.K)(value, index)); - }) - return results; - }, - - include: function(object) { - var found = false; - this.each(function(value) { - if (value == object) { - found = true; - throw $break; - } - }); - return found; - }, - - inject: function(memo, iterator) { - this.each(function(value, index) { - memo = iterator(memo, value, index); - }); - return memo; - }, - - invoke: function(method) { - var args = $A(arguments).slice(1); - return this.collect(function(value) { - return value[method].apply(value, args); - }); - }, - - max: function(iterator) { - var result; - this.each(function(value, index) { - value = (iterator || Prototype.K)(value, index); - if (value >= (result || value)) - result = value; - }); - return result; - }, - - min: function(iterator) { - var result; - this.each(function(value, index) { - value = (iterator || Prototype.K)(value, index); - if (value <= (result || value)) - result = value; - }); - return result; - }, - - partition: function(iterator) { - var trues = [], falses = []; - this.each(function(value, index) { - ((iterator || Prototype.K)(value, index) ? - trues : falses).push(value); - }); - return [trues, falses]; - }, - - pluck: function(property) { - var results = []; - this.each(function(value, index) { - results.push(value[property]); - }); - return results; - }, - - reject: function(iterator) { - var results = []; - this.each(function(value, index) { - if (!iterator(value, index)) - results.push(value); - }); - return results; - }, - - sortBy: function(iterator) { - return this.collect(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.collect(Prototype.K); - }, - - zip: function() { - var iterator = Prototype.K, args = $A(arguments); - if (typeof args.last() == 'function') - iterator = args.pop(); - - var collections = [this].concat(args).map($A); - return this.map(function(value, index) { - iterator(value = collections.pluck(index)); - return value; - }); - }, - - inspect: function() { - return '#'; - } -} - -Object.extend(Enumerable, { - map: Enumerable.collect, - find: Enumerable.detect, - select: Enumerable.findAll, - member: Enumerable.include, - entries: Enumerable.toArray -}); -var $A = Array.from = function(iterable) { - if (!iterable) return []; - if (iterable.toArray) { - return iterable.toArray(); - } else { - var results = []; - for (var i = 0; i < iterable.length; i++) - results.push(iterable[i]); - return results; - } -} - -Object.extend(Array.prototype, Enumerable); - -Array.prototype._reverse = Array.prototype.reverse; - -Object.extend(Array.prototype, { - _each: function(iterator) { - for (var i = 0; i < this.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 != undefined || value != null; - }); - }, - - flatten: function() { - return this.inject([], function(array, value) { - return array.concat(value.constructor == Array ? - value.flatten() : [value]); - }); - }, - - without: function() { - var values = $A(arguments); - return this.select(function(value) { - return !values.include(value); - }); - }, - - indexOf: function(object) { - for (var i = 0; i < this.length; i++) - if (this[i] == object) return i; - return -1; - }, - - reverse: function(inline) { - return (inline !== false ? this : this.toArray())._reverse(); - }, - - shift: function() { - var result = this[0]; - for (var i = 0; i < this.length - 1; i++) - this[i] = this[i + 1]; - this.length--; - return result; - }, - - inspect: function() { - return '[' + this.map(Object.inspect).join(', ') + ']'; - } -}); -var Hash = { - _each: function(iterator) { - for (key in this) { - var value = this[key]; - if (typeof value == 'function') 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'); - }, - - merge: function(hash) { - return $H(hash).inject($H(this), function(mergedHash, pair) { - mergedHash[pair.key] = pair.value; - return mergedHash; - }); - }, - - toQueryString: function() { - return this.map(function(pair) { - return pair.map(encodeURIComponent).join('='); - }).join('&'); - }, - - inspect: function() { - return '#'; - } -} - -function $H(object) { - var hash = Object.extend({}, object || {}); - Object.extend(hash, Enumerable); - Object.extend(hash, Hash); - return hash; -} -ObjectRange = Class.create(); -Object.extend(ObjectRange.prototype, Enumerable); -Object.extend(ObjectRange.prototype, { - initialize: function(start, end, exclusive) { - this.start = start; - this.end = end; - this.exclusive = exclusive; - }, - - _each: function(iterator) { - var value = this.start; - do { - iterator(value); - value = value.succ(); - } while (this.include(value)); - }, - - 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 ActiveXObject('Msxml2.XMLHTTP')}, - function() {return new ActiveXObject('Microsoft.XMLHTTP')}, - function() {return new XMLHttpRequest()} - ) || false; - }, - - activeRequestCount: 0 -} - -Ajax.Responders = { - responders: [], - - _each: function(iterator) { - this.responders._each(iterator); - }, - - register: function(responderToAdd) { - if (!this.include(responderToAdd)) - this.responders.push(responderToAdd); - }, - - unregister: function(responderToRemove) { - this.responders = this.responders.without(responderToRemove); - }, - - dispatch: function(callback, request, transport, json) { - this.each(function(responder) { - if (responder[callback] && typeof responder[callback] == 'function') { - 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 = function() {}; -Ajax.Base.prototype = { - setOptions: function(options) { - this.options = { - method: 'post', - asynchronous: true, - parameters: '' - } - Object.extend(this.options, options || {}); - }, - - responseIsSuccess: function() { - return this.transport.status == undefined - || this.transport.status == 0 - || (this.transport.status >= 200 && this.transport.status < 300); - }, - - responseIsFailure: function() { - return !this.responseIsSuccess(); - } -} - -Ajax.Request = Class.create(); -Ajax.Request.Events = - ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete']; - -Ajax.Request.prototype = Object.extend(new Ajax.Base(), { - initialize: function(url, options) { - this.transport = Ajax.getTransport(); - this.setOptions(options); - this.request(url); - }, - - request: function(url) { - var parameters = this.options.parameters || ''; - if (parameters.length > 0) parameters += '&_='; - - try { - this.url = url; - if (this.options.method == 'get' && parameters.length > 0) - this.url += (this.url.match(/\?/) ? '&' : '?') + parameters; - - Ajax.Responders.dispatch('onCreate', this, this.transport); - - this.transport.open(this.options.method, this.url, - this.options.asynchronous); - - if (this.options.asynchronous) { - this.transport.onreadystatechange = this.onStateChange.bind(this); - setTimeout((function() {this.respondToReadyState(1)}).bind(this), 10); - } - - this.setRequestHeaders(); - - var body = this.options.postBody ? this.options.postBody : parameters; - this.transport.send(this.options.method == 'post' ? body : null); - - } catch (e) { - this.dispatchException(e); - } - }, - - setRequestHeaders: function() { - var requestHeaders = - ['X-Requested-With', 'XMLHttpRequest', - 'X-Prototype-Version', Prototype.Version]; - - if (this.options.method == 'post') { - requestHeaders.push('Content-type', - 'application/x-www-form-urlencoded'); - - /* Force "Connection: close" for Mozilla browsers to work around - * a bug where XMLHttpReqeuest sends an incorrect Content-length - * header. See Mozilla Bugzilla #246651. - */ - if (this.transport.overrideMimeType) - requestHeaders.push('Connection', 'close'); - } - - if (this.options.requestHeaders) - requestHeaders.push.apply(requestHeaders, this.options.requestHeaders); - - for (var i = 0; i < requestHeaders.length; i += 2) - this.transport.setRequestHeader(requestHeaders[i], requestHeaders[i+1]); - }, - - onStateChange: function() { - var readyState = this.transport.readyState; - if (readyState != 1) - this.respondToReadyState(this.transport.readyState); - }, - - header: function(name) { - try { - return this.transport.getResponseHeader(name); - } catch (e) {} - }, - - evalJSON: function() { - try { - return eval(this.header('X-JSON')); - } catch (e) {} - }, - - evalResponse: function() { - try { - return eval(this.transport.responseText); - } catch (e) { - this.dispatchException(e); - } - }, - - respondToReadyState: function(readyState) { - var event = Ajax.Request.Events[readyState]; - var transport = this.transport, json = this.evalJSON(); - - if (event == 'Complete') { - try { - (this.options['on' + this.transport.status] - || this.options['on' + (this.responseIsSuccess() ? 'Success' : 'Failure')] - || Prototype.emptyFunction)(transport, json); - } catch (e) { - this.dispatchException(e); - } - - if ((this.header('Content-type') || '').match(/^text\/javascript/i)) - this.evalResponse(); - } - - try { - (this.options['on' + event] || Prototype.emptyFunction)(transport, json); - Ajax.Responders.dispatch('on' + event, this, transport, json); - } catch (e) { - this.dispatchException(e); - } - - /* Avoid memory leak in MSIE: clean up the oncomplete event handler */ - if (event == 'Complete') - this.transport.onreadystatechange = Prototype.emptyFunction; - }, - - dispatchException: function(exception) { - (this.options.onException || Prototype.emptyFunction)(this, exception); - Ajax.Responders.dispatch('onException', this, exception); - } -}); - -Ajax.Updater = Class.create(); - -Object.extend(Object.extend(Ajax.Updater.prototype, Ajax.Request.prototype), { - initialize: function(container, url, options) { - this.containers = { - success: container.success ? $(container.success) : $(container), - failure: container.failure ? $(container.failure) : - (container.success ? null : $(container)) - } - - this.transport = Ajax.getTransport(); - this.setOptions(options); - - var onComplete = this.options.onComplete || Prototype.emptyFunction; - this.options.onComplete = (function(transport, object) { - this.updateContent(); - onComplete(transport, object); - }).bind(this); - - this.request(url); - }, - - updateContent: function() { - var receiver = this.responseIsSuccess() ? - this.containers.success : this.containers.failure; - var response = this.transport.responseText; - - if (!this.options.evalScripts) - response = response.stripScripts(); - - if (receiver) { - if (this.options.insertion) { - new this.options.insertion(receiver, response); - } else { - Element.update(receiver, response); - } - } - - if (this.responseIsSuccess()) { - if (this.onComplete) - setTimeout(this.onComplete.bind(this), 10); - } - } -}); - -Ajax.PeriodicalUpdater = Class.create(); -Ajax.PeriodicalUpdater.prototype = Object.extend(new Ajax.Base(), { - initialize: function(container, url, options) { - this.setOptions(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.onComplete = undefined; - clearTimeout(this.timer); - (this.onComplete || Prototype.emptyFunction).apply(this, arguments); - }, - - updateComplete: function(request) { - if (this.options.decay) { - this.decay = (request.responseText == this.lastText ? - this.decay * this.options.decay : 1); - - this.lastText = request.responseText; - } - this.timer = setTimeout(this.onTimerEvent.bind(this), - this.decay * this.frequency * 1000); - }, - - onTimerEvent: function() { - this.updater = new Ajax.Updater(this.container, this.url, this.options); - } -}); -document.getElementsByClassName = function(className, parentElement) { - var children = ($(parentElement) || document.body).getElementsByTagName('*'); - return $A(children).inject([], function(elements, child) { - if (child.className.match(new RegExp("(^|\\s)" + className + "(\\s|$)"))) - elements.push(child); - return elements; - }); -} - -/*--------------------------------------------------------------------------*/ - -if (!window.Element) { - var Element = new Object(); -} - -Object.extend(Element, { - visible: function(element) { - return $(element).style.display != 'none'; - }, - - toggle: function() { - for (var i = 0; i < arguments.length; i++) { - var element = $(arguments[i]); - Element[Element.visible(element) ? 'hide' : 'show'](element); - } - }, - - hide: function() { - for (var i = 0; i < arguments.length; i++) { - var element = $(arguments[i]); - element.style.display = 'none'; - } - }, - - show: function() { - for (var i = 0; i < arguments.length; i++) { - var element = $(arguments[i]); - element.style.display = ''; - } - }, - - remove: function(element) { - element = $(element); - element.parentNode.removeChild(element); - }, - - update: function(element, html) { - $(element).innerHTML = html.stripScripts(); - setTimeout(function() {html.evalScripts()}, 10); - }, - - getHeight: function(element) { - element = $(element); - return element.offsetHeight; - }, - - classNames: function(element) { - return new Element.ClassNames(element); - }, - - hasClassName: function(element, className) { - if (!(element = $(element))) return; - return Element.classNames(element).include(className); - }, - - addClassName: function(element, className) { - if (!(element = $(element))) return; - return Element.classNames(element).add(className); - }, - - removeClassName: function(element, className) { - if (!(element = $(element))) return; - return Element.classNames(element).remove(className); - }, - - // removes whitespace-only text node children - cleanWhitespace: function(element) { - element = $(element); - for (var i = 0; i < element.childNodes.length; i++) { - var node = element.childNodes[i]; - if (node.nodeType == 3 && !/\S/.test(node.nodeValue)) - Element.remove(node); - } - }, - - empty: function(element) { - return $(element).innerHTML.match(/^\s*$/); - }, - - scrollTo: function(element) { - element = $(element); - var x = element.x ? element.x : element.offsetLeft, - y = element.y ? element.y : element.offsetTop; - window.scrollTo(x, y); - }, - - getStyle: function(element, style) { - element = $(element); - var value = element.style[style.camelize()]; - if (!value) { - if (document.defaultView && document.defaultView.getComputedStyle) { - var css = document.defaultView.getComputedStyle(element, null); - value = css ? css.getPropertyValue(style) : null; - } else if (element.currentStyle) { - value = element.currentStyle[style.camelize()]; - } - } - - if (window.opera && ['left', 'top', 'right', 'bottom'].include(style)) - if (Element.getStyle(element, 'position') == 'static') value = 'auto'; - - return value == 'auto' ? null : value; - }, - - setStyle: function(element, style) { - element = $(element); - for (name in style) - element.style[name.camelize()] = style[name]; - }, - - getDimensions: function(element) { - element = $(element); - if (Element.getStyle(element, 'display') != 'none') - 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; - els.visibility = 'hidden'; - els.position = 'absolute'; - els.display = ''; - var originalWidth = element.clientWidth; - var originalHeight = element.clientHeight; - els.display = 'none'; - 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; - } - } - }, - - 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 = ''; - } - }, - - makeClipping: function(element) { - element = $(element); - if (element._overflow) return; - element._overflow = element.style.overflow; - if ((Element.getStyle(element, 'overflow') || 'visible') != 'hidden') - element.style.overflow = 'hidden'; - }, - - undoClipping: function(element) { - element = $(element); - if (element._overflow) return; - element.style.overflow = element._overflow; - element._overflow = undefined; - } -}); - -var Toggle = new Object(); -Toggle.display = Element.toggle; - -/*--------------------------------------------------------------------------*/ - -Abstract.Insertion = function(adjacency) { - this.adjacency = adjacency; -} - -Abstract.Insertion.prototype = { - initialize: function(element, content) { - this.element = $(element); - this.content = content.stripScripts(); - - if (this.adjacency && this.element.insertAdjacentHTML) { - try { - this.element.insertAdjacentHTML(this.adjacency, this.content); - } catch (e) { - if (this.element.tagName.toLowerCase() == 'tbody') { - this.insertContent(this.contentFromAnonymousTable()); - } else { - throw e; - } - } - } else { - this.range = this.element.ownerDocument.createRange(); - if (this.initializeRange) this.initializeRange(); - this.insertContent([this.range.createContextualFragment(this.content)]); - } - - setTimeout(function() {content.evalScripts()}, 10); - }, - - contentFromAnonymousTable: function() { - var div = document.createElement('div'); - div.innerHTML = '' + this.content + '
    '; - return $A(div.childNodes[0].childNodes[0].childNodes); - } -} - -var Insertion = new Object(); - -Insertion.Before = Class.create(); -Insertion.Before.prototype = Object.extend(new Abstract.Insertion('beforeBegin'), { - initializeRange: function() { - this.range.setStartBefore(this.element); - }, - - insertContent: function(fragments) { - fragments.each((function(fragment) { - this.element.parentNode.insertBefore(fragment, this.element); - }).bind(this)); - } -}); - -Insertion.Top = Class.create(); -Insertion.Top.prototype = Object.extend(new Abstract.Insertion('afterBegin'), { - initializeRange: function() { - this.range.selectNodeContents(this.element); - this.range.collapse(true); - }, - - insertContent: function(fragments) { - fragments.reverse(false).each((function(fragment) { - this.element.insertBefore(fragment, this.element.firstChild); - }).bind(this)); - } -}); - -Insertion.Bottom = Class.create(); -Insertion.Bottom.prototype = Object.extend(new Abstract.Insertion('beforeEnd'), { - initializeRange: function() { - this.range.selectNodeContents(this.element); - this.range.collapse(this.element); - }, - - insertContent: function(fragments) { - fragments.each((function(fragment) { - this.element.appendChild(fragment); - }).bind(this)); - } -}); - -Insertion.After = Class.create(); -Insertion.After.prototype = Object.extend(new Abstract.Insertion('afterEnd'), { - initializeRange: function() { - this.range.setStartAfter(this.element); - }, - - insertContent: function(fragments) { - fragments.each((function(fragment) { - this.element.parentNode.insertBefore(fragment, - this.element.nextSibling); - }).bind(this)); - } -}); - -/*--------------------------------------------------------------------------*/ - -Element.ClassNames = Class.create(); -Element.ClassNames.prototype = { - initialize: function(element) { - this.element = $(element); - }, - - _each: function(iterator) { - this.element.className.split(/\s+/).select(function(name) { - return name.length > 0; - })._each(iterator); - }, - - set: function(className) { - this.element.className = className; - }, - - add: function(classNameToAdd) { - if (this.include(classNameToAdd)) return; - this.set(this.toArray().concat(classNameToAdd).join(' ')); - }, - - remove: function(classNameToRemove) { - if (!this.include(classNameToRemove)) return; - this.set(this.select(function(className) { - return className != classNameToRemove; - }).join(' ')); - }, - - toString: function() { - return this.toArray().join(' '); - } -} - -Object.extend(Element.ClassNames.prototype, Enumerable); -var Field = { - clear: function() { - for (var i = 0; i < arguments.length; i++) - $(arguments[i]).value = ''; - }, - - focus: function(element) { - $(element).focus(); - }, - - present: function() { - for (var i = 0; i < arguments.length; i++) - if ($(arguments[i]).value == '') return false; - return true; - }, - - select: function(element) { - $(element).select(); - }, - - activate: function(element) { - element = $(element); - element.focus(); - if (element.select) - element.select(); - } -} - -/*--------------------------------------------------------------------------*/ - -var Form = { - serialize: function(form) { - var elements = Form.getElements($(form)); - var queryComponents = new Array(); - - for (var i = 0; i < elements.length; i++) { - var queryComponent = Form.Element.serialize(elements[i]); - if (queryComponent) - queryComponents.push(queryComponent); - } - - return queryComponents.join('&'); - }, - - getElements: function(form) { - form = $(form); - var elements = new Array(); - - for (tagName in Form.Element.Serializers) { - var tagElements = form.getElementsByTagName(tagName); - for (var j = 0; j < tagElements.length; j++) - elements.push(tagElements[j]); - } - return elements; - }, - - getInputs: function(form, typeName, name) { - form = $(form); - var inputs = form.getElementsByTagName('input'); - - if (!typeName && !name) - return inputs; - - var matchingInputs = new Array(); - for (var i = 0; i < inputs.length; i++) { - var input = inputs[i]; - if ((typeName && input.type != typeName) || - (name && input.name != name)) - continue; - matchingInputs.push(input); - } - - return matchingInputs; - }, - - disable: function(form) { - var elements = Form.getElements(form); - for (var i = 0; i < elements.length; i++) { - var element = elements[i]; - element.blur(); - element.disabled = 'true'; - } - }, - - enable: function(form) { - var elements = Form.getElements(form); - for (var i = 0; i < elements.length; i++) { - var element = elements[i]; - element.disabled = ''; - } - }, - - findFirstElement: function(form) { - return Form.getElements(form).find(function(element) { - return element.type != 'hidden' && !element.disabled && - ['input', 'select', 'textarea'].include(element.tagName.toLowerCase()); - }); - }, - - focusFirstElement: function(form) { - Field.activate(Form.findFirstElement(form)); - }, - - reset: function(form) { - $(form).reset(); - } -} - -Form.Element = { - serialize: function(element) { - element = $(element); - var method = element.tagName.toLowerCase(); - var parameter = Form.Element.Serializers[method](element); - - if (parameter) { - var key = encodeURIComponent(parameter[0]); - if (key.length == 0) return; - - if (parameter[1].constructor != Array) - parameter[1] = [parameter[1]]; - - return parameter[1].map(function(value) { - return key + '=' + encodeURIComponent(value); - }).join('&'); - } - }, - - getValue: function(element) { - element = $(element); - var method = element.tagName.toLowerCase(); - var parameter = Form.Element.Serializers[method](element); - - if (parameter) - return parameter[1]; - } -} - -Form.Element.Serializers = { - input: function(element) { - switch (element.type.toLowerCase()) { - case 'submit': - case 'hidden': - case 'password': - case 'text': - return Form.Element.Serializers.textarea(element); - case 'checkbox': - case 'radio': - return Form.Element.Serializers.inputSelector(element); - } - return false; - }, - - inputSelector: function(element) { - if (element.checked) - return [element.name, element.value]; - }, - - textarea: function(element) { - return [element.name, element.value]; - }, - - select: function(element) { - return Form.Element.Serializers[element.type == 'select-one' ? - 'selectOne' : 'selectMany'](element); - }, - - selectOne: function(element) { - var value = '', opt, index = element.selectedIndex; - if (index >= 0) { - opt = element.options[index]; - value = opt.value; - if (!value && !('value' in opt)) - value = opt.text; - } - return [element.name, value]; - }, - - selectMany: function(element) { - var value = new Array(); - for (var i = 0; i < element.length; i++) { - var opt = element.options[i]; - if (opt.selected) { - var optValue = opt.value; - if (!optValue && !('value' in opt)) - optValue = opt.text; - value.push(optValue); - } - } - return [element.name, value]; - } -} - -/*--------------------------------------------------------------------------*/ - -var $F = Form.Element.getValue; - -/*--------------------------------------------------------------------------*/ - -Abstract.TimedObserver = function() {} -Abstract.TimedObserver.prototype = { - initialize: function(element, frequency, callback) { - this.frequency = frequency; - this.element = $(element); - this.callback = callback; - - this.lastValue = this.getValue(); - this.registerCallback(); - }, - - registerCallback: function() { - setInterval(this.onTimerEvent.bind(this), this.frequency * 1000); - }, - - onTimerEvent: function() { - var value = this.getValue(); - if (this.lastValue != value) { - this.callback(this.element, value); - this.lastValue = value; - } - } -} - -Form.Element.Observer = Class.create(); -Form.Element.Observer.prototype = Object.extend(new Abstract.TimedObserver(), { - getValue: function() { - return Form.Element.getValue(this.element); - } -}); - -Form.Observer = Class.create(); -Form.Observer.prototype = Object.extend(new Abstract.TimedObserver(), { - getValue: function() { - return Form.serialize(this.element); - } -}); - -/*--------------------------------------------------------------------------*/ - -Abstract.EventObserver = function() {} -Abstract.EventObserver.prototype = { - 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() { - var elements = Form.getElements(this.element); - for (var i = 0; i < elements.length; i++) - this.registerCallback(elements[i]); - }, - - registerCallback: function(element) { - if (element.type) { - switch (element.type.toLowerCase()) { - case 'checkbox': - case 'radio': - Event.observe(element, 'click', this.onElementEvent.bind(this)); - break; - case 'password': - case 'text': - case 'textarea': - case 'select-one': - case 'select-multiple': - Event.observe(element, 'change', this.onElementEvent.bind(this)); - break; - } - } - } -} - -Form.Element.EventObserver = Class.create(); -Form.Element.EventObserver.prototype = Object.extend(new Abstract.EventObserver(), { - getValue: function() { - return Form.Element.getValue(this.element); - } -}); - -Form.EventObserver = Class.create(); -Form.EventObserver.prototype = Object.extend(new Abstract.EventObserver(), { - getValue: function() { - return Form.serialize(this.element); - } -}); -if (!window.Event) { - var Event = new Object(); -} - -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, - - element: function(event) { - return event.target || event.srcElement; - }, - - isLeftClick: function(event) { - return (((event.which) && (event.which == 1)) || - ((event.button) && (event.button == 1))); - }, - - pointerX: function(event) { - return event.pageX || (event.clientX + - (document.documentElement.scrollLeft || document.body.scrollLeft)); - }, - - pointerY: function(event) { - return event.pageY || (event.clientY + - (document.documentElement.scrollTop || document.body.scrollTop)); - }, - - stop: function(event) { - if (event.preventDefault) { - event.preventDefault(); - event.stopPropagation(); - } else { - event.returnValue = false; - event.cancelBubble = true; - } - }, - - // find the first node with the given tagName, starting from the - // node the event was triggered on; traverses the DOM upwards - findElement: function(event, tagName) { - var element = Event.element(event); - while (element.parentNode && (!element.tagName || - (element.tagName.toUpperCase() != tagName.toUpperCase()))) - element = element.parentNode; - return element; - }, - - observers: false, - - _observeAndCache: function(element, name, observer, useCapture) { - if (!this.observers) this.observers = []; - if (element.addEventListener) { - this.observers.push([element, name, observer, useCapture]); - element.addEventListener(name, observer, useCapture); - } else if (element.attachEvent) { - this.observers.push([element, name, observer, useCapture]); - element.attachEvent('on' + name, observer); - } - }, - - unloadCache: function() { - if (!Event.observers) return; - for (var i = 0; i < Event.observers.length; i++) { - Event.stopObserving.apply(this, Event.observers[i]); - Event.observers[i][0] = null; - } - Event.observers = false; - }, - - observe: function(element, name, observer, useCapture) { - var element = $(element); - useCapture = useCapture || false; - - if (name == 'keypress' && - (navigator.appVersion.match(/Konqueror|Safari|KHTML/) - || element.attachEvent)) - name = 'keydown'; - - this._observeAndCache(element, name, observer, useCapture); - }, - - stopObserving: function(element, name, observer, useCapture) { - var element = $(element); - useCapture = useCapture || false; - - if (name == 'keypress' && - (navigator.appVersion.match(/Konqueror|Safari|KHTML/) - || element.detachEvent)) - name = 'keydown'; - - if (element.removeEventListener) { - element.removeEventListener(name, observer, useCapture); - } else if (element.detachEvent) { - element.detachEvent('on' + name, observer); - } - } -}); - -/* prevent memory leaks in IE */ -Event.observe(window, 'unload', Event.unloadCache, false); -var Position = { - // set to true if needed, warning: firefox performance problems - // NOT neeeded for page scrolling, only if draggable contained in - // scrollable elements - includeScrollOffsets: false, - - // must be called before calling withinIncludingScrolloffset, every time the - // page is scrolled - prepare: function() { - this.deltaX = window.pageXOffset - || document.documentElement.scrollLeft - || document.body.scrollLeft - || 0; - this.deltaY = window.pageYOffset - || document.documentElement.scrollTop - || document.body.scrollTop - || 0; - }, - - realOffset: function(element) { - var valueT = 0, valueL = 0; - do { - valueT += element.scrollTop || 0; - valueL += element.scrollLeft || 0; - element = element.parentNode; - } while (element); - return [valueL, valueT]; - }, - - cumulativeOffset: function(element) { - var valueT = 0, valueL = 0; - do { - valueT += element.offsetTop || 0; - valueL += element.offsetLeft || 0; - element = element.offsetParent; - } while (element); - return [valueL, valueT]; - }, - - positionedOffset: function(element) { - var valueT = 0, valueL = 0; - do { - valueT += element.offsetTop || 0; - valueL += element.offsetLeft || 0; - element = element.offsetParent; - if (element) { - p = Element.getStyle(element, 'position'); - if (p == 'relative' || p == 'absolute') break; - } - } while (element); - return [valueL, valueT]; - }, - - offsetParent: 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; - }, - - // caches x/y coordinate pair to use with overlap - within: function(element, x, y) { - if (this.includeScrollOffsets) - return this.withinIncludingScrolloffsets(element, x, y); - this.xcomp = x; - this.ycomp = y; - this.offset = this.cumulativeOffset(element); - - return (y >= this.offset[1] && - y < this.offset[1] + element.offsetHeight && - x >= this.offset[0] && - x < this.offset[0] + element.offsetWidth); - }, - - withinIncludingScrolloffsets: function(element, x, y) { - var offsetcache = this.realOffset(element); - - this.xcomp = x + offsetcache[0] - this.deltaX; - this.ycomp = y + offsetcache[1] - this.deltaY; - this.offset = this.cumulativeOffset(element); - - return (this.ycomp >= this.offset[1] && - this.ycomp < this.offset[1] + element.offsetHeight && - this.xcomp >= this.offset[0] && - this.xcomp < this.offset[0] + element.offsetWidth); - }, - - // within must be called directly before - overlap: function(mode, element) { - if (!mode) return 0; - if (mode == 'vertical') - return ((this.offset[1] + element.offsetHeight) - this.ycomp) / - element.offsetHeight; - if (mode == 'horizontal') - return ((this.offset[0] + element.offsetWidth) - this.xcomp) / - element.offsetWidth; - }, - - clone: function(source, target) { - source = $(source); - target = $(target); - target.style.position = 'absolute'; - var offsets = this.cumulativeOffset(source); - target.style.top = offsets[1] + 'px'; - target.style.left = offsets[0] + 'px'; - target.style.width = source.offsetWidth + 'px'; - target.style.height = source.offsetHeight + 'px'; - }, - - page: 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) - if (Element.getStyle(element,'position')=='absolute') break; - - } while (element = element.offsetParent); - - element = forElement; - do { - valueT -= element.scrollTop || 0; - valueL -= element.scrollLeft || 0; - } while (element = element.parentNode); - - return [valueL, valueT]; - }, - - clone: function(source, target) { - 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 = Position.page(source); - - // find coordinate system to use - target = $(target); - 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(target,'position') == 'absolute') { - parent = Position.offsetParent(target); - delta = Position.page(parent); - } - - // 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) target.style.left = (p[0] - delta[0] + options.offsetLeft) + 'px'; - if(options.setTop) target.style.top = (p[1] - delta[1] + options.offsetTop) + 'px'; - if(options.setWidth) target.style.width = source.offsetWidth + 'px'; - if(options.setHeight) target.style.height = source.offsetHeight + 'px'; - }, - - absolutize: function(element) { - element = $(element); - if (element.style.position == 'absolute') return; - Position.prepare(); - - var offsets = Position.positionedOffset(element); - 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';; - }, - - relativize: function(element) { - element = $(element); - if (element.style.position == 'relative') return; - Position.prepare(); - - 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; - } -} - -// Safari returns margins on body which is incorrect if the child is absolutely -// positioned. For performance reasons, redefine Position.cumulativeOffset for -// KHTML/WebKit only. -if (/Konqueror|Safari|KHTML/.test(navigator.userAgent)) { - Position.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 [valueL, valueT]; - } -} \ No newline at end of file diff --git a/tracks/vendor/rails/railties/html/robots.txt b/tracks/vendor/rails/railties/html/robots.txt deleted file mode 100644 index 4ab9e89f..00000000 --- a/tracks/vendor/rails/railties/html/robots.txt +++ /dev/null @@ -1 +0,0 @@ -# See http://www.robotstxt.org/wc/norobots.html for documentation on how to use the robots.txt file \ No newline at end of file diff --git a/tracks/vendor/rails/railties/lib/binding_of_caller.rb b/tracks/vendor/rails/railties/lib/binding_of_caller.rb deleted file mode 100644 index c1f2cc7b..00000000 --- a/tracks/vendor/rails/railties/lib/binding_of_caller.rb +++ /dev/null @@ -1,85 +0,0 @@ -begin - require 'simplecc' -rescue LoadError - # to satisfy rdoc - class Continuation #:nodoc: - end - def Continuation.create(*args, &block) # :nodoc: - cc = nil; result = callcc {|c| cc = c; block.call(cc) if block and args.empty?} - result ||= args - return *[cc, *result] - end -end - -class Binding; end # for RDoc -# This method returns the binding of the method that called your -# method. It will raise an Exception when you're not inside a method. -# -# It's used like this: -# def inc_counter(amount = 1) -# Binding.of_caller do |binding| -# # Create a lambda that will increase the variable 'counter' -# # in the caller of this method when called. -# inc = eval("lambda { |arg| counter += arg }", binding) -# # We can refer to amount from inside this block safely. -# inc.call(amount) -# end -# # No other statements can go here. Put them inside the block. -# end -# counter = 0 -# 2.times { inc_counter } -# counter # => 2 -# -# Binding.of_caller must be the last statement in the method. -# This means that you will have to put everything you want to -# do after the call to Binding.of_caller into the block of it. -# This should be no problem however, because Ruby has closures. -# If you don't do this an Exception will be raised. Because of -# the way that Binding.of_caller is implemented it has to be -# done this way. -def Binding.of_caller(&block) - old_critical = Thread.critical - Thread.critical = true - count = 0 - cc, result, error, extra_data = Continuation.create(nil, nil) - error.call if error - - tracer = lambda do |*args| - type, context, extra_data = args[0], args[4], args - if type == "return" - count += 1 - # First this method and then calling one will return -- - # the trace event of the second event gets the context - # of the method which called the method that called this - # method. - if count == 2 - # It would be nice if we could restore the trace_func - # that was set before we swapped in our own one, but - # this is impossible without overloading set_trace_func - # in current Ruby. - set_trace_func(nil) - cc.call(eval("binding", context), nil, extra_data) - end - elsif type == "line" then - nil - elsif type == "c-return" and extra_data[3] == :set_trace_func then - nil - else - set_trace_func(nil) - error_msg = "Binding.of_caller used in non-method context or " + - "trailing statements of method using it aren't in the block." - cc.call(nil, lambda { raise(ArgumentError, error_msg) }, nil) - end - end - - unless result - set_trace_func(tracer) - return nil - else - Thread.critical = old_critical - case block.arity - when 1 then yield(result) - else yield(result, extra_data) - end - end -end diff --git a/tracks/vendor/rails/railties/lib/breakpoint.rb b/tracks/vendor/rails/railties/lib/breakpoint.rb deleted file mode 100644 index 327e43e8..00000000 --- a/tracks/vendor/rails/railties/lib/breakpoint.rb +++ /dev/null @@ -1,523 +0,0 @@ -# The Breakpoint library provides the convenience of -# being able to inspect and modify state, diagnose -# bugs all via IRB by simply setting breakpoints in -# your applications by the call of a method. -# -# This library was written and is supported by me, -# Florian Gross. I can be reached at flgr@ccan.de -# and enjoy getting feedback about my libraries. -# -# The whole library (including breakpoint_client.rb -# and binding_of_caller.rb) is licensed under the -# same license that Ruby uses. (Which is currently -# either the GNU General Public License or a custom -# one that allows for commercial usage.) If you for -# some good reason need to use this under another -# license please contact me. - -require 'irb' -require 'binding_of_caller' -require 'drb' -require 'drb/acl' - -module Breakpoint - id = %q$Id: breakpoint.rb 92 2005-02-04 22:35:53Z flgr $ - Version = id.split(" ")[2].to_i - - extend self - - # This will pop up an interactive ruby session at a - # pre-defined break point in a Ruby application. In - # this session you can examine the environment of - # the break point. - # - # You can get a list of variables in the context using - # local_variables via +local_variables+. You can then - # examine their values by typing their names. - # - # You can have a look at the call stack via +caller+. - # - # The source code around the location where the breakpoint - # was executed can be examined via +source_lines+. Its - # argument specifies how much lines of context to display. - # The default amount of context is 5 lines. Note that - # the call to +source_lines+ can raise an exception when - # it isn't able to read in the source code. - # - # breakpoints can also return a value. They will execute - # a supplied block for getting a default return value. - # A custom value can be returned from the session by doing - # +throw(:debug_return, value)+. - # - # You can also give names to break points which will be - # used in the message that is displayed upon execution - # of them. - # - # Here's a sample of how breakpoints should be placed: - # - # class Person - # def initialize(name, age) - # @name, @age = name, age - # breakpoint("Person#initialize") - # end - # - # attr_reader :age - # def name - # breakpoint("Person#name") { @name } - # end - # end - # - # person = Person.new("Random Person", 23) - # puts "Name: #{person.name}" - # - # And here is a sample debug session: - # - # Executing break point "Person#initialize" at file.rb:4 in `initialize' - # irb(#):001:0> local_variables - # => ["name", "age", "_", "__"] - # irb(#):002:0> [name, age] - # => ["Random Person", 23] - # irb(#):003:0> [@name, @age] - # => ["Random Person", 23] - # irb(#):004:0> self - # => # - # irb(#):005:0> @age += 1; self - # => # - # irb(#):006:0> exit - # Executing break point "Person#name" at file.rb:9 in `name' - # irb(#):001:0> throw(:debug_return, "Overriden name") - # Name: Overriden name - # - # Breakpoint sessions will automatically have a few - # convenience methods available. See Breakpoint::CommandBundle - # for a list of them. - # - # Breakpoints can also be used remotely over sockets. - # This is implemented by running part of the IRB session - # in the application and part of it in a special client. - # You have to call Breakpoint.activate_drb to enable - # support for remote breakpoints and then run - # breakpoint_client.rb which is distributed with this - # library. See the documentation of Breakpoint.activate_drb - # for details. - def breakpoint(id = nil, context = nil, &block) - callstack = caller - callstack.slice!(0, 3) if callstack.first["breakpoint"] - file, line, method = *callstack.first.match(/^(.+?):(\d+)(?::in `(.*?)')?/).captures - - message = "Executing break point " + (id ? "#{id.inspect} " : "") + - "at #{file}:#{line}" + (method ? " in `#{method}'" : "") - - if context then - return handle_breakpoint(context, message, file, line, &block) - end - - Binding.of_caller do |binding_context| - handle_breakpoint(binding_context, message, file, line, &block) - end - end - - module CommandBundle - # Proxy to a Breakpoint client. Lets you directly execute code - # in the context of the client. - class Client - def initialize(eval_handler) # :nodoc: - eval_handler.untaint - @eval_handler = eval_handler - end - - instance_methods.each do |method| - next if method[/^__.+__$/] - undef_method method - end - - # Executes the specified code at the client. - def eval(code) - @eval_handler.call(code) - end - - # Will execute the specified statement at the client. - def method_missing(method, *args, &block) - if args.empty? and not block - result = eval "#{method}" - else - # This is a bit ugly. The alternative would be using an - # eval context instead of an eval handler for executing - # the code at the client. The problem with that approach - # is that we would have to handle special expressions - # like "self", "nil" or constants ourself which is hard. - remote = eval %{ - result = lambda { |block, *args| #{method}(*args, &block) } - def result.call_with_block(*args, &block) - call(block, *args) - end - result - } - remote.call_with_block(*args, &block) - end - - return result - end - end - - # Returns the source code surrounding the location where the - # breakpoint was issued. - def source_lines(context = 5, return_line_numbers = false) - lines = File.readlines(@__bp_file).map { |line| line.chomp } - - break_line = @__bp_line - start_line = [break_line - context, 1].max - end_line = break_line + context - - result = lines[(start_line - 1) .. (end_line - 1)] - - if return_line_numbers then - return [start_line, break_line, result] - else - return result - end - end - - # Lets an object that will forward method calls to the breakpoint - # client. This is useful for outputting longer things at the client - # and so on. You can for example do these things: - # - # client.puts "Hello" # outputs "Hello" at client console - # # outputs "Hello" into the file temp.txt at the client - # client.File.open("temp.txt", "w") { |f| f.puts "Hello" } - def client() - if Breakpoint.use_drb? then - sleep(0.5) until Breakpoint.drb_service.eval_handler - Client.new(Breakpoint.drb_service.eval_handler) - else - Client.new(lambda { |code| eval(code, TOPLEVEL_BINDING) }) - end - end - end - - def handle_breakpoint(context, message, file = "", line = "", &block) # :nodoc: - catch(:debug_return) do |value| - eval(%{ - @__bp_file = #{file.inspect} - @__bp_line = #{line} - extend Breakpoint::CommandBundle - extend DRbUndumped if self - }, context) rescue nil - - if not use_drb? then - puts message - IRB.start(nil, IRB::WorkSpace.new(context)) - else - @drb_service.add_breakpoint(context, message) - end - - block.call if block - end - end - - # These exceptions will be raised on failed asserts - # if Breakpoint.asserts_cause_exceptions is set to - # true. - class FailedAssertError < RuntimeError - end - - # This asserts that the block evaluates to true. - # If it doesn't evaluate to true a breakpoint will - # automatically be created at that execution point. - # - # You can disable assert checking in production - # code by setting Breakpoint.optimize_asserts to - # true. (It will still be enabled when Ruby is run - # via the -d argument.) - # - # Example: - # person_name = "Foobar" - # assert { not person_name.nil? } - # - # Note: If you want to use this method from an - # unit test, you will have to call it by its full - # name, Breakpoint.assert. - def assert(context = nil, &condition) - return if Breakpoint.optimize_asserts and not $DEBUG - return if yield - - callstack = caller - callstack.slice!(0, 3) if callstack.first["assert"] - file, line, method = *callstack.first.match(/^(.+?):(\d+)(?::in `(.*?)')?/).captures - - message = "Assert failed at #{file}:#{line}#{" in `#{method}'" if method}." - - if Breakpoint.asserts_cause_exceptions and not $DEBUG then - raise(Breakpoint::FailedAssertError, message) - end - - message += " Executing implicit breakpoint." - - if context then - return handle_breakpoint(context, message, file, line) - end - - Binding.of_caller do |context| - handle_breakpoint(context, message, file, line) - end - end - - # Whether asserts should be ignored if not in debug mode. - # Debug mode can be enabled by running ruby with the -d - # switch or by setting $DEBUG to true. - attr_accessor :optimize_asserts - self.optimize_asserts = false - - # Whether an Exception should be raised on failed asserts - # in non-$DEBUG code or not. By default this is disabled. - attr_accessor :asserts_cause_exceptions - self.asserts_cause_exceptions = false - @use_drb = false - - attr_reader :drb_service # :nodoc: - - class DRbService # :nodoc: - include DRbUndumped - - def initialize - @handler = @eval_handler = @collision_handler = nil - - IRB.instance_eval { @CONF[:RC] = true } - IRB.run_config - end - - def collision - sleep(0.5) until @collision_handler - - @collision_handler.untaint - - @collision_handler.call - end - - def ping() end - - def add_breakpoint(context, message) - workspace = IRB::WorkSpace.new(context) - workspace.extend(DRbUndumped) - - sleep(0.5) until @handler - - @handler.untaint - @handler.call(workspace, message) - end - - attr_accessor :handler, :eval_handler, :collision_handler - end - - # Will run Breakpoint in DRb mode. This will spawn a server - # that can be attached to via the breakpoint-client command - # whenever a breakpoint is executed. This is useful when you - # are debugging CGI applications or other applications where - # you can't access debug sessions via the standard input and - # output of your application. - # - # You can specify an URI where the DRb server will run at. - # This way you can specify the port the server runs on. The - # default URI is druby://localhost:42531. - # - # Please note that breakpoints will be skipped silently in - # case the DRb server can not spawned. (This can happen if - # the port is already used by another instance of your - # application on CGI or another application.) - # - # Also note that by default this will only allow access - # from localhost. You can however specify a list of - # allowed hosts or nil (to allow access from everywhere). - # But that will still not protect you from somebody - # reading the data as it goes through the net. - # - # A good approach for getting security and remote access - # is setting up an SSH tunnel between the DRb service - # and the client. This is usually done like this: - # - # $ ssh -L20000:127.0.0.1:20000 -R10000:127.0.0.1:10000 example.com - # (This will connect port 20000 at the client side to port - # 20000 at the server side, and port 10000 at the server - # side to port 10000 at the client side.) - # - # After that do this on the server side: (the code being debugged) - # Breakpoint.activate_drb("druby://127.0.0.1:20000", "localhost") - # - # And at the client side: - # ruby breakpoint_client.rb -c druby://127.0.0.1:10000 -s druby://127.0.0.1:20000 - # - # Running through such a SSH proxy will also let you use - # breakpoint.rb in case you are behind a firewall. - # - # Detailed information about running DRb through firewalls is - # available at http://www.rubygarden.org/ruby?DrbTutorial - def activate_drb(uri = nil, allowed_hosts = ['localhost', '127.0.0.1', '::1'], - ignore_collisions = false) - - return false if @use_drb - - uri ||= 'druby://localhost:42531' - - if allowed_hosts then - acl = ["deny", "all"] - - Array(allowed_hosts).each do |host| - acl += ["allow", host] - end - - DRb.install_acl(ACL.new(acl)) - end - - @use_drb = true - @drb_service = DRbService.new - did_collision = false - begin - @service = DRb.start_service(uri, @drb_service) - rescue Errno::EADDRINUSE - if ignore_collisions then - nil - else - # The port is already occupied by another - # Breakpoint service. We will try to tell - # the old service that we want its port. - # It will then forward that request to the - # user and retry. - unless did_collision then - DRbObject.new(nil, uri).collision - did_collision = true - end - sleep(10) - retry - end - end - - return true - end - - # Deactivates a running Breakpoint service. - def deactivate_drb - @service.stop_service unless @service.nil? - @service = nil - @use_drb = false - @drb_service = nil - end - - # Returns true when Breakpoints are used over DRb. - # Breakpoint.activate_drb causes this to be true. - def use_drb? - @use_drb == true - end -end - -module IRB # :nodoc: - class << self; remove_method :start; end - def self.start(ap_path = nil, main_context = nil, workspace = nil) - $0 = File::basename(ap_path, ".rb") if ap_path - - # suppress some warnings about redefined constants - old_verbose, $VERBOSE = $VERBOSE, nil - IRB.setup(ap_path) - $VERBOSE = old_verbose - - if @CONF[:SCRIPT] then - irb = Irb.new(main_context, @CONF[:SCRIPT]) - else - irb = Irb.new(main_context) - end - - if workspace then - irb.context.workspace = workspace - end - - @CONF[:IRB_RC].call(irb.context) if @CONF[:IRB_RC] - @CONF[:MAIN_CONTEXT] = irb.context - - old_sigint = trap("SIGINT") do - begin - irb.signal_handle - rescue RubyLex::TerminateLineInput - # ignored - end - end - - catch(:IRB_EXIT) do - irb.eval_input - end - ensure - trap("SIGINT", old_sigint) - end - - class << self - alias :old_CurrentContext :CurrentContext - remove_method :CurrentContext - end - def IRB.CurrentContext - if old_CurrentContext.nil? and Breakpoint.use_drb? then - result = Object.new - def result.last_value; end - return result - else - old_CurrentContext - end - end - def IRB.parse_opts() end - - class Context #:nodoc: - alias :old_evaluate :evaluate - def evaluate(line, line_no) - if line.chomp == "exit" then - exit - else - old_evaluate(line, line_no) - end - end - end - - class WorkSpace #:nodoc: - alias :old_evaluate :evaluate - - def evaluate(*args) - if Breakpoint.use_drb? then - result = old_evaluate(*args) - if args[0] != :no_proxy and - not [true, false, nil].include?(result) - then - result.extend(DRbUndumped) rescue nil - end - return result - else - old_evaluate(*args) - end - end - end - - module InputCompletor #:nodoc: - def self.eval(code, context, *more) - # Big hack, this assumes that InputCompletor - # will only call eval() when it wants code - # to be executed in the IRB context. - IRB.conf[:MAIN_CONTEXT].workspace.evaluate(:no_proxy, code, *more) - end - end -end - -module DRb #:nodoc: - class DRbObject #:nodoc: - undef :inspect if method_defined?(:inspect) - undef :clone if method_defined?(:clone) - end -end - -# See Breakpoint.breakpoint -def breakpoint(id = nil, &block) - Binding.of_caller do |context| - Breakpoint.breakpoint(id, context, &block) - end -end - -# See Breakpoint.assert -def assert(&block) - Binding.of_caller do |context| - Breakpoint.assert(context, &block) - end -end diff --git a/tracks/vendor/rails/railties/lib/breakpoint_client.rb b/tracks/vendor/rails/railties/lib/breakpoint_client.rb deleted file mode 100644 index 36b7469e..00000000 --- a/tracks/vendor/rails/railties/lib/breakpoint_client.rb +++ /dev/null @@ -1,196 +0,0 @@ -require 'breakpoint' -require 'optparse' -require 'timeout' - -Options = { - :ClientURI => nil, - :ServerURI => "druby://localhost:42531", - :RetryDelay => 2, - :Permanent => true, - :Verbose => false -} - -ARGV.options do |opts| - script_name = File.basename($0) - opts.banner = [ - "Usage: ruby #{script_name} [Options] [server uri]", - "", - "This tool lets you connect to a breakpoint service ", - "which was started via Breakpoint.activate_drb.", - "", - "The server uri defaults to druby://localhost:42531" - ].join("\n") - - opts.separator "" - - opts.on("-c", "--client-uri=uri", - "Run the client on the specified uri.", - "This can be used to specify the port", - "that the client uses to allow for back", - "connections from the server.", - "Default: Find a good URI automatically.", - "Example: -c druby://localhost:12345" - ) { |Options[:ClientURI]| } - - opts.on("-s", "--server-uri=uri", - "Connect to the server specified at the", - "specified uri.", - "Default: druby://localhost:42531" - ) { |Options[:ServerURI]| } - - opts.on("-R", "--retry-delay=delay", Integer, - "Automatically try to reconnect to the", - "server after delay seconds when the", - "connection failed or timed out.", - "A value of 0 disables automatical", - "reconnecting completely.", - "Default: 10" - ) { |Options[:RetryDelay]| } - - opts.on("-P", "--[no-]permanent", - "Run the breakpoint client in permanent mode.", - "This means that the client will keep continue", - "running even after the server has closed the", - "connection. Useful for example in Rails." - ) { |Options[:Permanent]| } - - opts.on("-V", "--[no-]verbose", - "Run the breakpoint client in verbose mode.", - "Will produce more messages, for example between", - "individual breakpoints. This might help in seeing", - "that the breakpoint client is still alive, but adds", - "quite a bit of clutter." - ) { |Options[:Verbose]| } - - opts.separator "" - - opts.on("-h", "--help", - "Show this help message." - ) { puts opts; exit } - opts.on("-v", "--version", - "Display the version information." - ) do - id = %q$Id: breakpoint_client.rb 91 2005-02-04 22:34:08Z flgr $ - puts id.sub("Id: ", "") - puts "(Breakpoint::Version = #{Breakpoint::Version})" - exit - end - - opts.parse! -end - -Options[:ServerURI] = ARGV[0] if ARGV[0] - -module Handlers #:nodoc: - extend self - - def breakpoint_handler(workspace, message) - puts message - IRB.start(nil, nil, workspace) - - puts "" - if Options[:Verbose] then - puts "Resumed execution. Waiting for next breakpoint...", "" - end - end - - def eval_handler(code) - result = eval(code, TOPLEVEL_BINDING) - if result then - DRbObject.new(result) - else - result - end - end - - def collision_handler() - msg = [ - " *** Breakpoint service collision ***", - " Another Breakpoint service tried to use the", - " port already occupied by this one. It will", - " keep waiting until this Breakpoint service", - " is shut down.", - " ", - " If you are using the Breakpoint library for", - " debugging a Rails or other CGI application", - " this likely means that this Breakpoint", - " session belongs to an earlier, outdated", - " request and should be shut down via 'exit'." - ].join("\n") - - if RUBY_PLATFORM["win"] then - # This sucks. Sorry, I'm not doing this because - # I like funky message boxes -- I need to do this - # because on Windows I have no way of displaying - # my notification via puts() when gets() is still - # being performed on STDIN. I have not found a - # better solution. - begin - require 'tk' - root = TkRoot.new { withdraw } - Tk.messageBox('message' => msg, 'type' => 'ok') - root.destroy - rescue Exception - puts "", msg, "" - end - else - puts "", msg, "" - end - end -end - -# Used for checking whether we are currently in the reconnecting loop. -reconnecting = false - -loop do - DRb.start_service(Options[:ClientURI]) - - begin - service = DRbObject.new(nil, Options[:ServerURI]) - - begin - ehandler = Handlers.method(:eval_handler) - chandler = Handlers.method(:collision_handler) - handler = Handlers.method(:breakpoint_handler) - service.eval_handler = ehandler - service.collision_handler = chandler - service.handler = handler - - reconnecting = false - if Options[:Verbose] then - puts "Connection established. Waiting for breakpoint...", "" - end - - loop do - begin - service.ping - rescue DRb::DRbConnError => error - puts "Server exited. Closing connection...", "" - exit! unless Options[:Permanent] - break - end - - sleep(0.5) - end - ensure - service.eval_handler = nil - service.collision_handler = nil - service.handler = nil - end - rescue Exception => error - if Options[:RetryDelay] > 0 then - if not reconnecting then - reconnecting = true - puts "No connection to breakpoint service at #{Options[:ServerURI]} " + - "(#{error.class})" - puts error.backtrace if $DEBUG - puts "Tries to connect will be made every #{Options[:RetryDelay]} seconds..." - end - - sleep Options[:RetryDelay] - retry - else - raise - end - end -end diff --git a/tracks/vendor/rails/railties/lib/code_statistics.rb b/tracks/vendor/rails/railties/lib/code_statistics.rb deleted file mode 100644 index f1c0bf1f..00000000 --- a/tracks/vendor/rails/railties/lib/code_statistics.rb +++ /dev/null @@ -1,107 +0,0 @@ -class CodeStatistics #:nodoc: - - TEST_TYPES = ['Units', 'Functionals', 'Unit tests', 'Functional tests'] - - def initialize(*pairs) - @pairs = pairs - @statistics = calculate_statistics - @total = calculate_total if pairs.length > 1 - end - - def to_s - print_header - @pairs.each { |pair| print_line(pair.first, @statistics[pair.first]) } - print_splitter - - if @total - print_line("Total", @total) - print_splitter - end - - print_code_test_stats - end - - private - def calculate_statistics - @pairs.inject({}) { |stats, pair| stats[pair.first] = calculate_directory_statistics(pair.last); stats } - end - - def calculate_directory_statistics(directory, pattern = /.*\.rb$/) - stats = { "lines" => 0, "codelines" => 0, "classes" => 0, "methods" => 0 } - - Dir.foreach(directory) do |file_name| - if File.stat(directory + "/" + file_name).directory? and (/^\./ !~ file_name) - newstats = calculate_directory_statistics(directory + "/" + file_name, pattern) - stats.each { |k, v| stats[k] += newstats[k] } - end - - next unless file_name =~ pattern - - f = File.open(directory + "/" + file_name) - - while line = f.gets - stats["lines"] += 1 - stats["classes"] += 1 if line =~ /class [A-Z]/ - stats["methods"] += 1 if line =~ /def [a-z]/ - stats["codelines"] += 1 unless line =~ /^\s*$/ || line =~ /^\s*#/ - end - end - - stats - end - - def calculate_total - total = { "lines" => 0, "codelines" => 0, "classes" => 0, "methods" => 0 } - @statistics.each_value { |pair| pair.each { |k, v| total[k] += v } } - total - end - - def calculate_code - code_loc = 0 - @statistics.each { |k, v| code_loc += v['codelines'] unless TEST_TYPES.include? k } - code_loc - end - - def calculate_tests - test_loc = 0 - @statistics.each { |k, v| test_loc += v['codelines'] if TEST_TYPES.include? k } - test_loc - end - - def print_header - print_splitter - puts "| Name | Lines | LOC | Classes | Methods | M/C | LOC/M |" - print_splitter - end - - def print_splitter - puts "+----------------------+-------+-------+---------+---------+-----+-------+" - end - - def print_line(name, statistics) - m_over_c = (statistics["methods"] / statistics["classes"]) rescue m_over_c = 0 - loc_over_m = (statistics["codelines"] / statistics["methods"]) - 2 rescue loc_over_m = 0 - - start = if TEST_TYPES.include? name - "| #{name.ljust(18)} " - else - "| #{name.ljust(20)} " - end - - puts start + - "| #{statistics["lines"].to_s.rjust(5)} " + - "| #{statistics["codelines"].to_s.rjust(5)} " + - "| #{statistics["classes"].to_s.rjust(7)} " + - "| #{statistics["methods"].to_s.rjust(7)} " + - "| #{m_over_c.to_s.rjust(3)} " + - "| #{loc_over_m.to_s.rjust(5)} |" - end - - def print_code_test_stats - code = calculate_code - tests = calculate_tests - - puts " Code LOC: #{code} Test LOC: #{tests} Code to Test Ratio: 1:#{sprintf("%.1f", tests.to_f/code)}" - puts "" - end - end diff --git a/tracks/vendor/rails/railties/lib/commands.rb b/tracks/vendor/rails/railties/lib/commands.rb deleted file mode 100644 index 841e98a0..00000000 --- a/tracks/vendor/rails/railties/lib/commands.rb +++ /dev/null @@ -1,17 +0,0 @@ -commands = Dir["#{File.dirname(__FILE__)}/commands/*.rb"].collect { |file_path| File.basename(file_path).split(".").first } - -if commands.include?(ARGV.first) - require "#{File.dirname(__FILE__)}/commands/#{ARGV.shift}" -else - puts <<-USAGE -The 'run' provides a unified access point for all the default Rails' commands. - -Usage: ./script/run [OPTIONS] - -Examples: - ./script/run generate controller Admin - ./script/run process reaper - -USAGE - puts "Choose: #{commands.join(", ")}" -end \ No newline at end of file diff --git a/tracks/vendor/rails/railties/lib/commands/about.rb b/tracks/vendor/rails/railties/lib/commands/about.rb deleted file mode 100644 index 313bc18c..00000000 --- a/tracks/vendor/rails/railties/lib/commands/about.rb +++ /dev/null @@ -1,2 +0,0 @@ -require 'environment' -puts Rails::Info diff --git a/tracks/vendor/rails/railties/lib/commands/breakpointer.rb b/tracks/vendor/rails/railties/lib/commands/breakpointer.rb deleted file mode 100644 index cc52010c..00000000 --- a/tracks/vendor/rails/railties/lib/commands/breakpointer.rb +++ /dev/null @@ -1 +0,0 @@ -require 'breakpoint_client' diff --git a/tracks/vendor/rails/railties/lib/commands/console.rb b/tracks/vendor/rails/railties/lib/commands/console.rb deleted file mode 100644 index 3f21412b..00000000 --- a/tracks/vendor/rails/railties/lib/commands/console.rb +++ /dev/null @@ -1,23 +0,0 @@ -irb = RUBY_PLATFORM =~ /mswin32/ ? 'irb.bat' : 'irb' - -require 'optparse' -options = { :sandbox => false, :irb => irb } -OptionParser.new do |opt| - opt.banner = "Usage: console [environment] [options]" - opt.on('-s', '--sandbox', 'Rollback database modifications on exit.') { |options[:sandbox]| } - opt.on("--irb=[#{irb}]", 'Invoke a different irb.') { |options[:irb]| } - opt.parse!(ARGV) -end - -libs = " -r irb/completion" -libs << " -r #{RAILS_ROOT}/config/environment" -libs << " -r console_sandbox" if options[:sandbox] - -ENV['RAILS_ENV'] = ARGV.first || 'development' -if options[:sandbox] - puts "Loading #{ENV['RAILS_ENV']} environment in sandbox." - puts "Any modifications you make will be rolled back on exit." -else - puts "Loading #{ENV['RAILS_ENV']} environment." -end -exec "#{options[:irb]} #{libs} --prompt-mode simple" diff --git a/tracks/vendor/rails/railties/lib/commands/destroy.rb b/tracks/vendor/rails/railties/lib/commands/destroy.rb deleted file mode 100644 index f4b81d65..00000000 --- a/tracks/vendor/rails/railties/lib/commands/destroy.rb +++ /dev/null @@ -1,6 +0,0 @@ -require "#{RAILS_ROOT}/config/environment" -require 'rails_generator' -require 'rails_generator/scripts/destroy' - -ARGV.shift if ['--help', '-h'].include?(ARGV[0]) -Rails::Generator::Scripts::Destroy.new.run(ARGV) diff --git a/tracks/vendor/rails/railties/lib/commands/generate.rb b/tracks/vendor/rails/railties/lib/commands/generate.rb deleted file mode 100644 index 3d3db3d8..00000000 --- a/tracks/vendor/rails/railties/lib/commands/generate.rb +++ /dev/null @@ -1,6 +0,0 @@ -require "#{RAILS_ROOT}/config/environment" -require 'rails_generator' -require 'rails_generator/scripts/generate' - -ARGV.shift if ['--help', '-h'].include?(ARGV[0]) -Rails::Generator::Scripts::Generate.new.run(ARGV) diff --git a/tracks/vendor/rails/railties/lib/commands/ncgi/listener b/tracks/vendor/rails/railties/lib/commands/ncgi/listener deleted file mode 100644 index 421c453f..00000000 --- a/tracks/vendor/rails/railties/lib/commands/ncgi/listener +++ /dev/null @@ -1,86 +0,0 @@ -#!/usr/local/bin/ruby - -require 'stringio' -require 'fileutils' -require 'fcgi_handler' - -def message(s) - $stderr.puts "listener: #{s}" if ENV && ENV["DEBUG_GATEWAY"] -end - -class RemoteCGI < CGI - attr_accessor :stdinput, :stdoutput, :env_table - def initialize(env_table, input = nil, output = nil) - self.env_table = env_table - self.stdinput = input || StringIO.new - self.stdoutput = output || StringIO.new - super() - end - - def out(stream) # Ignore the requested output stream - super(stdoutput) - end -end - -class Listener - include DRbUndumped - - def initialize(timeout, socket_path) - @socket = File.expand_path(socket_path) - @mutex = Mutex.new - @active = false - @timeout = timeout - - @handler = RailsFCGIHandler.new - @handler.extend DRbUndumped - - message 'opening socket' - DRb.start_service("drbunix:#{@socket}", self) - - message 'entering process loop' - @handler.process! self - end - - def each_cgi(&cgi_block) - @cgi_block = cgi_block - message 'entering idle loop' - loop do - sleep @timeout rescue nil - die! unless @active - @active = false - end - end - - def process(env, input) - message 'received request' - @mutex.synchronize do - @active = true - - message 'creating input stream' - input_stream = StringIO.new(input) - message 'building CGI instance' - cgi = RemoteCGI.new(eval(env), input_stream) - - message 'yielding to fcgi handler' - @cgi_block.call cgi - message 'yield finished -- sending output' - - cgi.stdoutput.seek(0) - output = cgi.stdoutput.read - - return output - end - end - - def die! - message 'shutting down' - DRb.stop_service - FileUtils.rm_f @socket - Kernel.exit 0 - end -end - -socket_path = ARGV.shift -timeout = (ARGV.shift || 90).to_i - -Listener.new(timeout, socket_path) \ No newline at end of file diff --git a/tracks/vendor/rails/railties/lib/commands/ncgi/tracker b/tracks/vendor/rails/railties/lib/commands/ncgi/tracker deleted file mode 100644 index 859c9fa0..00000000 --- a/tracks/vendor/rails/railties/lib/commands/ncgi/tracker +++ /dev/null @@ -1,69 +0,0 @@ -#!/usr/local/bin/ruby - -require 'drb' -require 'thread' - -def message(s) - $stderr.puts "tracker: #{s}" if ENV && ENV["DEBUG_GATEWAY"] -end - -class Tracker - include DRbUndumped - - def initialize(instances, socket_path) - @instances = instances - @socket = File.expand_path(socket_path) - @active = false - - @listeners = [] - @instances.times { @listeners << Mutex.new } - - message "using #{@listeners.length} listeners" - message "opening socket at #{@socket}" - - @service = DRb.start_service("drbunix://#{@socket}", self) - end - - def with_listener - message "listener requested" - - mutex = has_lock = index = nil - 3.times do - @listeners.each_with_index do |mutex, index| - has_lock = mutex.try_lock - break if has_lock - end - break if has_lock - sleep 0.05 - end - - if has_lock - message "obtained listener #{index}" - @active = true - begin yield index - ensure - mutex.unlock - message "released listener #{index}" - end - else - message "dropping request because no listeners are available!" - end - end - - def background(check_interval = nil) - if check_interval - loop do - sleep check_interval - message "Idle for #{check_interval}, shutting down" unless @active - @active = false - Kernel.exit 0 - end - else DRb.thread.join - end - end -end - -socket_path = ARGV.shift -instances = ARGV.shift.to_i -t = Tracker.new(instances, socket_path) -t.background(ARGV.first ? ARGV.shift.to_i : 90) \ No newline at end of file diff --git a/tracks/vendor/rails/railties/lib/commands/performance/benchmarker.rb b/tracks/vendor/rails/railties/lib/commands/performance/benchmarker.rb deleted file mode 100644 index e8804fe1..00000000 --- a/tracks/vendor/rails/railties/lib/commands/performance/benchmarker.rb +++ /dev/null @@ -1,24 +0,0 @@ -if ARGV.empty? - puts "Usage: ./script/performance/benchmarker [times] 'Person.expensive_way' 'Person.another_expensive_way' ..." - exit 1 -end - -begin - N = Integer(ARGV.first) - ARGV.shift -rescue ArgumentError - N = 1 -end - -require RAILS_ROOT + '/config/environment' -require 'benchmark' -include Benchmark - -# Don't include compilation in the benchmark -ARGV.each { |expression| eval(expression) } - -bm(6) do |x| - ARGV.each_with_index do |expression, idx| - x.report("##{idx + 1}") { N.times { eval(expression) } } - end -end diff --git a/tracks/vendor/rails/railties/lib/commands/performance/profiler.rb b/tracks/vendor/rails/railties/lib/commands/performance/profiler.rb deleted file mode 100644 index 310d6764..00000000 --- a/tracks/vendor/rails/railties/lib/commands/performance/profiler.rb +++ /dev/null @@ -1,34 +0,0 @@ -if ARGV.empty? - $stderr.puts "Usage: ./script/performance/profiler 'Person.expensive_method(10)' [times]" - exit(1) -end - -# Keep the expensive require out of the profile. -$stderr.puts 'Loading Rails...' -require RAILS_ROOT + '/config/environment' - -# Define a method to profile. -if ARGV[1] and ARGV[1].to_i > 1 - eval "def profile_me() #{ARGV[1]}.times { #{ARGV[0]} } end" -else - eval "def profile_me() #{ARGV[0]} end" -end - -# Use the ruby-prof extension if available. Fall back to stdlib profiler. -begin - require 'prof' - $stderr.puts 'Using the ruby-prof extension.' - Prof.clock_mode = Prof::GETTIMEOFDAY - Prof.start - profile_me - results = Prof.stop - require 'rubyprof_ext' - Prof.print_profile(results, $stderr) -rescue LoadError - require 'profiler' - $stderr.puts 'Using the standard Ruby profiler.' - Profiler__.start_profile - profile_me - Profiler__.stop_profile - Profiler__.print_profile($stderr) -end diff --git a/tracks/vendor/rails/railties/lib/commands/plugin.rb b/tracks/vendor/rails/railties/lib/commands/plugin.rb deleted file mode 100644 index 6946f0b9..00000000 --- a/tracks/vendor/rails/railties/lib/commands/plugin.rb +++ /dev/null @@ -1,823 +0,0 @@ -# Rails Plugin Manager. -# -# Listing available plugins: -# -# $ ./script/plugin list -# continuous_builder http://dev.rubyonrails.com/svn/rails/plugins/continuous_builder -# asset_timestamping http://svn.aviditybytes.com/rails/plugins/asset_timestamping -# enumerations_mixin http://svn.protocool.com/rails/plugins/enumerations_mixin/trunk -# calculations http://techno-weenie.net/svn/projects/calculations/ -# ... -# -# Installing plugins: -# -# $ ./script/plugin install continuous_builder asset_timestamping -# -# Finding Repositories: -# -# $ ./script/plugin discover -# -# Adding Repositories: -# -# $ ./script/plugin source http://svn.protocool.com/rails/plugins/ -# -# How it works: -# -# * Maintains a list of subversion repositories that are assumed to have -# a plugin directory structure. Manage them with the (source, unsource, -# and sources commands) -# -# * The discover command scrapes the following page for things that -# look like subversion repositories with plugins: -# http://wiki.rubyonrails.org/rails/pages/Plugins -# -# * If `vendor/plugins` is under subversion control, the script will -# modify the svn:externals property and perform an update. You can -# use normal subversion commands to keep the plugins up to date or -# you can use the built in update command. -# -# * Or, if `vendor/plugins` is not under subversion control, the -# plugin is pulled via `svn checkout` or `svn export` but looks -# exactly the same. -# -# This is Free Software, copyright 2005 by Ryan Tomayko (rtomayko@gmail.com) -# and is licensed MIT: (http://www.opensource.org/licenses/mit-license.php) - -$verbose = false - - -require 'open-uri' -require 'fileutils' -require 'tempfile' - -include FileUtils - -class RailsEnvironment - attr_reader :root - - def initialize(dir) - @root = dir - end - - def self.find(dir=nil) - dir ||= pwd - while dir.length > 1 - return new(dir) if File.exist?(File.join(dir, 'config', 'environment.rb')) - dir = File.dirname(dir) - end - end - - def self.default - @default ||= find - end - - def self.default=(rails_env) - @default = rails_env - end - - def install(name_uri_or_plugin) - if name_uri_or_plugin.is_a? String - if name_uri_or_plugin =~ /:\/\// - plugin = Plugin.new(name_uri_or_plugin) - else - plugin = Plugins[name_uri_or_plugin] - end - else - plugin = name_uri_or_plugin - end - unless plugin.nil? - plugin.install - else - puts "plugin not found: #{name_uri_or_plugin}" - end - end - - def use_svn? - `svn --version` rescue nil - !$?.nil? && $?.success? - end - - def use_externals? - File.directory?("#{root}/vendor/plugins/.svn") - end - - def use_checkout? - # this is a bit of a guess. we assume that if the rails environment - # is under subversion than they probably want the plugin checked out - # instead of exported. This can be overridden on the command line - File.directory?("#{root}/.svn") - end - - def best_install_method - return :http unless use_svn? - case - when use_externals? then :externals - when use_checkout? then :checkout - else :export - end - end - - def externals - return [] unless use_externals? - ext = `svn propget svn:externals #{root}/vendor/plugins` - ext.reject{ |line| line.strip == '' }.map do |line| - line.strip.split(/\s+/, 2) - end - end - - def externals=(items) - unless items.is_a? String - items = items.map{|name,uri| "#{name.ljust(29)} #{uri.chomp('/')}"}.join("\n") - end - Tempfile.open("svn-set-prop") do |file| - file.write(items) - file.flush - system("svn propset -q svn:externals -F #{file.path} #{root}/vendor/plugins") - end - end - -end - -class Plugin - attr_reader :name, :uri - - def initialize(uri, name=nil) - @uri = uri - guess_name(uri) - end - - def to_s - "#{@name.ljust(30)}#{@uri}" - end - - def installed? - File.directory?("#{rails_env.root}/vendor/plugins/#{name}") \ - or rails_env.externals.detect{ |name, repo| self.uri == repo } - end - - def install(method=nil) - method ||= rails_env.best_install_method? - unless installed? - send("install_using_#{method}") - else - puts "already installed: #{name} (#{uri})" - end - end - - private - def install_using_export - root = rails_env.root - mkdir_p "#{root}/vendor/plugins" - system("svn export #{uri} #{root}/vendor/plugins/#{name}") - end - - def install_using_checkout - root = rails_env.root - mkdir_p "#{root}/vendor/plugins" - system("svn checkout #{uri} #{root}/vendor/plugins/#{name}") - end - - def install_using_externals - externals = rails_env.externals - externals.push([@name, uri]) - rails_env.externals = externals - install_using_checkout - end - - def install_using_http - root = rails_env.root - mkdir_p "#{root}/vendor/plugins" - Dir.chdir "#{root}/vendor/plugins" - RecursiveHTTPFetcher.new(uri).fetch - end - - def guess_name(url) - @name = File.basename(url) - if @name == 'trunk' || @name.empty? - @name = File.basename(File.dirname(url)) - end - end - - def rails_env - @rails_env || RailsEnvironment.default - end -end - -class Repositories - include Enumerable - - def initialize(cache_file = File.join(find_home, ".rails-plugin-sources")) - @cache_file = File.expand_path(cache_file) - load! - end - - def each(&block) - @repositories.each(&block) - end - - def add(uri) - unless find{|repo| repo.uri == uri } - @repositories.push(Repository.new(uri)).last - end - end - - def remove(uri) - @repositories.reject!{|repo| repo.uri == uri} - end - - def exist?(uri) - @repositories.detect{|repo| repo.uri == uri } - end - - def all - @repositories - end - - def find_plugin(name) - @repositories.each do |repo| - repo.each do |plugin| - return plugin if plugin.name == name - end - end - - return nil - end - - def load! - contents = File.exist?(@cache_file) ? File.read(@cache_file) : defaults - contents = defaults if contents.empty? - @repositories = contents.split(/\n/).reject do |line| - line =~ /^\s*#/ or line =~ /^\s*$/ - end.map { |source| Repository.new(source.strip) } - end - - def save - File.open(@cache_file, 'w') do |f| - each do |repo| - f.write(repo.uri) - f.write("\n") - end - end - end - - def defaults - <<-DEFAULTS - http://dev.rubyonrails.com/svn/rails/plugins/ - DEFAULTS - end - - def find_home - ['HOME', 'USERPROFILE'].each do |homekey| - return ENV[homekey] if ENV[homekey] - end - if ENV['HOMEDRIVE'] && ENV['HOMEPATH'] - return "#{ENV['HOMEDRIVE']}:#{ENV['HOMEPATH']}" - end - begin - File.expand_path("~") - rescue StandardError => ex - if File::ALT_SEPARATOR - "C:/" - else - "/" - end - end - end - - def self.instance - @instance ||= Repositories.new - end - - def self.each(&block) - self.instance.each(&block) - end -end - -class Repository - include Enumerable - attr_reader :uri, :plugins - - def initialize(uri) - uri << "/" unless uri =~ /\/$/ - @uri = uri - @plugins = nil - end - - def plugins - unless @plugins - if $verbose - puts "Discovering plugins in #{@uri}" - puts index - end - - @plugins = index.split(/\n/).reject{ |line| line !~ /\/$/ } - @plugins.map! { |name| Plugin.new(File.join(@uri, name), name) } - end - - @plugins - end - - def each(&block) - plugins.each(&block) - end - - private - def index - @index ||= `svn ls #{@uri}` - end -end - - -# load default environment and parse arguments -require 'optparse' -module Commands - - class Plugin - attr_reader :environment, :script_name, :sources - def initialize - @environment = RailsEnvironment.default - @rails_root = RailsEnvironment.default.root - @script_name = File.basename($0) - @sources = [] - end - - def environment=(value) - @environment = value - RailsEnvironment.default = value - end - - def options - OptionParser.new do |o| - o.set_summary_indent(' ') - o.banner = "Usage: #{@script_name} [OPTIONS] command" - o.define_head "Rails plugin manager." - - o.separator "" - o.separator "GENERAL OPTIONS" - - o.on("-r", "--root=DIR", String, - "Set an explicit rails app directory.", - "Default: #{@rails_root}") { |@rails_root| self.environment = RailsEnvironment.new(@rails_root) } - o.on("-s", "--source=URL1,URL2", Array, - "Use the specified plugin repositories instead of the defaults.") { |@sources|} - - o.on("-v", "--verbose", "Turn on verbose output.") { |$verbose| } - o.on("-h", "--help", "Show this help message.") { puts o; exit } - - o.separator "" - o.separator "COMMANDS" - - o.separator " discover Discover plugin repositories." - o.separator " list List available plugins." - o.separator " install Install plugin(s) from known repositories or URLs." - o.separator " update Update installed plugins." - o.separator " remove Uninstall plugins." - o.separator " source Add a plugin source repository." - o.separator " unsource Remove a plugin repository." - o.separator " sources List currently configured plugin repositories." - - o.separator "" - o.separator "EXAMPLES" - o.separator " Install a plugin:" - o.separator " #{@script_name} install continuous_builder\n" - o.separator " Install a plugin from a subversion URL:" - o.separator " #{@script_name} install http://dev.rubyonrails.com/svn/rails/plugins/continuous_builder\n" - o.separator " Install a plugin and add a svn:externals entry to vendor/plugins" - o.separator " #{@script_name} install -x continuous_builder\n" - o.separator " List all available plugins:" - o.separator " #{@script_name} list\n" - o.separator " List plugins in the specified repository:" - o.separator " #{@script_name} list --source=http://dev.rubyonrails.com/svn/rails/plugins/\n" - o.separator " Discover and prompt to add new repositories:" - o.separator " #{@script_name} discover\n" - o.separator " Discover new repositories but just list them, don't add anything:" - o.separator " #{@script_name} discover -l\n" - o.separator " Add a new repository to the source list:" - o.separator " #{@script_name} source http://dev.rubyonrails.com/svn/rails/plugins/\n" - o.separator " Remove a repository from the source list:" - o.separator " #{@script_name} unsource http://dev.rubyonrails.com/svn/rails/plugins/\n" - o.separator " Show currently configured repositories:" - o.separator " #{@script_name} sources\n" - end - end - - def parse!(args=ARGV) - general, sub = split_args(args) - options.parse!(general) - - command = general.shift - if command =~ /^(list|discover|install|source|unsource|sources|remove|update)$/ - command = Commands.const_get(command.capitalize).new(self) - command.parse!(sub) - else - puts "Unknown command: #{command}" - puts "Try: #{$0} --help" - exit 1 - end - end - - def split_args(args) - left = [] - left << args.shift while args[0] and args[0] =~ /^-/ - left << args.shift if args[0] - return [left, args] - end - - def self.parse!(args=ARGV) - Plugin.new.parse!(args) - end - end - - - class List - def initialize(base_command) - @base_command = base_command - @sources = [] - @local = false - @remote = true - @details = false - end - - def options - OptionParser.new do |o| - o.set_summary_indent(' ') - o.banner = "Usage: #{@base_command.script_name} list [OPTIONS] [PATTERN]" - o.define_head "List available plugins." - o.separator "" - o.separator "Options:" - o.separator "" - o.on( "-s", "--source=URL1,URL2", Array, - "Use the specified plugin repositories.") {|@sources|} - o.on( "--local", - "List locally installed plugins.") {|@local| @remote = false} - o.on( "--remote", - "List remotely availabled plugins. This is the default behavior", - "unless --local is provided.") {|@remote|} - o.on( "-l", "--long", - "Long listing / details about each plugin.") {|@details|} - end - end - - def parse!(args) - options.order!(args) - unless @sources.empty? - @sources.map!{ |uri| Repository.new(uri) } - else - @sources = Repositories.instance.all - end - if @remote - @sources.map{|r| r.plugins}.flatten.each do |plugin| - if @local or !plugin.installed? - puts plugin.to_s - system "svn info #{plugin.uri}" if @details - end - end - else - cd "#{@base_command.environment.root}/vendor/plugins" - Dir["*"].select{|p| File.directory?(p)}.each do |name| - puts name - system "svn info #{name}" if @details - end - end - end - end - - - class Sources - def initialize(base_command) - @base_command = base_command - end - - def options - OptionParser.new do |o| - o.set_summary_indent(' ') - o.banner = "Usage: #{@base_command.script_name} sources [OPTIONS] [PATTERN]" - o.define_head "List configured plugin repositories." - o.separator "" - o.separator "Options:" - o.separator "" - o.on( "-c", "--check", - "Report status of repository.") { |@sources|} - end - end - - def parse!(args) - options.parse!(args) - Repositories.each do |repo| - puts repo.uri - end - end - end - - - class Source - def initialize(base_command) - @base_command = base_command - end - - def options - OptionParser.new do |o| - o.set_summary_indent(' ') - o.banner = "Usage: #{@base_command.script_name} source REPOSITORY" - o.define_head "Add a new repository." - end - end - - def parse!(args) - options.parse!(args) - count = 0 - args.each do |uri| - if Repositories.instance.add(uri) - puts "added: #{uri.ljust(50)}" if $verbose - count += 1 - else - puts "failed: #{uri.ljust(50)}" - end - end - Repositories.instance.save - puts "Added #{count} repositories." - end - end - - - class Unsource - def initialize(base_command) - @base_command = base_command - end - - def options - OptionParser.new do |o| - o.set_summary_indent(' ') - o.banner = "Usage: #{@base_command.script_name} source URI [URI [URI]...]" - o.define_head "Remove repositories from the default search list." - o.separator "" - o.on_tail("-h", "--help", "Show this help message.") { puts o; exit } - end - end - - def parse!(args) - options.parse!(args) - count = 0 - args.each do |uri| - if Repositories.instance.remove(uri) - count += 1 - puts "removed: #{uri.ljust(50)}" - else - puts "failed: #{uri.ljust(50)}" - end - end - Repositories.instance.save - puts "Removed #{count} repositories." - end - end - - - class Discover - def initialize(base_command) - @base_command = base_command - @list = false - @prompt = true - end - - def options - OptionParser.new do |o| - o.set_summary_indent(' ') - o.banner = "Usage: #{@base_command.script_name} discover URI [URI [URI]...]" - o.define_head "Discover repositories referenced on a page." - o.separator "" - o.separator "Options:" - o.separator "" - o.on( "-l", "--list", - "List but don't prompt or add discovered repositories.") { |@list| @prompt = !@list } - o.on( "-n", "--no-prompt", - "Add all new repositories without prompting.") { |v| @prompt = !v } - end - end - - def parse!(args) - options.parse!(args) - args = ['http://wiki.rubyonrails.org/rails/pages/Plugins'] if args.empty? - args.each do |uri| - scrape(uri) do |repo_uri| - catch(:next_uri) do - if @prompt - begin - $stdout.print "Add #{repo_uri}? [Y/n] " - throw :next_uri if $stdin.gets !~ /^y?$/i - rescue Interrupt - $stdout.puts - exit 1 - end - elsif @list - puts repo_uri - throw :next_uri - end - Repositories.instance.add(repo_uri) - puts "discovered: #{repo_uri}" if $verbose or !@prompt - end - end - end - Repositories.instance.save - end - - def scrape(uri) - require 'open-uri' - puts "Scraping #{uri}" if $verbose - dupes = [] - content = open(uri).each do |line| - if line =~ /]*href=['"]([^'"]*)['"]/ - uri = $1 - if uri =~ /\/plugins\// and uri !~ /\/browser\// - uri = extract_repository_uri(uri) - yield uri unless dupes.include?(uri) or Repositories.instance.exist?(uri) - dupes << uri - end - end - end - end - - def extract_repository_uri(uri) - uri.match(/(svn|https?):.*\/plugins\//i)[0] - end - end - - class Install - def initialize(base_command) - @base_command = base_command - @method = :export - end - - def options - OptionParser.new do |o| - o.set_summary_indent(' ') - o.banner = "Usage: #{@base_command.script_name} install PLUGIN [PLUGIN [PLUGIN] ...]" - o.define_head "Install one or more plugins." - o.separator "" - o.separator "Options:" - o.on( "-x", "--externals", - "Use svn:externals to grab the plugin.", - "Enables plugin updates and plugin versioning.") { |v| @method = :externals } - o.on( "-o", "--checkout", - "Use svn checkout to grab the plugin.", - "Enables updating but does not add a svn:externals entry.") { |v| @method = :checkout } - o.separator "" - o.separator "You can specify plugin names as given in 'plugin list' output or absolute URLs to " - o.separator "a plugin repository." - end - end - - def determine_install_method - best = @base_command.environment.best_install_method - @method = :http if best == :http and @method == :export - case - when (best == :http and @method != :http) - msg = "Cannot install using subversion because `svn' cannot be found in your PATH" - when (best == :export and (@method != :export and method != :http)) - msg = "Cannot install using #{requested} because this project is not under subversion." - when (best != :externals and @method == :externals) - msg = "Cannot install using externals because vendor/plugins is not under subversion." - end - if msg - puts msg - exit 1 - end - @method - end - - def parse!(args) - options.parse!(args) - environment = @base_command.environment - install_method = determine_install_method - puts "Plugins will be installed using #{install_method}" if $verbose - args.each do |name| - if name =~ /\// then - ::Plugin.new(name).install(install_method) - else - plugin = Repositories.instance.find_plugin(name) - unless plugin.nil? - plugin.install(install_method) - else - puts "Plugin not found: #{name}" - exit 1 - end - end - end - end - end - - - class Remove - def initialize(base_command) - @base_command = base_command - end - - def options - OptionParser.new do |o| - o.set_summary_indent(' ') - o.banner = "Usage: #{@base_command.script_name} remove name [name]..." - o.define_head "Remove plugins." - end - end - - def parse!(args) - options.parse!(args) - root = @base_command.environment.root - args.each do |name| - path = "#{root}/vendor/plugins/#{name}" - if File.directory?(path) - rm_r path - else - puts "Plugin doesn't exist: #{path}" - end - # clean up svn:externals - externals = @base_command.environment.externals - externals.reject!{|n,u| name == n or name == u} - @base_command.environment.externals = externals - end - end - end - - class Update - def initialize(base_command) - @base_command = base_command - end - - def options - OptionParser.new do |o| - o.set_summary_indent(' ') - o.banner = "Usage: #{@base_command.script_name} update [name [name]...]" - o.define_head "Update plugins." - end - end - - def parse!(args) - options.parse!(args) - root = @base_command.environment.root - args = Dir["#{root}/vendor/plugins/*"].map do |f| - File.directory?("#{f}/.svn") ? File.basename(f) : nil - end.compact if args.empty? - cd "#{root}/vendor/plugins" - args.each do |name| - if File.directory?(name) - puts "Updating plugin: #{name}" - system("svn #{$verbose ? '' : '-q'} up #{name}") - else - puts "Plugin doesn't exist: #{name}" - end - end - end - end - -end - -class RecursiveHTTPFetcher - def initialize(urls_to_fetch, cwd = ".") - @cwd = cwd - @urls_to_fetch = urls_to_fetch.to_a - end - - def push_d(dir) - @cwd = File.join(@cwd, dir) - FileUtils.mkdir_p(@cwd) - end - - def pop_d - @cwd = File.dirname(@cwd) - end - - def links(base_url, contents) - links = [] - contents.scan(/href\s*=\s*\"*[^\">]*/i) do |link| - link = link.sub(/href="/i, "") - next if link =~ /^http/i || link =~ /^\./ - links << File.join(base_url, link) - end - links - end - - def download(link) - puts "+ #{File.join(@cwd, File.basename(link))}" - open(link) do |stream| - File.open(File.join(@cwd, File.basename(link)), "wb") do |file| - file.write(stream.read) - end - end - end - - def fetch(links = @urls_to_fetch) - links.each do |l| - (l =~ /\/$/ || links == @urls_to_fetch) ? fetch_dir(l) : download(l) - end - end - - def fetch_dir(url) - push_d(File.basename(url)) - open(url) do |stream| - contents = stream.read - fetch(links(url, contents)) - end - pop_d - end -end - -Commands::Plugin.parse! diff --git a/tracks/vendor/rails/railties/lib/commands/process/reaper.rb b/tracks/vendor/rails/railties/lib/commands/process/reaper.rb deleted file mode 100644 index 6da2191d..00000000 --- a/tracks/vendor/rails/railties/lib/commands/process/reaper.rb +++ /dev/null @@ -1,130 +0,0 @@ -require 'optparse' -require 'net/http' -require 'uri' - -if RUBY_PLATFORM =~ /mswin32/ then abort("Reaper is only for Unix") end - -# Instances of this class represent a single running process. Processes may -# be queried by "keyword" to find those that meet a specific set of criteria. -class ProgramProcess - class << self - - # Searches for all processes matching the given keywords, and then invokes - # a specific action on each of them. This is useful for (e.g.) reloading a - # set of processes: - # - # ProgramProcess.process_keywords(:reload, "basecamp") - def process_keywords(action, *keywords) - processes = keywords.collect { |keyword| find_by_keyword(keyword) }.flatten - - if processes.empty? - puts "Couldn't find any process matching: #{keywords.join(" or ")}" - else - processes.each do |process| - puts "#{action.capitalize}ing #{process}" - process.send(action) - end - end - end - - # Searches for all processes matching the given keyword: - # - # ProgramProcess.find_by_keyword("basecamp") - def find_by_keyword(keyword) - process_lines_with_keyword(keyword).split("\n").collect { |line| - next if line =~ /inq|ps axww|grep|spawn-fcgi|spawner|reaper/ - pid, *command = line.split - new(pid, command.join(" ")) - }.compact - end - - private - def process_lines_with_keyword(keyword) - `ps axww -o 'pid command' | grep #{keyword}` - end - end - - # Create a new ProgramProcess instance that represents the process with the - # given pid, running the given command. - def initialize(pid, command) - @pid, @command = pid, command - end - - # Forces the (rails) application to reload by sending a +HUP+ signal to the - # process. - def reload - `kill -s HUP #{@pid}` - end - - # Forces the (rails) application to gracefully terminate by sending a - # +TERM+ signal to the process. - def graceful - `kill -s TERM #{@pid}` - end - - # Forces the (rails) application to terminate immediately by sending a -9 - # signal to the process. - def kill - `kill -9 #{@pid}` - end - - # Send a +USR1+ signal to the process. - def usr1 - `kill -s USR1 #{@pid}` - end - - # Force the (rails) application to restart by sending a +USR2+ signal to the - # process. - def restart - `kill -s USR2 #{@pid}` - end - - def to_s #:nodoc: - "[#{@pid}] #{@command}" - end -end - -OPTIONS = { - :action => "restart", - :dispatcher => File.expand_path(RAILS_ROOT + '/public/dispatch.fcgi') -} - -ARGV.options do |opts| - opts.banner = "Usage: reaper [options]" - - opts.separator "" - - opts.on <<-EOF - Description: - The reaper is used to restart, reload, gracefully exit, and forcefully exit FCGI processes - running a Rails Dispatcher. This is commonly done when a new version of the application - is available, so the existing processes can be updated to use the latest code. - - The reaper actions are: - - * restart : Restarts the application by reloading both application and framework code - * reload : Only reloads the application, but not the framework (like the development environment) - * graceful: Marks all of the processes for exit after the next request - * kill : Forcefully exists all processes regardless of whether they're currently serving a request - - Restart is the most common and default action. - - Examples: - reaper # restarts the default dispatcher - reaper -a reload - reaper -a exit -d /my/special/dispatcher.fcgi - EOF - - opts.on(" Options:") - - opts.on("-a", "--action=name", "reload|graceful|kill (default: #{OPTIONS[:action]})", String) { |OPTIONS[:action]| } - opts.on("-d", "--dispatcher=path", "default: #{OPTIONS[:dispatcher]}", String) { |OPTIONS[:dispatcher]| } - - opts.separator "" - - opts.on("-h", "--help", "Show this help message.") { puts opts; exit } - - opts.parse! -end - -ProgramProcess.process_keywords(OPTIONS[:action], OPTIONS[:dispatcher]) diff --git a/tracks/vendor/rails/railties/lib/commands/process/spawner.rb b/tracks/vendor/rails/railties/lib/commands/process/spawner.rb deleted file mode 100644 index 465017d8..00000000 --- a/tracks/vendor/rails/railties/lib/commands/process/spawner.rb +++ /dev/null @@ -1,52 +0,0 @@ -require 'optparse' - -def spawn(port) - print "Starting FCGI on port: #{port}\n " - system("#{OPTIONS[:spawner]} -f #{OPTIONS[:dispatcher]} -p #{port}") -end - -OPTIONS = { - :environment => "production", - :spawner => '/usr/bin/env spawn-fcgi', - :dispatcher => File.expand_path(RAILS_ROOT + '/public/dispatch.fcgi'), - :port => 8000, - :instances => 3 -} - -ARGV.options do |opts| - opts.banner = "Usage: spawner [options]" - - opts.separator "" - - opts.on <<-EOF - Description: - The spawner is a wrapper for spawn-fcgi that makes it easier to start multiple FCGI - processes running the Rails dispatcher. The spawn-fcgi command is included with the lighttpd - web server, but can be used with both Apache and lighttpd (and any other web server supporting - externally managed FCGI processes). - - You decide a starting port (default is 8000) and the number of FCGI process instances you'd - like to run. So if you pick 9100 and 3 instances, you'll start processes on 9100, 9101, and 9102. - - Examples: - spawner # starts instances on 8000, 8001, and 8002 - spawner -p 9100 -i 10 # starts 10 instances counting from 9100 to 9109 - EOF - - opts.on(" Options:") - - opts.on("-p", "--port=number", Integer, "Starting port number (default: #{OPTIONS[:port]})") { |OPTIONS[:port]| } - opts.on("-i", "--instances=number", Integer, "Number of instances (default: #{OPTIONS[:instances]})") { |OPTIONS[:instances]| } - opts.on("-e", "--environment=name", String, "test|development|production (default: #{OPTIONS[:environment]})") { |OPTIONS[:environment]| } - opts.on("-s", "--spawner=path", String, "default: #{OPTIONS[:spawner]}") { |OPTIONS[:spawner]| } - opts.on("-d", "--dispatcher=path", String, "default: #{OPTIONS[:dispatcher]}") { |dispatcher| OPTIONS[:dispatcher] = File.expand_path(dispatcher) } - - opts.separator "" - - opts.on("-h", "--help", "Show this help message.") { puts opts; exit } - - opts.parse! -end - -ENV["RAILS_ENV"] = OPTIONS[:environment] -OPTIONS[:instances].times { |i| spawn(OPTIONS[:port] + i) } \ No newline at end of file diff --git a/tracks/vendor/rails/railties/lib/commands/process/spinner.rb b/tracks/vendor/rails/railties/lib/commands/process/spinner.rb deleted file mode 100644 index af073c74..00000000 --- a/tracks/vendor/rails/railties/lib/commands/process/spinner.rb +++ /dev/null @@ -1,57 +0,0 @@ -require 'optparse' - -def daemonize #:nodoc: - exit if fork # Parent exits, child continues. - Process.setsid # Become session leader. - exit if fork # Zap session leader. See [1]. - Dir.chdir "/" # Release old working directory. - File.umask 0000 # Ensure sensible umask. Adjust as needed. - STDIN.reopen "/dev/null" # Free file descriptors and - STDOUT.reopen "/dev/null", "a" # point them somewhere sensible. - STDERR.reopen STDOUT # STDOUT/ERR should better go to a logfile. -end - -OPTIONS = { - :interval => 5.0, - :command => File.expand_path(RAILS_ROOT + '/script/process/spawner'), - :daemon => false -} - -ARGV.options do |opts| - opts.banner = "Usage: spinner [options]" - - opts.separator "" - - opts.on <<-EOF - Description: - The spinner is a protection loop for the spawner, which will attempt to restart any FCGI processes - that might have been exited or outright crashed. It's a brute-force attempt that'll just try - to run the spawner every X number of seconds, so it does pose a light load on the server. - - Examples: - spinner # attempts to run the spawner with default settings every second with output on the terminal - spinner -i 3 -d # only run the spawner every 3 seconds and detach from the terminal to become a daemon - spinner -c '/path/to/app/script/process/spawner -p 9000 -i 10' -d # using custom spawner - EOF - - opts.on(" Options:") - - opts.on("-c", "--command=path", String) { |OPTIONS[:command]| } - opts.on("-i", "--interval=seconds", Float) { |OPTIONS[:interval]| } - opts.on("-d", "--daemon") { |OPTIONS[:daemon]| } - - opts.separator "" - - opts.on("-h", "--help", "Show this help message.") { puts opts; exit } - - opts.parse! -end - -daemonize if OPTIONS[:daemon] - -trap(OPTIONS[:daemon] ? "TERM" : "INT") { exit } - -loop do - system(OPTIONS[:command]) - sleep(OPTIONS[:interval]) -end \ No newline at end of file diff --git a/tracks/vendor/rails/railties/lib/commands/runner.rb b/tracks/vendor/rails/railties/lib/commands/runner.rb deleted file mode 100644 index 27a2cf33..00000000 --- a/tracks/vendor/rails/railties/lib/commands/runner.rb +++ /dev/null @@ -1,27 +0,0 @@ -require 'optparse' - -options = { :environment => (ENV['RAILS_ENV'] || "development").dup } - -ARGV.options do |opts| - script_name = File.basename($0) - opts.banner = "Usage: runner 'puts Person.find(1).name' [options]" - - opts.separator "" - - opts.on("-e", "--environment=name", String, - "Specifies the environment for the runner to operate under (test/development/production).", - "Default: development") { |options[:environment]| } - - opts.separator "" - - opts.on("-h", "--help", - "Show this help message.") { puts opts; exit } - - opts.parse! -end - -ENV["RAILS_ENV"] = options[:environment] -RAILS_ENV.replace(options[:environment]) if defined?(RAILS_ENV) - -require RAILS_ROOT + '/config/environment' -eval(ARGV.first) diff --git a/tracks/vendor/rails/railties/lib/commands/server.rb b/tracks/vendor/rails/railties/lib/commands/server.rb deleted file mode 100644 index 310afba6..00000000 --- a/tracks/vendor/rails/railties/lib/commands/server.rb +++ /dev/null @@ -1,28 +0,0 @@ -require 'active_support' - -begin - require_library_or_gem 'fcgi' -rescue Exception - # FCGI not available -end - -server = case ARGV.first - when "lighttpd" - ARGV.shift - when "webrick" - ARGV.shift - else - if RUBY_PLATFORM !~ /mswin/ && !silence_stderr { `lighttpd -version` }.blank? && defined?(FCGI) - "lighttpd" - else - "webrick" - end -end - -if server == "webrick" - puts "=> Booting WEBrick..." -else - puts "=> Booting lighttpd (use 'script/server webrick' to force WEBrick)" -end - -require "commands/servers/#{server}" \ No newline at end of file diff --git a/tracks/vendor/rails/railties/lib/commands/servers/lighttpd.rb b/tracks/vendor/rails/railties/lib/commands/servers/lighttpd.rb deleted file mode 100644 index 8f67721a..00000000 --- a/tracks/vendor/rails/railties/lib/commands/servers/lighttpd.rb +++ /dev/null @@ -1,60 +0,0 @@ -unless RUBY_PLATFORM !~ /mswin/ && !silence_stderr { `lighttpd -version` }.blank? - puts "PROBLEM: Lighttpd is not available on your system (or not in your path)" - exit 1 -end - -unless defined?(FCGI) - puts "PROBLEM: Lighttpd requires that the FCGI Ruby bindings are installed on the system" - exit 1 -end - -require 'initializer' -configuration = Rails::Initializer.run(:initialize_logger).configuration - -config_file = "#{RAILS_ROOT}/config/lighttpd.conf" - -unless File.exist?(config_file) - require 'fileutils' - source = File.expand_path(File.join(File.dirname(__FILE__), - "..", "..", "..", "configs", "lighttpd.conf")) - puts "=> #{config_file} not found, copying from #{source}" - FileUtils.cp source, config_file -end - -config = IO.read(config_file) -default_port, default_ip = 3000, '0.0.0.0' -port = config.scan(/^\s*server.port\s*=\s*(\d+)/).first rescue default_port -ip = config.scan(/^\s*server.bind\s*=\s*"([^"]+)"/).first rescue default_ip -puts "=> Rails application started on http://#{ip || default_ip}:#{port || default_port}" - -tail_thread = nil - -if ARGV.first == "-d" - puts "=> Configure in config/lighttpd.conf" - detach = true -else - puts "=> Call with -d to detach (requires absolute paths in config/lighttpd.conf)" - puts "=> Ctrl-C to shutdown server (see config/lighttpd.conf for options)" - detach = false - - cursor = File.size(configuration.log_path) - last_checked = Time.now - tail_thread = Thread.new do - File.open(configuration.log_path, 'r') do |f| - loop do - f.seek cursor - if f.mtime > last_checked - last_checked = f.mtime - contents = f.read - cursor += contents.length - print contents - end - sleep 1 - end - end - end -end - -trap(:INT) { exit } -`lighttpd #{!detach ? "-D " : ""}-f #{config_file}` -tail_thread.kill if tail_thread diff --git a/tracks/vendor/rails/railties/lib/commands/servers/webrick.rb b/tracks/vendor/rails/railties/lib/commands/servers/webrick.rb deleted file mode 100644 index db8e8b3d..00000000 --- a/tracks/vendor/rails/railties/lib/commands/servers/webrick.rb +++ /dev/null @@ -1,59 +0,0 @@ -require 'webrick' -require 'optparse' - -OPTIONS = { - :port => 3000, - :ip => "0.0.0.0", - :environment => (ENV['RAILS_ENV'] || "development").dup, - :server_root => File.expand_path(RAILS_ROOT + "/public/"), - :server_type => WEBrick::SimpleServer, - :charset => "UTF-8", - :mime_types => WEBrick::HTTPUtils::DefaultMimeTypes -} - -ARGV.options do |opts| - script_name = File.basename($0) - opts.banner = "Usage: ruby #{script_name} [options]" - - opts.separator "" - - opts.on("-p", "--port=port", Integer, - "Runs Rails on the specified port.", - "Default: 3000") { |OPTIONS[:port]| } - opts.on("-b", "--binding=ip", String, - "Binds Rails to the specified ip.", - "Default: 0.0.0.0") { |OPTIONS[:ip]| } - opts.on("-e", "--environment=name", String, - "Specifies the environment to run this server under (test/development/production).", - "Default: development") { |OPTIONS[:environment]| } - opts.on("-m", "--mime-types=filename", String, - "Specifies an Apache style mime.types configuration file to be used for mime types", - "Default: none") { |mime_types_file| OPTIONS[:mime_types] = WEBrick::HTTPUtils::load_mime_types(mime_types_file) } - - opts.on("-d", "--daemon", - "Make Rails run as a Daemon (only works if fork is available -- meaning on *nix)." - ) { OPTIONS[:server_type] = WEBrick::Daemon } - - opts.on("-c", "--charset=charset", String, - "Set default charset for output.", - "Default: UTF-8") { |OPTIONS[:charset]| } - - opts.separator "" - - opts.on("-h", "--help", - "Show this help message.") { puts opts; exit } - - opts.parse! -end - -ENV["RAILS_ENV"] = OPTIONS[:environment] -RAILS_ENV.replace(OPTIONS[:environment]) if defined?(RAILS_ENV) - -require RAILS_ROOT + "/config/environment" -require 'webrick_server' - -OPTIONS['working_directory'] = File.expand_path(RAILS_ROOT) - -puts "=> Rails application started on http://#{OPTIONS[:ip]}:#{OPTIONS[:port]}" -puts "=> Ctrl-C to shutdown server; call with --help for options" if OPTIONS[:server_type] == WEBrick::SimpleServer -DispatchServlet.dispatch(OPTIONS) diff --git a/tracks/vendor/rails/railties/lib/commands/update.rb b/tracks/vendor/rails/railties/lib/commands/update.rb deleted file mode 100644 index 83ef8333..00000000 --- a/tracks/vendor/rails/railties/lib/commands/update.rb +++ /dev/null @@ -1,4 +0,0 @@ -require "#{RAILS_ROOT}/config/environment" -require 'rails_generator' -require 'rails_generator/scripts/update' -Rails::Generator::Scripts::Update.new.run(ARGV) diff --git a/tracks/vendor/rails/railties/lib/console_sandbox.rb b/tracks/vendor/rails/railties/lib/console_sandbox.rb deleted file mode 100644 index 80f3dbc2..00000000 --- a/tracks/vendor/rails/railties/lib/console_sandbox.rb +++ /dev/null @@ -1,6 +0,0 @@ -ActiveRecord::Base.lock_mutex -ActiveRecord::Base.connection.begin_db_transaction -at_exit do - ActiveRecord::Base.connection.rollback_db_transaction - ActiveRecord::Base.unlock_mutex -end diff --git a/tracks/vendor/rails/railties/lib/dispatcher.rb b/tracks/vendor/rails/railties/lib/dispatcher.rb deleted file mode 100644 index 29dae09b..00000000 --- a/tracks/vendor/rails/railties/lib/dispatcher.rb +++ /dev/null @@ -1,99 +0,0 @@ -#-- -# Copyright (c) 2004 David Heinemeier Hansson -# -# 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. -#++ - -# This class provides an interface for dispatching a CGI (or CGI-like) request -# to the appropriate controller and action. It also takes care of resetting -# the environment (when Dependencies.load? is true) after each request. -class Dispatcher - class << self - - # Dispatch the given CGI request, using the given session options, and - # emitting the output via the given output. If you dispatch with your - # own CGI object be sure to handle the exceptions it raises on multipart - # requests (EOFError and ArgumentError). - def dispatch(cgi = nil, session_options = ActionController::CgiRequest::DEFAULT_SESSION_OPTIONS, output = $stdout) - if cgi ||= new_cgi(output) - request, response = ActionController::CgiRequest.new(cgi, session_options), ActionController::CgiResponse.new(cgi) - prepare_application - ActionController::Routing::Routes.recognize!(request).process(request, response).out(output) - end - rescue Object => exception - failsafe_response(output, '500 Internal Server Error') do - ActionController::Base.process_with_exception(request, response, exception).out(output) - end - ensure - # Do not give a failsafe response here. - reset_after_dispatch - end - - # Reset the application by clearing out loaded controllers, views, actions, - # mailers, and so forth. This allows them to be loaded again without having - # to restart the server (WEBrick, FastCGI, etc.). - def reset_application! - Controllers.clear! - Dependencies.clear - ActiveRecord::Base.reset_subclasses - Dependencies.remove_subclasses_for(ActiveRecord::Base, ActiveRecord::Observer, ActionController::Base) - Dependencies.remove_subclasses_for(ActionMailer::Base) if defined?(ActionMailer::Base) - end - - private - # CGI.new plus exception handling. CGI#read_multipart raises EOFError - # if body.empty? or body.size != Content-Length and raises ArgumentError - # if Content-Length is non-integer. - def new_cgi(output) - failsafe_response(output, '400 Bad Request') { CGI.new } - end - - def prepare_application - ActionController::Routing::Routes.reload if Dependencies.load? - prepare_breakpoint - Controllers.const_load!(:ApplicationController, "application") unless Controllers.const_defined?(:ApplicationController) - end - - def reset_after_dispatch - reset_application! if Dependencies.load? - ActiveRecord::Base.clear_connection_cache! - Breakpoint.deactivate_drb if defined?(BREAKPOINT_SERVER_PORT) - end - - def prepare_breakpoint - return unless defined?(BREAKPOINT_SERVER_PORT) - require 'breakpoint' - Breakpoint.activate_drb("druby://localhost:#{BREAKPOINT_SERVER_PORT}", nil, !defined?(FastCGI)) - true - rescue - nil - end - - # If the block raises, send status code as a last-ditch response. - def failsafe_response(output, status) - yield - rescue Object - begin - output.write "Status: #{status}\r\n" - rescue Object - end - end - end -end diff --git a/tracks/vendor/rails/railties/lib/fcgi_handler.rb b/tracks/vendor/rails/railties/lib/fcgi_handler.rb deleted file mode 100644 index 0170d690..00000000 --- a/tracks/vendor/rails/railties/lib/fcgi_handler.rb +++ /dev/null @@ -1,189 +0,0 @@ -require 'fcgi' -require 'logger' -require 'dispatcher' -require 'rbconfig' - -class RailsFCGIHandler - SIGNALS = { - 'HUP' => :reload, - 'TERM' => :exit_now, - 'USR1' => :exit, - 'USR2' => :restart - } - - attr_reader :when_ready - - attr_accessor :log_file_path - attr_accessor :gc_request_period - - - # Initialize and run the FastCGI instance, passing arguments through to new. - def self.process!(*args, &block) - new(*args, &block).process! - end - - # Initialize the FastCGI instance with the path to a crash log - # detailing unhandled exceptions (default RAILS_ROOT/log/fastcgi.crash.log) - # and the number of requests to process between garbage collection runs - # (default nil for normal GC behavior.) Optionally, pass a block which - # takes this instance as an argument for further configuration. - def initialize(log_file_path = nil, gc_request_period = nil) - self.log_file_path = log_file_path || "#{RAILS_ROOT}/log/fastcgi.crash.log" - self.gc_request_period = gc_request_period - - # Yield for additional configuration. - yield self if block_given? - - # Safely install signal handlers. - install_signal_handlers - - # Start error timestamp at 11 seconds ago. - @last_error_on = Time.now - 11 - - dispatcher_log :info, "starting" - end - - def process!(provider = FCGI) - # Make a note of $" so we can safely reload this instance. - mark! - - run_gc! if gc_request_period - - provider.each_cgi do |cgi| - process_request(cgi) - - case when_ready - when :reload - reload! - when :restart - close_connection(cgi) - restart! - when :exit - close_connection(cgi) - break - end - - gc_countdown - end - - GC.enable - dispatcher_log :info, "terminated gracefully" - - rescue SystemExit => exit_error - dispatcher_log :info, "terminated by explicit exit" - - rescue Object => fcgi_error - # retry on errors that would otherwise have terminated the FCGI process, - # but only if they occur more than 10 seconds apart. - if !(SignalException === fcgi_error) && Time.now - @last_error_on > 10 - @last_error_on = Time.now - dispatcher_error(fcgi_error, "almost killed by this error") - retry - else - dispatcher_error(fcgi_error, "killed by this error") - end - end - - - private - def logger - @logger ||= Logger.new(@log_file_path) - end - - def dispatcher_log(level, msg) - time_str = Time.now.strftime("%d/%b/%Y:%H:%M:%S") - logger.send(level, "[#{time_str} :: #{$$}] #{msg}") - rescue Object => log_error - STDERR << "Couldn't write to #{@log_file_path.inspect}: #{msg}\n" - STDERR << " #{log_error.class}: #{log_error.message}\n" - end - - def dispatcher_error(e, msg = "") - error_message = - "Dispatcher failed to catch: #{e} (#{e.class})\n" + - " #{e.backtrace.join("\n ")}\n#{msg}" - dispatcher_log(:error, error_message) - end - - def install_signal_handlers - SIGNALS.each do |signal, handler_name| - install_signal_handler(signal, method("#{handler_name}_handler").to_proc) - end - end - - def install_signal_handler(signal, handler) - trap(signal, handler) - rescue ArgumentError - dispatcher_log :warn, "Ignoring unsupported signal #{signal}." - end - - def exit_now_handler(signal) - dispatcher_log :info, "asked to terminate immediately" - exit - end - - def exit_handler(signal) - dispatcher_log :info, "asked to terminate ASAP" - @when_ready = :exit - end - - def reload_handler(signal) - dispatcher_log :info, "asked to reload ASAP" - @when_ready = :reload - end - - def restart_handler(signal) - dispatcher_log :info, "asked to restart ASAP" - @when_ready = :restart - end - - def process_request(cgi) - Dispatcher.dispatch(cgi) - rescue Object => e - raise if SignalException === e - dispatcher_error(e) - end - - def restart! - config = ::Config::CONFIG - ruby = File::join(config['bindir'], config['ruby_install_name']) + config['EXEEXT'] - command_line = [ruby, $0, ARGV].flatten.join(' ') - - dispatcher_log :info, "restarted" - - exec(command_line) - end - - def reload! - run_gc! if gc_request_period - restore! - @when_ready = nil - dispatcher_log :info, "reloaded" - end - - def mark! - @features = $".clone - end - - def restore! - $".replace @features - Dispatcher.reset_application! - ActionController::Routing::Routes.reload - end - - def run_gc! - @gc_request_countdown = gc_request_period - GC.enable; GC.start; GC.disable - end - - def gc_countdown - if gc_request_period - @gc_request_countdown -= 1 - run_gc! if @gc_request_countdown <= 0 - end - end - - def close_connection(cgi) - cgi.instance_variable_get("@request").finish - end -end \ No newline at end of file diff --git a/tracks/vendor/rails/railties/lib/initializer.rb b/tracks/vendor/rails/railties/lib/initializer.rb deleted file mode 100644 index 13837427..00000000 --- a/tracks/vendor/rails/railties/lib/initializer.rb +++ /dev/null @@ -1,553 +0,0 @@ -require 'logger' -require 'set' -require File.join(File.dirname(__FILE__), 'railties_path') - -RAILS_ENV = (ENV['RAILS_ENV'] || 'development').dup unless defined?(RAILS_ENV) - -module Rails - # The Initializer is responsible for processing the Rails configuration, such - # as setting the $LOAD_PATH, requiring the right frameworks, initializing - # logging, and more. It can be run either as a single command that'll just - # use the default configuration, like this: - # - # Rails::Initializer.run - # - # But normally it's more interesting to pass in a custom configuration - # through the block running: - # - # Rails::Initializer.run do |config| - # config.frameworks -= [ :action_web_service ] - # end - # - # This will use the default configuration options from Rails::Configuration, - # but allow for overwriting on select areas. - class Initializer - # The Configuration instance used by this Initializer instance. - attr_reader :configuration - - # The set of loaded plugins. - attr_reader :loaded_plugins - - # Runs the initializer. By default, this will invoke the #process method, - # which simply executes all of the initialization routines. Alternately, - # you can specify explicitly which initialization routine you want: - # - # Rails::Initializer.run(:set_load_path) - # - # This is useful if you only want the load path initialized, without - # incuring the overhead of completely loading the entire environment. - def self.run(command = :process, configuration = Configuration.new) - yield configuration if block_given? - initializer = new configuration - initializer.send(command) - initializer - end - - # Create a new Initializer instance that references the given Configuration - # instance. - def initialize(configuration) - @configuration = configuration - @loaded_plugins = Set.new - end - - # Sequentially step through all of the available initialization routines, - # in order: - # - # * #set_load_path - # * #set_connection_adapters - # * #require_frameworks - # * #load_environment - # * #initialize_database - # * #initialize_logger - # * #initialize_framework_logging - # * #initialize_framework_views - # * #initialize_routing - # * #initialize_dependency_mechanism - # * #initialize_breakpoints - # * #initialize_whiny_nils - # * #initialize_framework_settings - # * #load_environment - # * #load_plugins - # - # (Note that #load_environment is invoked twice, once at the start and - # once at the end, to support the legacy configuration style where the - # environment could overwrite the defaults directly, instead of via the - # Configuration instance. - def process - set_load_path - set_connection_adapters - - require_frameworks - load_environment - - initialize_database - initialize_logger - initialize_framework_logging - initialize_framework_views - initialize_dependency_mechanism - initialize_breakpoints - initialize_whiny_nils - - initialize_framework_settings - - # Support for legacy configuration style where the environment - # could overwrite anything set from the defaults/global through - # the individual base class configurations. - load_environment - - load_framework_info - - load_plugins - - # Routing must be initialized after plugins to allow the former to extend the routes - initialize_routing - end - - # Set the $LOAD_PATH based on the value of - # Configuration#load_paths. Duplicates are removed. - def set_load_path - configuration.load_paths.reverse.each { |dir| $LOAD_PATH.unshift(dir) if File.directory?(dir) } - $LOAD_PATH.uniq! - end - - # Sets the +RAILS_CONNECTION_ADAPTERS+ constant based on the value of - # Configuration#connection_adapters. This constant is used to determine - # which database adapters should be loaded (by default, all adapters are - # loaded). - def set_connection_adapters - Object.const_set("RAILS_CONNECTION_ADAPTERS", configuration.connection_adapters) if configuration.connection_adapters - end - - # Requires all frameworks specified by the Configuration#frameworks - # list. By default, all frameworks (ActiveRecord, ActiveSupport, - # ActionPack, ActionMailer, and ActionWebService) are loaded. - def require_frameworks - configuration.frameworks.each { |framework| require(framework.to_s) } - end - - # Loads Rails::VERSION and Rails::Info. - # TODO: Make this work via dependencies.rb/const_missing instead. - def load_framework_info - require 'rails_info' - end - - # Loads all plugins in config.plugin_paths. plugin_paths - # defaults to vendor/plugins but may also be set to a list of - # paths, such as - # config.plugin_paths = ['lib/plugins', 'vendor/plugins'] - # - # Each plugin discovered in plugin_paths is initialized: - # * add its +lib+ directory, if present, to the beginning of the load path - # * evaluate init.rb if present - # - # After all plugins are loaded, duplicates are removed from the load path. - def load_plugins - find_plugins(configuration.plugin_paths).each { |path| load_plugin path } - $LOAD_PATH.uniq! - end - - # Loads the environment specified by Configuration#environment_path, which - # is typically one of development, testing, or production. - def load_environment - silence_warnings do - config = configuration - constants = self.class.constants - eval(IO.read(configuration.environment_path), binding) - (self.class.constants - constants).each do |const| - Object.const_set(const, self.class.const_get(const)) - end - end - end - - # This initialization routine does nothing unless :active_record - # is one of the frameworks to load (Configuration#frameworks). If it is, - # this sets the database configuration from Configuration#database_configuration - # and then establishes the connection. - def initialize_database - return unless configuration.frameworks.include?(:active_record) - ActiveRecord::Base.configurations = configuration.database_configuration - ActiveRecord::Base.establish_connection - end - - # If the +RAILS_DEFAULT_LOGGER+ constant is already set, this initialization - # routine does nothing. If the constant is not set, and Configuration#logger - # is not +nil+, this also does nothing. Otherwise, a new logger instance - # is created at Configuration#log_path, with a default log level of - # Configuration#log_level. - # - # If the log could not be created, the log will be set to output to - # +STDERR+, with a log level of +WARN+. - def initialize_logger - # if the environment has explicitly defined a logger, use it - return if defined?(RAILS_DEFAULT_LOGGER) - - unless logger = configuration.logger - begin - logger = Logger.new(configuration.log_path) - logger.level = Logger.const_get(configuration.log_level.to_s.upcase) - rescue StandardError - logger = Logger.new(STDERR) - logger.level = Logger::WARN - logger.warn( - "Rails Error: Unable to access log file. Please ensure that #{configuration.log_path} exists and is chmod 0666. " + - "The log level has been raised to WARN and the output directed to STDERR until the problem is fixed." - ) - end - end - - silence_warnings { Object.const_set "RAILS_DEFAULT_LOGGER", logger } - end - - # Sets the logger for ActiveRecord, ActionController, and ActionMailer - # (but only for those frameworks that are to be loaded). If the framework's - # logger is already set, it is not changed, otherwise it is set to use - # +RAILS_DEFAULT_LOGGER+. - def initialize_framework_logging - for framework in ([ :active_record, :action_controller, :action_mailer ] & configuration.frameworks) - framework.to_s.camelize.constantize.const_get("Base").logger ||= RAILS_DEFAULT_LOGGER - end - end - - # Sets the +template_root+ for ActionController::Base and ActionMailer::Base - # (but only for those frameworks that are to be loaded). If the framework's - # +template_root+ has already been set, it is not changed, otherwise it is - # set to use Configuration#view_path. - def initialize_framework_views - for framework in ([ :action_controller, :action_mailer ] & configuration.frameworks) - framework.to_s.camelize.constantize.const_get("Base").template_root ||= configuration.view_path - end - end - - # If ActionController is not one of the loaded frameworks (Configuration#frameworks) - # this does nothing. Otherwise, it loads the routing definitions and sets up - # loading module used to lazily load controllers (Configuration#controller_paths). - def initialize_routing - return unless configuration.frameworks.include?(:action_controller) - ActionController::Routing::Routes.reload - Object.const_set "Controllers", Dependencies::LoadingModule.root(*configuration.controller_paths) - end - - # Sets the dependency loading mechanism based on the value of - # Configuration#cache_classes. - def initialize_dependency_mechanism - Dependencies.mechanism = configuration.cache_classes ? :require : :load - end - - # Sets the +BREAKPOINT_SERVER_PORT+ if Configuration#breakpoint_server - # is true. - def initialize_breakpoints - silence_warnings { Object.const_set("BREAKPOINT_SERVER_PORT", 42531) if configuration.breakpoint_server } - end - - # Loads support for "whiny nil" (noisy warnings when methods are invoked - # on +nil+ values) if Configuration#whiny_nils is true. - def initialize_whiny_nils - require('active_support/whiny_nil') if configuration.whiny_nils - end - - # Initialize framework-specific settings for each of the loaded frameworks - # (Configuration#frameworks). The available settings map to the accessors - # on each of the corresponding Base classes. - def initialize_framework_settings - configuration.frameworks.each do |framework| - base_class = framework.to_s.camelize.constantize.const_get("Base") - - configuration.send(framework).each do |setting, value| - base_class.send("#{setting}=", value) - end - end - end - - protected - # Return a list of plugin paths within base_path. A plugin path is - # a directory that contains either a lib directory or an init.rb file. - # This recurses into directories which are not plugin paths, so you - # may organize your plugins which the plugin path. - def find_plugins(*base_paths) - base_paths.flatten.inject([]) do |plugins, base_path| - Dir.glob(File.join(base_path, '*')).each do |path| - if plugin_path?(path) - plugins << path - elsif File.directory?(path) - plugins += find_plugins(path) - end - end - plugins - end - end - - def plugin_path?(path) - File.directory?(path) and (File.directory?(File.join(path, 'lib')) or File.file?(File.join(path, 'init.rb'))) - end - - # Load the plugin at path unless already loaded. - # - # Each plugin is initialized: - # * add its +lib+ directory, if present, to the beginning of the load path - # * evaluate init.rb if present - # - # Returns true if the plugin is successfully loaded or - # false if it is already loaded (similar to Kernel#require). - # Raises LoadError if the plugin is not found. - def load_plugin(directory) - name = File.basename(directory) - return false if loaded_plugins.include?(name) - - # Catch nonexistent and empty plugins. - raise LoadError, "No such plugin: #{directory}" unless plugin_path?(directory) - - lib_path = File.join(directory, 'lib') - init_path = File.join(directory, 'init.rb') - has_lib = File.directory?(lib_path) - has_init = File.file?(init_path) - - # Add lib to load path. - $LOAD_PATH.unshift(lib_path) if has_lib - - # Allow plugins to reference the current configuration object - config = configuration - - # Evaluate init.rb. - silence_warnings { eval(IO.read(init_path), binding, init_path) } if has_init - - # Add to set of loaded plugins. - loaded_plugins << name - true - end - end - - # The Configuration class holds all the parameters for the Initializer and - # ships with defaults that suites most Rails applications. But it's possible - # to overwrite everything. Usually, you'll create an Configuration file - # implicitly through the block running on the Initializer, but it's also - # possible to create the Configuration instance in advance and pass it in - # like this: - # - # config = Rails::Configuration.new - # Rails::Initializer.run(:process, config) - class Configuration - # A stub for setting options on ActionController::Base - attr_accessor :action_controller - - # A stub for setting options on ActionMailer::Base - attr_accessor :action_mailer - - # A stub for setting options on ActionView::Base - attr_accessor :action_view - - # A stub for setting options on ActionWebService::Base - attr_accessor :action_web_service - - # A stub for setting options on ActiveRecord::Base - attr_accessor :active_record - - # Whether or not to use the breakpoint server (boolean) - attr_accessor :breakpoint_server - - # Whether or not classes should be cached (set to false if you want - # application classes to be reloaded on each request) - attr_accessor :cache_classes - - # The list of connection adapters to load. (By default, all connection - # adapters are loaded. You can set this to be just the adapter(s) you - # will use to reduce your application's load time.) - attr_accessor :connection_adapters - - # The list of paths that should be searched for controllers. (Defaults - # to app/controllers and components.) - attr_accessor :controller_paths - - # The path to the database configuration file to use. (Defaults to - # config/database.yml.) - attr_accessor :database_configuration_file - - # The list of rails framework components that should be loaded. (Defaults - # to :active_record, :action_controller, - # :action_view, :action_mailer, and - # :action_web_service). - attr_accessor :frameworks - - # An array of additional paths to prepend to the load path. By default, - # all +app+, +lib+, +vendor+ and mock paths are included in this list. - attr_accessor :load_paths - - # The log level to use for the default Rails logger. In production mode, - # this defaults to :info. In development mode, it defaults to - # :debug. - attr_accessor :log_level - - # The path to the log file to use. Defaults to log/#{environment}.log - # (e.g. log/development.log or log/production.log). - attr_accessor :log_path - - # The specific logger to use. By default, a logger will be created and - # initialized using #log_path and #log_level, but a programmer may - # specifically set the logger to use via this accessor and it will be - # used directly. - attr_accessor :logger - - # The root of the application's views. (Defaults to app/views.) - attr_accessor :view_path - - # Set to +true+ if you want to be warned (noisily) when you try to invoke - # any method of +nil+. Set to +false+ for the standard Ruby behavior. - attr_accessor :whiny_nils - - # The path to the root of the plugins directory. By default, it is in - # vendor/plugins. - attr_accessor :plugin_paths - - # Create a new Configuration instance, initialized with the default - # values. - def initialize - self.frameworks = default_frameworks - self.load_paths = default_load_paths - self.log_path = default_log_path - self.log_level = default_log_level - self.view_path = default_view_path - self.controller_paths = default_controller_paths - self.cache_classes = default_cache_classes - self.breakpoint_server = default_breakpoint_server - self.whiny_nils = default_whiny_nils - self.plugin_paths = default_plugin_paths - self.database_configuration_file = default_database_configuration_file - - for framework in default_frameworks - self.send("#{framework}=", OrderedOptions.new) - end - end - - # Loads and returns the contents of the #database_configuration_file. The - # contents of the file are processed via ERB before being sent through - # YAML::load. - def database_configuration - YAML::load(ERB.new(IO.read(database_configuration_file)).result) - end - - # The path to the current environment's file (development.rb, etc.). By - # default the file is at config/environments/#{environment}.rb. - def environment_path - "#{root_path}/config/environments/#{environment}.rb" - end - - # Return the currently selected environment. By default, it returns the - # value of the +RAILS_ENV+ constant. - def environment - ::RAILS_ENV - end - - private - def root_path - ::RAILS_ROOT - end - - def default_frameworks - [ :active_record, :action_controller, :action_view, :action_mailer, :action_web_service ] - end - - def default_load_paths - paths = ["#{root_path}/test/mocks/#{environment}"] - - # Then model subdirectories. - # TODO: Don't include .rb models as load paths - paths.concat(Dir["#{root_path}/app/models/[_a-z]*"]) - paths.concat(Dir["#{root_path}/components/[_a-z]*"]) - - # Followed by the standard includes. - # TODO: Don't include dirs for frameworks that are not used - paths.concat %w( - app - app/models - app/controllers - app/helpers - app/services - app/apis - components - config - lib - vendor - vendor/rails/railties - vendor/rails/railties/lib - vendor/rails/actionpack/lib - vendor/rails/activesupport/lib - vendor/rails/activerecord/lib - vendor/rails/actionmailer/lib - vendor/rails/actionwebservice/lib - ).map { |dir| "#{root_path}/#{dir}" }.select { |dir| File.directory?(dir) } - end - - def default_log_path - File.join(root_path, 'log', "#{environment}.log") - end - - def default_log_level - environment == 'production' ? :info : :debug - end - - def default_database_configuration_file - File.join(root_path, 'config', 'database.yml') - end - - def default_view_path - File.join(root_path, 'app', 'views') - end - - def default_controller_paths - [ File.join(root_path, 'app', 'controllers'), File.join(root_path, 'components'), File.join(RAILTIES_PATH, 'builtin', 'controllers') ] - end - - def default_dependency_mechanism - :load - end - - def default_cache_classes - false - end - - def default_breakpoint_server - false - end - - def default_whiny_nils - false - end - - def default_plugin_paths - ["#{root_path}/vendor/plugins"] - end - end -end - -# Needs to be duplicated from Active Support since its needed before Active -# Support is available. -class OrderedOptions < Array # :nodoc: - def []=(key, value) - key = key.to_sym - - if pair = find_pair(key) - pair.pop - pair << value - else - self << [key, value] - end - end - - def [](key) - pair = find_pair(key.to_sym) - pair ? pair.last : nil - end - - def method_missing(name, *args) - if name.to_s =~ /(.*)=$/ - self[$1.to_sym] = args.first - else - self[name] - end - end - - private - def find_pair(key) - self.each { |i| return i if i.first == key } - return false - end -end diff --git a/tracks/vendor/rails/railties/lib/rails_generator.rb b/tracks/vendor/rails/railties/lib/rails_generator.rb deleted file mode 100644 index 9c587c95..00000000 --- a/tracks/vendor/rails/railties/lib/rails_generator.rb +++ /dev/null @@ -1,43 +0,0 @@ -#-- -# Copyright (c) 2004 Jeremy Kemper -# -# 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. -#++ - -$:.unshift(File.dirname(__FILE__)) -$:.unshift(File.dirname(__FILE__) + "/../../activesupport/lib") - -begin - require 'active_support' -rescue LoadError - require 'rubygems' - require_gem 'activesupport' -end - -require 'rails_generator/base' -require 'rails_generator/lookup' -require 'rails_generator/commands' - -Rails::Generator::Base.send(:include, Rails::Generator::Lookup) -Rails::Generator::Base.send(:include, Rails::Generator::Commands) - -# Set up a default logger for convenience. -require 'rails_generator/simple_logger' -Rails::Generator::Base.logger = Rails::Generator::SimpleLogger.new(STDOUT) diff --git a/tracks/vendor/rails/railties/lib/rails_generator/base.rb b/tracks/vendor/rails/railties/lib/rails_generator/base.rb deleted file mode 100644 index 6a56f96b..00000000 --- a/tracks/vendor/rails/railties/lib/rails_generator/base.rb +++ /dev/null @@ -1,203 +0,0 @@ -require File.dirname(__FILE__) + '/options' -require File.dirname(__FILE__) + '/manifest' -require File.dirname(__FILE__) + '/spec' - -# Rails::Generator is a code generation platform tailored for the Rails -# web application framework. Generators are easily invoked within Rails -# applications to add and remove components such as models and controllers. -# New generators are easy to create and may be distributed as RubyGems or -# tarballs for inclusion system-wide, per-user, or per-application. -# -# Generators may subclass other generators to provide variations that -# require little or no new logic but replace the template files. -# The postback generator is an example: it subclasses the scaffold -# generator and just replaces the code templates with its own. -# -# Now go forth and multiply^Wgenerate. -module Rails - module Generator - class GeneratorError < StandardError; end - class UsageError < GeneratorError; end - - - # The base code generator is bare-bones. It sets up the source and - # destination paths and tells the logger whether to keep its trap shut. - # You're probably looking for NamedBase, a subclass meant for generating - # "named" components such as models, controllers, and mailers. - # - # Generators create a manifest of the actions they perform then hand - # the manifest to a command which replay the actions to do the heavy - # lifting. Create, destroy, and list commands are included. Since a - # single manifest may be used by any command, creating new generators is - # as simple as writing some code templates and declaring what you'd like - # to do with them. - # - # The manifest method must be implemented by subclasses, returning a - # Rails::Generator::Manifest. The record method is provided as a - # convenience for manifest creation. Example: - # class EliteGenerator < Rails::Generator::Base - # def manifest - # record do |m| - # m.do(some) - # m.things(in) { here } - # end - # end - # end - class Base - include Options - - # Declare default options for the generator. These options - # are inherited to subclasses. - default_options :collision => :ask, :quiet => false - - # A logger instance available everywhere in the generator. - cattr_accessor :logger - - # Every generator that is dynamically looked up is tagged with a - # Spec describing where it was found. - class_inheritable_accessor :spec - - attr_reader :source_root, :destination_root, :args - - def initialize(runtime_args, runtime_options = {}) - @args = runtime_args - parse!(@args, runtime_options) - - # Derive source and destination paths. - @source_root = options[:source] || File.join(spec.path, 'templates') - if options[:destination] - @destination_root = options[:destination] - elsif defined? ::RAILS_ROOT - @destination_root = ::RAILS_ROOT - end - - # Silence the logger if requested. - logger.quiet = options[:quiet] - - # Raise usage error if help is requested. - usage if options[:help] - end - - # Generators must provide a manifest. Use the record method to create - # a new manifest and record your generator's actions. - def manifest - raise NotImplementedError, "No manifest for '#{spec.name}' generator." - end - - # Return the full path from the source root for the given path. - # Example for source_root = '/source': - # source_path('some/path.rb') == '/source/some/path.rb' - # - # The given path may include a colon ':' character to indicate that - # the file belongs to another generator. This notation allows any - # generator to borrow files from another. Example: - # source_path('model:fixture.yml') = '/model/source/path/fixture.yml' - def source_path(relative_source) - # Check whether we're referring to another generator's file. - name, path = relative_source.split(':', 2) - - # If not, return the full path to our source file. - if path.nil? - File.join(source_root, name) - - # Otherwise, ask our referral for the file. - else - # FIXME: this is broken, though almost always true. Others' - # source_root are not necessarily the templates dir. - File.join(self.class.lookup(name).path, 'templates', path) - end - end - - # Return the full path from the destination root for the given path. - # Example for destination_root = '/dest': - # destination_path('some/path.rb') == '/dest/some/path.rb' - def destination_path(relative_destination) - File.join(destination_root, relative_destination) - end - - protected - # Convenience method for generator subclasses to record a manifest. - def record - Rails::Generator::Manifest.new(self) { |m| yield m } - end - - # Override with your own usage banner. - def banner - "Usage: #{$0} #{spec.name} [options]" - end - - # Read USAGE from file in generator base path. - def usage_message - File.read(File.join(spec.path, 'USAGE')) rescue '' - end - end - - - # The base generator for named components: models, controllers, mailers, - # etc. The target name is taken as the first argument and inflected to - # singular, plural, class, file, and table forms for your convenience. - # The remaining arguments are aliased to actions for controller and - # mailer convenience. - # - # If no name is provided, the generator raises a usage error with content - # optionally read from the USAGE file in the generator's base path. - # - # See Rails::Generator::Base for a discussion of Manifests and Commands. - class NamedBase < Base - attr_reader :name, :class_name, :singular_name, :plural_name, :table_name - attr_reader :class_path, :file_path, :class_nesting, :class_nesting_depth - alias_method :file_name, :singular_name - alias_method :actions, :args - - def initialize(runtime_args, runtime_options = {}) - super - - # Name argument is required. - usage if runtime_args.empty? - - @args = runtime_args.dup - base_name = @args.shift - assign_names!(base_name) - end - - protected - # Override with your own usage banner. - def banner - "Usage: #{$0} #{spec.name} #{spec.name.camelize}Name [options]" - end - - private - def assign_names!(name) - @name = name - base_name, @class_path, @file_path, @class_nesting, @class_nesting_depth = extract_modules(@name) - @class_name_without_nesting, @singular_name, @plural_name = inflect_names(base_name) - @table_name = ActiveRecord::Base.pluralize_table_names ? plural_name : singular_name - if @class_nesting.empty? - @class_name = @class_name_without_nesting - else - @class_name = "#{@class_nesting}::#{@class_name_without_nesting}" - end - end - - # Extract modules from filesystem-style or ruby-style path: - # good/fun/stuff - # Good::Fun::Stuff - # produce the same results. - def extract_modules(name) - modules = name.include?('/') ? name.split('/') : name.split('::') - name = modules.pop - path = modules.map { |m| m.underscore } - file_path = (path + [name.underscore]).join('/') - nesting = modules.map { |m| m.camelize }.join('::') - [name, path, file_path, nesting, modules.size] - end - - def inflect_names(name) - camel = name.camelize - under = camel.underscore - plural = under.pluralize - [camel, under, plural] - end - end - end -end diff --git a/tracks/vendor/rails/railties/lib/rails_generator/commands.rb b/tracks/vendor/rails/railties/lib/rails_generator/commands.rb deleted file mode 100644 index 93d22dde..00000000 --- a/tracks/vendor/rails/railties/lib/rails_generator/commands.rb +++ /dev/null @@ -1,509 +0,0 @@ -require 'delegate' -require 'optparse' -require 'fileutils' -require 'erb' - -module Rails - module Generator - module Commands - # Here's a convenient way to get a handle on generator commands. - # Command.instance('destroy', my_generator) instantiates a Destroy - # delegate of my_generator ready to do your dirty work. - def self.instance(command, generator) - const_get(command.to_s.camelize).new(generator) - end - - # Even more convenient access to commands. Include Commands in - # the generator Base class to get a nice #command instance method - # which returns a delegate for the requested command. - def self.append_features(base) - base.send(:define_method, :command) do |command| - Commands.instance(command, self) - end - end - - - # Generator commands delegate Rails::Generator::Base and implement - # a standard set of actions. Their behavior is defined by the way - # they respond to these actions: Create brings life; Destroy brings - # death; List passively observes. - # - # Commands are invoked by replaying (or rewinding) the generator's - # manifest of actions. See Rails::Generator::Manifest and - # Rails::Generator::Base#manifest method that generator subclasses - # are required to override. - # - # Commands allows generators to "plug in" invocation behavior, which - # corresponds to the GoF Strategy pattern. - class Base < DelegateClass(Rails::Generator::Base) - # Replay action manifest. RewindBase subclass rewinds manifest. - def invoke! - manifest.replay(self) - end - - def dependency(generator_name, args, runtime_options = {}) - logger.dependency(generator_name) do - self.class.new(instance(generator_name, args, full_options(runtime_options))).invoke! - end - end - - # Does nothing for all commands except Create. - def class_collisions(*class_names) - end - - # Does nothing for all commands except Create. - def readme(*args) - end - - protected - def migration_directory(relative_path) - directory(@migration_directory = relative_path) - end - - def existing_migrations(file_name) - Dir.glob("#{@migration_directory}/[0-9]*_#{file_name}.rb") - end - - def migration_exists?(file_name) - not existing_migrations(file_name).empty? - end - - def current_migration_number - Dir.glob("#{@migration_directory}/[0-9]*.rb").inject(0) do |max, file_path| - n = File.basename(file_path).split('_', 2).first.to_i - if n > max then n else max end - end - end - - def next_migration_number - current_migration_number + 1 - end - - def next_migration_string(padding = 3) - "%.#{padding}d" % next_migration_number - end - - private - # Ask the user interactively whether to force collision. - def force_file_collision?(destination) - $stdout.print "overwrite #{destination}? [Ynaq] " - case $stdin.gets - when /a/i - $stdout.puts "forcing #{spec.name}" - options[:collision] = :force - when /q/i - $stdout.puts "aborting #{spec.name}" - raise SystemExit - when /n/i then :skip - else :force - end - rescue - retry - end - - def render_template_part(template_options) - # Getting Sandbox to evaluate part template in it - part_binding = template_options[:sandbox].call.sandbox_binding - part_rel_path = template_options[:insert] - part_path = source_path(part_rel_path) - - # Render inner template within Sandbox binding - rendered_part = ERB.new(File.readlines(part_path).join, nil, '-').result(part_binding) - begin_mark = template_part_mark(template_options[:begin_mark], template_options[:mark_id]) - end_mark = template_part_mark(template_options[:end_mark], template_options[:mark_id]) - begin_mark + rendered_part + end_mark - end - - def template_part_mark(name, id) - "\n" - end - end - - # Base class for commands which handle generator actions in reverse, such as Destroy. - class RewindBase < Base - # Rewind action manifest. - def invoke! - manifest.rewind(self) - end - end - - - # Create is the premier generator command. It copies files, creates - # directories, renders templates, and more. - class Create < Base - - # Check whether the given class names are already taken by - # Ruby or Rails. In the future, expand to check other namespaces - # such as the rest of the user's app. - def class_collisions(*class_names) - class_names.flatten.each do |class_name| - # Convert to string to allow symbol arguments. - class_name = class_name.to_s - - # Skip empty strings. - next if class_name.strip.empty? - - # Split the class from its module nesting. - nesting = class_name.split('::') - name = nesting.pop - - # Extract the last Module in the nesting. - last = nesting.inject(Object) { |last, nest| - break unless last.const_defined?(nest) - last.const_get(nest) - } - - # If the last Module exists, check whether the given - # class exists and raise a collision if so. - if last and last.const_defined?(name.camelize) - raise_class_collision(class_name) - end - end - end - - # Copy a file from source to destination with collision checking. - # - # The file_options hash accepts :chmod and :shebang options. - # :chmod sets the permissions of the destination file: - # file 'config/empty.log', 'log/test.log', :chmod => 0664 - # :shebang sets the #!/usr/bin/ruby line for scripts - # file 'bin/generate.rb', 'script/generate', :chmod => 0755, :shebang => '/usr/bin/env ruby' - # - # Collisions are handled by checking whether the destination file - # exists and either skipping the file, forcing overwrite, or asking - # the user what to do. - def file(relative_source, relative_destination, file_options = {}, &block) - # Determine full paths for source and destination files. - source = source_path(relative_source) - destination = destination_path(relative_destination) - destination_exists = File.exists?(destination) - - # If source and destination are identical then we're done. - if destination_exists and identical?(source, destination, &block) - return logger.identical(relative_destination) - end - - # Check for and resolve file collisions. - if destination_exists - - # Make a choice whether to overwrite the file. :force and - # :skip already have their mind made up, but give :ask a shot. - choice = case options[:collision].to_sym #|| :ask - when :ask then force_file_collision?(relative_destination) - when :force then :force - when :skip then :skip - else raise "Invalid collision option: #{options[:collision].inspect}" - end - - # Take action based on our choice. Bail out if we chose to - # skip the file; otherwise, log our transgression and continue. - case choice - when :force then logger.force(relative_destination) - when :skip then return(logger.skip(relative_destination)) - else raise "Invalid collision choice: #{choice}.inspect" - end - - # File doesn't exist so log its unbesmirched creation. - else - logger.create relative_destination - end - - # If we're pretending, back off now. - return if options[:pretend] - - # Write destination file with optional shebang. Yield for content - # if block given so templaters may render the source file. If a - # shebang is requested, replace the existing shebang or insert a - # new one. - File.open(destination, 'wb') do |df| - File.open(source, 'rb') do |sf| - if block_given? - df.write(yield(sf)) - else - if file_options[:shebang] - df.puts("#!#{file_options[:shebang]}") - if line = sf.gets - df.puts(line) if line !~ /^#!/ - end - end - df.write(sf.read) - end - end - end - - # Optionally change permissions. - if file_options[:chmod] - FileUtils.chmod(file_options[:chmod], destination) - end - - # Optionally add file to subversion - system("svn add #{destination}") if options[:svn] - end - - # Checks if the source and the destination file are identical. If - # passed a block then the source file is a template that needs to first - # be evaluated before being compared to the destination. - def identical?(source, destination, &block) - return false if File.directory? destination - source = block_given? ? File.open(source) {|sf| yield(sf)} : IO.read(source) - destination = IO.read(destination) - source == destination - end - - # Generate a file for a Rails application using an ERuby template. - # Looks up and evalutes a template by name and writes the result. - # - # The ERB template uses explicit trim mode to best control the - # proliferation of whitespace in generated code. <%- trims leading - # whitespace; -%> trims trailing whitespace including one newline. - # - # A hash of template options may be passed as the last argument. - # The options accepted by the file are accepted as well as :assigns, - # a hash of variable bindings. Example: - # template 'foo', 'bar', :assigns => { :action => 'view' } - # - # Template is implemented in terms of file. It calls file with a - # block which takes a file handle and returns its rendered contents. - def template(relative_source, relative_destination, template_options = {}) - file(relative_source, relative_destination, template_options) do |file| - # Evaluate any assignments in a temporary, throwaway binding. - vars = template_options[:assigns] || {} - b = binding - vars.each { |k,v| eval "#{k} = vars[:#{k}] || vars['#{k}']", b } - - # Render the source file with the temporary binding. - ERB.new(file.read, nil, '-').result(b) - end - end - - def complex_template(relative_source, relative_destination, template_options = {}) - options = template_options.dup - options[:assigns] ||= {} - options[:assigns]['template_for_inclusion'] = render_template_part(template_options) - template(relative_source, relative_destination, options) - end - - # Create a directory including any missing parent directories. - # Always directories which exist. - def directory(relative_path) - path = destination_path(relative_path) - if File.exists?(path) - logger.exists relative_path - else - logger.create relative_path - FileUtils.mkdir_p(path) unless options[:pretend] - - # Optionally add file to subversion - system("svn add #{path}") if options[:svn] - end - end - - # Display a README. - def readme(*relative_sources) - relative_sources.flatten.each do |relative_source| - logger.readme relative_source - puts File.read(source_path(relative_source)) unless options[:pretend] - end - end - - # When creating a migration, it knows to find the first available file in db/migrate and use the migration.rb template. - def migration_template(relative_source, relative_destination, template_options = {}) - migration_directory relative_destination - raise "Another migration is already named #{file_name}: #{existing_migrations(file_name).first}" if migration_exists?(file_name) - template(relative_source, "#{relative_destination}/#{next_migration_string}_#{file_name}.rb", template_options) - end - - private - # Raise a usage error with an informative WordNet suggestion. - # Thanks to Florian Gross (flgr). - def raise_class_collision(class_name) - message = <", "") - data.scan(/^Sense \d+\n.+?\n\n/m) - end - end - rescue Exception - return nil - end - end - - - # Undo the actions performed by a generator. Rewind the action - # manifest and attempt to completely erase the results of each action. - class Destroy < RewindBase - # Remove a file if it exists and is a file. - def file(relative_source, relative_destination, file_options = {}) - destination = destination_path(relative_destination) - if File.exists?(destination) - logger.rm relative_destination - unless options[:pretend] - if options[:svn] - # If the file has been marked to be added - # but has not yet been checked in, revert and delete - if options[:svn][relative_destination] - system("svn revert #{destination}") - FileUtils.rm(destination) - else - # If the directory is not in the status list, it - # has no modifications so we can simply remove it - system("svn rm #{destination}") - end - else - FileUtils.rm(destination) - end - end - else - logger.missing relative_destination - return - end - end - - # Templates are deleted just like files and the actions take the - # same parameters, so simply alias the file method. - alias_method :template, :file - - # Remove each directory in the given path from right to left. - # Remove each subdirectory if it exists and is a directory. - def directory(relative_path) - parts = relative_path.split('/') - until parts.empty? - partial = File.join(parts) - path = destination_path(partial) - if File.exists?(path) - if Dir[File.join(path, '*')].empty? - logger.rmdir partial - unless options[:pretend] - if options[:svn] - # If the directory has been marked to be added - # but has not yet been checked in, revert and delete - if options[:svn][relative_path] - system("svn revert #{path}") - FileUtils.rmdir(path) - else - # If the directory is not in the status list, it - # has no modifications so we can simply remove it - system("svn rm #{path}") - end - else - FileUtils.rmdir(path) - end - end - else - logger.notempty partial - end - else - logger.missing partial - end - parts.pop - end - end - - def complex_template(*args) - # nothing should be done here - end - - # When deleting a migration, it knows to delete every file named "[0-9]*_#{file_name}". - def migration_template(relative_source, relative_destination, template_options = {}) - migration_directory relative_destination - raise "There is no migration named #{file_name}" unless migration_exists?(file_name) - existing_migrations(file_name).each do |file_path| - file(relative_source, file_path, template_options) - end - end - end - - - # List a generator's action manifest. - class List < Base - def dependency(generator_name, args, options = {}) - logger.dependency "#{generator_name}(#{args.join(', ')}, #{options.inspect})" - end - - def class_collisions(*class_names) - logger.class_collisions class_names.join(', ') - end - - def file(relative_source, relative_destination, options = {}) - logger.file relative_destination - end - - def template(relative_source, relative_destination, options = {}) - logger.template relative_destination - end - - def complex_template(relative_source, relative_destination, options = {}) - logger.template "#{options[:insert]} inside #{relative_destination}" - end - - def directory(relative_path) - logger.directory "#{destination_path(relative_path)}/" - end - - def readme(*args) - logger.readme args.join(', ') - end - - def migration_template(relative_source, relative_destination, options = {}) - migration_directory relative_destination - logger.migration_template file_name - end - end - - # Update generator's action manifest. - class Update < Create - def file(relative_source, relative_destination, options = {}) - # logger.file relative_destination - end - - def template(relative_source, relative_destination, options = {}) - # logger.template relative_destination - end - - def complex_template(relative_source, relative_destination, template_options = {}) - - begin - dest_file = destination_path(relative_destination) - source_to_update = File.readlines(dest_file).join - rescue Errno::ENOENT - logger.missing relative_destination - return - end - - logger.refreshing "#{template_options[:insert].gsub(/\.rhtml/,'')} inside #{relative_destination}" - - begin_mark = Regexp.quote(template_part_mark(template_options[:begin_mark], template_options[:mark_id])) - end_mark = Regexp.quote(template_part_mark(template_options[:end_mark], template_options[:mark_id])) - - # Refreshing inner part of the template with freshly rendered part. - rendered_part = render_template_part(template_options) - source_to_update.gsub!(/#{begin_mark}.*?#{end_mark}/m, rendered_part) - - File.open(dest_file, 'w') { |file| file.write(source_to_update) } - end - - def directory(relative_path) - # logger.directory "#{destination_path(relative_path)}/" - end - end - - end - end -end diff --git a/tracks/vendor/rails/railties/lib/rails_generator/generators/applications/app/USAGE b/tracks/vendor/rails/railties/lib/rails_generator/generators/applications/app/USAGE deleted file mode 100644 index 3bb55113..00000000 --- a/tracks/vendor/rails/railties/lib/rails_generator/generators/applications/app/USAGE +++ /dev/null @@ -1,16 +0,0 @@ -Description: - The 'rails' command creates a new Rails application with a default - directory structure and configuration at the path you specify. - -Example: - rails ~/Code/Ruby/weblog - - This generates a skeletal Rails installation in ~/Code/Ruby/weblog. - See the README in the newly created application to get going. - -WARNING: - Only specify --without-gems if you did not use gems to install Rails. - Your application will expect to find activerecord, actionpack, and - actionmailer directories in the vendor directory. A popular way to track - the bleeding edge of Rails development is to checkout from source control - directly to the vendor directory. See http://dev.rubyonrails.com diff --git a/tracks/vendor/rails/railties/lib/rails_generator/generators/applications/app/app_generator.rb b/tracks/vendor/rails/railties/lib/rails_generator/generators/applications/app/app_generator.rb deleted file mode 100644 index 2713854b..00000000 --- a/tracks/vendor/rails/railties/lib/rails_generator/generators/applications/app/app_generator.rb +++ /dev/null @@ -1,140 +0,0 @@ -require 'rbconfig' - -class AppGenerator < Rails::Generator::Base - DEFAULT_SHEBANG = File.join(Config::CONFIG['bindir'], - Config::CONFIG['ruby_install_name']) - - default_options :gem => true, :shebang => DEFAULT_SHEBANG - mandatory_options :source => "#{File.dirname(__FILE__)}/../../../../.." - - def initialize(runtime_args, runtime_options = {}) - super - usage if args.empty? - @destination_root = args.shift - @socket = MYSQL_SOCKET_LOCATIONS.find { |f| File.exists?(f) } - @socket = '/path/to/your/mysql.sock' if @socket.blank? - end - - def manifest - script_options = { :chmod => 0755 } - dispatcher_options = { :chmod => 0755, :shebang => options[:shebang] } - - record do |m| - # Root directory and all subdirectories. - m.directory '' - BASEDIRS.each { |path| m.directory path } - - # Root - m.file "fresh_rakefile", "Rakefile" - m.file "README", "README" - - # Application - m.template "helpers/application.rb", "app/controllers/application.rb" - m.template "helpers/application_helper.rb", "app/helpers/application_helper.rb" - m.template "helpers/test_helper.rb", "test/test_helper.rb" - - # database.yml and .htaccess - m.template "configs/database.yml", "config/database.yml", :assigns => { - :app_name => File.basename(File.expand_path(@destination_root)), - :socket => @socket - } - m.template "configs/routes.rb", "config/routes.rb" - m.template "configs/apache.conf", "public/.htaccess" - - # Environments - m.file "environments/boot.rb", "config/boot.rb" - m.file "environments/environment.rb", "config/environment.rb" - m.file "environments/production.rb", "config/environments/production.rb" - m.file "environments/development.rb", "config/environments/development.rb" - m.file "environments/test.rb", "config/environments/test.rb" - - # Scripts - %w( about breakpointer console destroy generate performance/benchmarker performance/profiler process/reaper process/spawner process/spinner runner server plugin ).each do |file| - m.file "bin/#{file}", "script/#{file}", script_options - end - - # Dispatches - m.file "dispatches/dispatch.rb", "public/dispatch.rb", dispatcher_options - m.file "dispatches/dispatch.rb", "public/dispatch.cgi", dispatcher_options - m.file "dispatches/dispatch.fcgi", "public/dispatch.fcgi", dispatcher_options - - # HTML files - %w(404 500 index).each do |file| - m.template "html/#{file}.html", "public/#{file}.html" - end - - m.template "html/favicon.ico", "public/favicon.ico" - m.template "html/robots.txt", "public/robots.txt" - m.file "html/images/rails.png", "public/images/rails.png" - - # Javascripts - m.file "html/javascripts/prototype.js", "public/javascripts/prototype.js" - m.file "html/javascripts/effects.js", "public/javascripts/effects.js" - m.file "html/javascripts/dragdrop.js", "public/javascripts/dragdrop.js" - m.file "html/javascripts/controls.js", "public/javascripts/controls.js" - - # Docs - m.file "doc/README_FOR_APP", "doc/README_FOR_APP" - - # Logs - %w(server production development test).each { |file| - m.file "configs/empty.log", "log/#{file}.log", :chmod => 0666 - } - end - end - - protected - def banner - "Usage: #{$0} /path/to/your/app [options]" - end - - def add_options!(opt) - opt.separator '' - opt.separator 'Options:' - opt.on("--ruby [#{DEFAULT_SHEBANG}]", - "Path to the Ruby binary of your choice.") { |options[:shebang]| } - opt.on("--without-gems", - "Don't use the Rails gems for your app.", - "WARNING: see note below.") { |options[:gem]| } - end - - - # Installation skeleton. Intermediate directories are automatically - # created so don't sweat their absence here. - BASEDIRS = %w( - app/controllers - app/helpers - app/models - app/views/layouts - config/environments - components - db - doc - lib - lib/tasks - log - public/images - public/javascripts - public/stylesheets - script/performance - script/process - test/fixtures - test/functional - test/mocks/development - test/mocks/test - test/unit - vendor - vendor/plugins - ) - - MYSQL_SOCKET_LOCATIONS = [ - "/tmp/mysql.sock", # default - "/var/run/mysqld/mysqld.sock", # debian/gentoo - "/var/tmp/mysql.sock", # freebsd - "/var/lib/mysql/mysql.sock", # fedora - "/opt/local/lib/mysql/mysql.sock", # fedora - "/opt/local/var/run/mysqld/mysqld.sock", # mac + darwinports + mysql - "/opt/local/var/run/mysql4/mysqld.sock", # mac + darwinports + mysql4 - "/opt/local/var/run/mysql5/mysqld.sock" # mac + darwinports + mysql5 - ] -end diff --git a/tracks/vendor/rails/railties/lib/rails_generator/generators/components/controller/USAGE b/tracks/vendor/rails/railties/lib/rails_generator/generators/components/controller/USAGE deleted file mode 100644 index ec642091..00000000 --- a/tracks/vendor/rails/railties/lib/rails_generator/generators/components/controller/USAGE +++ /dev/null @@ -1,30 +0,0 @@ -Description: - The controller generator creates stubs 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 a controller class in app/controllers with view - templates in app/views/controller_name, a helper class in app/helpers, - and a functional test suite in test/functional. - -Example: - ./script/generate controller CreditCard open debit credit close - - Credit card controller with URLs like /credit_card/debit. - Controller: app/controllers/credit_card_controller.rb - Views: app/views/credit_card/debit.rhtml [...] - Helper: app/helpers/credit_card_helper.rb - Test: test/functional/credit_card_controller_test.rb - -Modules Example: - ./script/generate controller 'admin/credit_card' suspend late_fee - - Credit card admin controller with URLs /admin/credit_card/suspend. - Controller: app/controllers/admin/credit_card_controller.rb - Views: app/views/admin/credit_card/debit.rhtml [...] - Helper: app/helpers/admin/credit_card_helper.rb - Test: test/functional/admin/credit_card_controller_test.rb - diff --git a/tracks/vendor/rails/railties/lib/rails_generator/generators/components/controller/controller_generator.rb b/tracks/vendor/rails/railties/lib/rails_generator/generators/components/controller/controller_generator.rb deleted file mode 100644 index 358d3574..00000000 --- a/tracks/vendor/rails/railties/lib/rails_generator/generators/components/controller/controller_generator.rb +++ /dev/null @@ -1,38 +0,0 @@ -class ControllerGenerator < Rails::Generator::NamedBase - def manifest - record do |m| - # Check for class naming collisions. - m.class_collisions class_path, "#{class_name}Controller", "#{class_name}ControllerTest", "#{class_name}Helper" - - # Controller, helper, views, and test 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('test/functional', class_path) - - # Controller class, functional test, and helper class. - m.template 'controller.rb', - File.join('app/controllers', - class_path, - "#{file_name}_controller.rb") - - m.template 'functional_test.rb', - File.join('test/functional', - class_path, - "#{file_name}_controller_test.rb") - - m.template 'helper.rb', - File.join('app/helpers', - class_path, - "#{file_name}_helper.rb") - - # View template for each action. - actions.each do |action| - path = File.join('app/views', class_path, file_name, "#{action}.rhtml") - m.template 'view.rhtml', - path, - :assigns => { :action => action, :path => path } - end - end - end -end diff --git a/tracks/vendor/rails/railties/lib/rails_generator/generators/components/controller/templates/controller.rb b/tracks/vendor/rails/railties/lib/rails_generator/generators/components/controller/templates/controller.rb deleted file mode 100644 index da71b5f0..00000000 --- a/tracks/vendor/rails/railties/lib/rails_generator/generators/components/controller/templates/controller.rb +++ /dev/null @@ -1,10 +0,0 @@ -class <%= class_name %>Controller < ApplicationController -<% if options[:scaffold] -%> - scaffold :<%= singular_name %> -<% end -%> -<% for action in actions -%> - - def <%= action %> - end -<% end -%> -end diff --git a/tracks/vendor/rails/railties/lib/rails_generator/generators/components/controller/templates/functional_test.rb b/tracks/vendor/rails/railties/lib/rails_generator/generators/components/controller/templates/functional_test.rb deleted file mode 100644 index abe9c4cf..00000000 --- a/tracks/vendor/rails/railties/lib/rails_generator/generators/components/controller/templates/functional_test.rb +++ /dev/null @@ -1,18 +0,0 @@ -require File.dirname(__FILE__) + '<%= '/..' * class_nesting_depth %>/../test_helper' -require '<%= file_path %>_controller' - -# Re-raise errors caught by the controller. -class <%= class_name %>Controller; def rescue_action(e) raise e end; end - -class <%= class_name %>ControllerTest < Test::Unit::TestCase - def setup - @controller = <%= class_name %>Controller.new - @request = ActionController::TestRequest.new - @response = ActionController::TestResponse.new - end - - # Replace this with your real tests. - def test_truth - assert true - end -end diff --git a/tracks/vendor/rails/railties/lib/rails_generator/generators/components/controller/templates/helper.rb b/tracks/vendor/rails/railties/lib/rails_generator/generators/components/controller/templates/helper.rb deleted file mode 100644 index 3fe2ecdc..00000000 --- a/tracks/vendor/rails/railties/lib/rails_generator/generators/components/controller/templates/helper.rb +++ /dev/null @@ -1,2 +0,0 @@ -module <%= class_name %>Helper -end diff --git a/tracks/vendor/rails/railties/lib/rails_generator/generators/components/controller/templates/view.rhtml b/tracks/vendor/rails/railties/lib/rails_generator/generators/components/controller/templates/view.rhtml deleted file mode 100644 index ad85431f..00000000 --- a/tracks/vendor/rails/railties/lib/rails_generator/generators/components/controller/templates/view.rhtml +++ /dev/null @@ -1,2 +0,0 @@ -

    <%= class_name %>#<%= action %>

    -

    Find me in <%= path %>

    diff --git a/tracks/vendor/rails/railties/lib/rails_generator/generators/components/mailer/USAGE b/tracks/vendor/rails/railties/lib/rails_generator/generators/components/mailer/USAGE deleted file mode 100644 index a036998a..00000000 --- a/tracks/vendor/rails/railties/lib/rails_generator/generators/components/mailer/USAGE +++ /dev/null @@ -1,18 +0,0 @@ -Description: - The mailer generator creates stubs for a new mailer and its views. - - The generator takes a mailer name and a list of views as arguments. - The mailer name may be given in CamelCase or under_score. - - The generator creates a mailer class in app/models with view templates - in app/views/mailer_name, and a test suite with fixtures in test/unit. - -Example: - ./script/generate mailer Notifications signup forgot_password invoice - - This will create a Notifications mailer class: - Mailer: app/models/notifications.rb - Views: app/views/notifications/signup.rhtml [...] - Test: test/unit/credit_card_controller_test.rb - Fixtures: test/fixtures/notifications/signup [...] - diff --git a/tracks/vendor/rails/railties/lib/rails_generator/generators/components/mailer/mailer_generator.rb b/tracks/vendor/rails/railties/lib/rails_generator/generators/components/mailer/mailer_generator.rb deleted file mode 100644 index bac0cb01..00000000 --- a/tracks/vendor/rails/railties/lib/rails_generator/generators/components/mailer/mailer_generator.rb +++ /dev/null @@ -1,32 +0,0 @@ -class MailerGenerator < Rails::Generator::NamedBase - def manifest - record do |m| - # Check for class naming collisions. - m.class_collisions class_path, class_name, "#{class_name}Test" - - # Mailer, view, test, and fixture directories. - m.directory File.join('app/models', class_path) - m.directory File.join('app/views', class_path, file_name) - m.directory File.join('test/unit', class_path) - m.directory File.join('test/fixtures', class_path, file_name) - - # Mailer class and unit test. - m.template "mailer.rb", File.join('app/models', - class_path, - "#{file_name}.rb") - m.template "unit_test.rb", File.join('test/unit', - class_path, - "#{file_name}_test.rb") - - # View template and fixture for each action. - actions.each do |action| - m.template "view.rhtml", - File.join('app/views', class_path, file_name, "#{action}.rhtml"), - :assigns => { :action => action } - m.template "fixture.rhtml", - File.join('test/fixtures', class_path, file_name, action), - :assigns => { :action => action } - end - end - end -end diff --git a/tracks/vendor/rails/railties/lib/rails_generator/generators/components/mailer/templates/fixture.rhtml b/tracks/vendor/rails/railties/lib/rails_generator/generators/components/mailer/templates/fixture.rhtml deleted file mode 100644 index b4819068..00000000 --- a/tracks/vendor/rails/railties/lib/rails_generator/generators/components/mailer/templates/fixture.rhtml +++ /dev/null @@ -1,3 +0,0 @@ -<%= class_name %>#<%= action %> - -Find me in app/views/<%= file_name %>/<%= action %>.rhtml diff --git a/tracks/vendor/rails/railties/lib/rails_generator/generators/components/mailer/templates/mailer.rb b/tracks/vendor/rails/railties/lib/rails_generator/generators/components/mailer/templates/mailer.rb deleted file mode 100644 index 127495fc..00000000 --- a/tracks/vendor/rails/railties/lib/rails_generator/generators/components/mailer/templates/mailer.rb +++ /dev/null @@ -1,13 +0,0 @@ -class <%= class_name %> < ActionMailer::Base -<% for action in actions -%> - - def <%= action %>(sent_at = Time.now) - @subject = '<%= class_name %>#<%= action %>' - @body = {} - @recipients = '' - @from = '' - @sent_on = sent_at - @headers = {} - end -<% end -%> -end diff --git a/tracks/vendor/rails/railties/lib/rails_generator/generators/components/mailer/templates/unit_test.rb b/tracks/vendor/rails/railties/lib/rails_generator/generators/components/mailer/templates/unit_test.rb deleted file mode 100644 index 0512cad5..00000000 --- a/tracks/vendor/rails/railties/lib/rails_generator/generators/components/mailer/templates/unit_test.rb +++ /dev/null @@ -1,37 +0,0 @@ -require File.dirname(__FILE__) + '/../test_helper' -require '<%= file_name %>' - -class <%= class_name %>Test < Test::Unit::TestCase - FIXTURES_PATH = File.dirname(__FILE__) + '/../fixtures' - CHARSET = "utf-8" - - include ActionMailer::Quoting - - def setup - ActionMailer::Base.delivery_method = :test - ActionMailer::Base.perform_deliveries = true - ActionMailer::Base.deliveries = [] - - @expected = TMail::Mail.new - @expected.set_content_type "text", "plain", { "charset" => CHARSET } - end - -<% for action in actions -%> - def test_<%= action %> - @expected.subject = '<%= class_name %>#<%= action %>' - @expected.body = read_fixture('<%= action %>') - @expected.date = Time.now - - assert_equal @expected.encoded, <%= class_name %>.create_<%= action %>(@expected.date).encoded - end - -<% end -%> - private - def read_fixture(action) - IO.readlines("#{FIXTURES_PATH}/<%= file_name %>/#{action}") - end - - def encode(subject) - quoted_printable(subject, CHARSET) - end -end diff --git a/tracks/vendor/rails/railties/lib/rails_generator/generators/components/mailer/templates/view.rhtml b/tracks/vendor/rails/railties/lib/rails_generator/generators/components/mailer/templates/view.rhtml deleted file mode 100644 index b4819068..00000000 --- a/tracks/vendor/rails/railties/lib/rails_generator/generators/components/mailer/templates/view.rhtml +++ /dev/null @@ -1,3 +0,0 @@ -<%= class_name %>#<%= action %> - -Find me in app/views/<%= file_name %>/<%= action %>.rhtml diff --git a/tracks/vendor/rails/railties/lib/rails_generator/generators/components/migration/USAGE b/tracks/vendor/rails/railties/lib/rails_generator/generators/components/migration/USAGE deleted file mode 100644 index 5487d3a3..00000000 --- a/tracks/vendor/rails/railties/lib/rails_generator/generators/components/migration/USAGE +++ /dev/null @@ -1,14 +0,0 @@ -Description: - The migration generator creates a stub for a new database migration. - - The generator takes a migration name as its argument. The migration name may be - given in CamelCase or under_score. - - The generator creates a migration class in db/migrate prefixed by its number - in the queue. - -Example: - ./script/generate migration AddSslFlag - - With 4 existing migrations, this will create an AddSslFlag migration in the - file db/migrate/5_add_ssl_flag.rb \ No newline at end of file diff --git a/tracks/vendor/rails/railties/lib/rails_generator/generators/components/migration/migration_generator.rb b/tracks/vendor/rails/railties/lib/rails_generator/generators/components/migration/migration_generator.rb deleted file mode 100644 index a0d0d472..00000000 --- a/tracks/vendor/rails/railties/lib/rails_generator/generators/components/migration/migration_generator.rb +++ /dev/null @@ -1,7 +0,0 @@ -class MigrationGenerator < Rails::Generator::NamedBase - def manifest - record do |m| - m.migration_template 'migration.rb', 'db/migrate' - end - end -end diff --git a/tracks/vendor/rails/railties/lib/rails_generator/generators/components/migration/templates/migration.rb b/tracks/vendor/rails/railties/lib/rails_generator/generators/components/migration/templates/migration.rb deleted file mode 100644 index 9d0e5306..00000000 --- a/tracks/vendor/rails/railties/lib/rails_generator/generators/components/migration/templates/migration.rb +++ /dev/null @@ -1,7 +0,0 @@ -class <%= class_name %> < ActiveRecord::Migration - def self.up - end - - def self.down - end -end diff --git a/tracks/vendor/rails/railties/lib/rails_generator/generators/components/model/USAGE b/tracks/vendor/rails/railties/lib/rails_generator/generators/components/model/USAGE deleted file mode 100644 index 9d5a2fd7..00000000 --- a/tracks/vendor/rails/railties/lib/rails_generator/generators/components/model/USAGE +++ /dev/null @@ -1,17 +0,0 @@ -Description: - The 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, a test suite in - test/unit, and test fixtures in test/fixtures/singular_name.yml. - -Example: - ./script/generate model Account - - This will create an Account model: - Model: app/models/account.rb - Test: test/unit/account_test.rb - Fixtures: test/fixtures/accounts.yml - diff --git a/tracks/vendor/rails/railties/lib/rails_generator/generators/components/model/model_generator.rb b/tracks/vendor/rails/railties/lib/rails_generator/generators/components/model/model_generator.rb deleted file mode 100644 index a978b96b..00000000 --- a/tracks/vendor/rails/railties/lib/rails_generator/generators/components/model/model_generator.rb +++ /dev/null @@ -1,18 +0,0 @@ -class ModelGenerator < Rails::Generator::NamedBase - def manifest - record do |m| - # Check for class naming collisions. - m.class_collisions class_path, class_name, "#{class_name}Test" - - # Model, test, and fixture directories. - m.directory File.join('app/models', class_path) - m.directory File.join('test/unit', class_path) - m.directory File.join('test/fixtures', class_path) - - # Model class, unit test, and fixtures. - m.template 'model.rb', File.join('app/models', class_path, "#{file_name}.rb") - m.template 'unit_test.rb', File.join('test/unit', class_path, "#{file_name}_test.rb") - m.template 'fixtures.yml', File.join('test/fixtures', class_path, "#{table_name}.yml") - end - end -end diff --git a/tracks/vendor/rails/railties/lib/rails_generator/generators/components/model/templates/fixtures.yml b/tracks/vendor/rails/railties/lib/rails_generator/generators/components/model/templates/fixtures.yml deleted file mode 100644 index 8794d28a..00000000 --- a/tracks/vendor/rails/railties/lib/rails_generator/generators/components/model/templates/fixtures.yml +++ /dev/null @@ -1,5 +0,0 @@ -# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html -first: - id: 1 -another: - id: 2 diff --git a/tracks/vendor/rails/railties/lib/rails_generator/generators/components/model/templates/model.rb b/tracks/vendor/rails/railties/lib/rails_generator/generators/components/model/templates/model.rb deleted file mode 100644 index 8d4c89e9..00000000 --- a/tracks/vendor/rails/railties/lib/rails_generator/generators/components/model/templates/model.rb +++ /dev/null @@ -1,2 +0,0 @@ -class <%= class_name %> < ActiveRecord::Base -end diff --git a/tracks/vendor/rails/railties/lib/rails_generator/generators/components/model/templates/unit_test.rb b/tracks/vendor/rails/railties/lib/rails_generator/generators/components/model/templates/unit_test.rb deleted file mode 100644 index 1c19cde7..00000000 --- a/tracks/vendor/rails/railties/lib/rails_generator/generators/components/model/templates/unit_test.rb +++ /dev/null @@ -1,10 +0,0 @@ -require File.dirname(__FILE__) + '<%= '/..' * class_nesting_depth %>/../test_helper' - -class <%= class_name %>Test < Test::Unit::TestCase - fixtures :<%= table_name %> - - # Replace this with your real tests. - def test_truth - assert_kind_of <%= class_name %>, <%= table_name %>(:first) - end -end diff --git a/tracks/vendor/rails/railties/lib/rails_generator/generators/components/plugin/USAGE b/tracks/vendor/rails/railties/lib/rails_generator/generators/components/plugin/USAGE deleted file mode 100644 index e858ada9..00000000 --- a/tracks/vendor/rails/railties/lib/rails_generator/generators/components/plugin/USAGE +++ /dev/null @@ -1,33 +0,0 @@ -Description: - The plugin generator creates stubs for a new plugin. - - The generator takes a plugin name as its argument. The plugin name may be - given in CamelCase or under_score and should not be suffixed with 'Plugin'. - - The generator creates a plugin directory in vendor/plugins that includes - both init.rb and README files as well as lib, task, and test directories. - - It's also possible to generate stub files for a generator to go with the - plugin by using --with-generator - -Example: - ./script/generate plugin BrowserFilters - - This will create: - vendor/plugins/browser_filters/README - vendor/plugins/browser_filters/init.rb - vendor/plugins/browser_filters/lib/browser_filters.rb - vendor/plugins/browser_filters/test/browser_filters_test.rb - vendor/plugins/browser_filters/tasks/browser_filters_tasks.rake - - ./script/generate plugin BrowserFilters --with-generator - - This will create: - vendor/plugins/browser_filters/README - vendor/plugins/browser_filters/init.rb - vendor/plugins/browser_filters/lib/browser_filters.rb - vendor/plugins/browser_filters/test/browser_filters_test.rb - vendor/plugins/browser_filters/tasks/browser_filters_tasks.rake - vendor/plugins/browser_filters/generators/browser_filters/browser_filters_generator.rb - vendor/plugins/browser_filters/generators/browser_filters/USAGE - vendor/plugins/browser_filters/generators/browser_filters/templates/ \ No newline at end of file diff --git a/tracks/vendor/rails/railties/lib/rails_generator/generators/components/plugin/plugin_generator.rb b/tracks/vendor/rails/railties/lib/rails_generator/generators/components/plugin/plugin_generator.rb deleted file mode 100644 index 18ac5a1c..00000000 --- a/tracks/vendor/rails/railties/lib/rails_generator/generators/components/plugin/plugin_generator.rb +++ /dev/null @@ -1,33 +0,0 @@ -class PluginGenerator < Rails::Generator::NamedBase - attr_reader :plugin_path - - def initialize(runtime_args, runtime_options = {}) - @with_generator = runtime_args.delete("--with-generator") - super - @plugin_path = "vendor/plugins/#{file_name}" - end - - def manifest - record do |m| - m.directory "#{plugin_path}/lib" - m.directory "#{plugin_path}/tasks" - m.directory "#{plugin_path}/test" - - m.template 'README', "#{plugin_path}/README" - m.template 'Rakefile', "#{plugin_path}/Rakefile" - m.template 'init.rb', "#{plugin_path}/init.rb" - m.template 'plugin.rb', "#{plugin_path}/lib/#{file_name}.rb" - m.template 'tasks.rake', "#{plugin_path}/tasks/#{file_name}_tasks.rake" - m.template 'unit_test.rb', "#{plugin_path}/test/#{file_name}_test.rb" - - if @with_generator - m.directory "#{plugin_path}/generators" - m.directory "#{plugin_path}/generators/#{file_name}" - m.directory "#{plugin_path}/generators/#{file_name}/templates" - - m.template 'generator.rb', "#{plugin_path}/generators/#{file_name}/#{file_name}_generator.rb" - m.template 'USAGE', "#{plugin_path}/generators/#{file_name}/USAGE" - end - end - end -end diff --git a/tracks/vendor/rails/railties/lib/rails_generator/generators/components/plugin/templates/README b/tracks/vendor/rails/railties/lib/rails_generator/generators/components/plugin/templates/README deleted file mode 100644 index d7276413..00000000 --- a/tracks/vendor/rails/railties/lib/rails_generator/generators/components/plugin/templates/README +++ /dev/null @@ -1,4 +0,0 @@ -<%= class_name %> -<%= "=" * class_name.size %> - -Description goes here \ No newline at end of file diff --git a/tracks/vendor/rails/railties/lib/rails_generator/generators/components/plugin/templates/Rakefile b/tracks/vendor/rails/railties/lib/rails_generator/generators/components/plugin/templates/Rakefile deleted file mode 100644 index 06910508..00000000 --- a/tracks/vendor/rails/railties/lib/rails_generator/generators/components/plugin/templates/Rakefile +++ /dev/null @@ -1,22 +0,0 @@ -require 'rake' -require 'rake/testtask' -require 'rake/rdoctask' - -desc 'Default: run unit tests.' -task :default => :test - -desc 'Test the <%= file_name %> plugin.' -Rake::TestTask.new(:test) do |t| - t.libs << 'lib' - t.pattern = 'test/**/*_test.rb' - t.verbose = true -end - -desc 'Generate documentation for the <%= file_name %> plugin.' -Rake::RDocTask.new(:rdoc) do |rdoc| - rdoc.rdoc_dir = 'rdoc' - rdoc.title = '<%= class_name %>' - rdoc.options << '--line-numbers --inline-source' - rdoc.rdoc_files.include('README') - rdoc.rdoc_files.include('lib/**/*.rb') -end diff --git a/tracks/vendor/rails/railties/lib/rails_generator/generators/components/plugin/templates/USAGE b/tracks/vendor/rails/railties/lib/rails_generator/generators/components/plugin/templates/USAGE deleted file mode 100644 index f9277994..00000000 --- a/tracks/vendor/rails/railties/lib/rails_generator/generators/components/plugin/templates/USAGE +++ /dev/null @@ -1,8 +0,0 @@ -Description: - Explain the generator - -Example: - ./script/generate <%= file_name %> Thing - - This will create: - what/will/it/create \ No newline at end of file diff --git a/tracks/vendor/rails/railties/lib/rails_generator/generators/components/plugin/templates/generator.rb b/tracks/vendor/rails/railties/lib/rails_generator/generators/components/plugin/templates/generator.rb deleted file mode 100644 index 3e800df6..00000000 --- a/tracks/vendor/rails/railties/lib/rails_generator/generators/components/plugin/templates/generator.rb +++ /dev/null @@ -1,8 +0,0 @@ -class <%= class_name %>Generator < Rails::Generator::NamedBase - def manifest - record do |m| - # m.directory "lib" - # m.template 'README', "README" - end - end -end diff --git a/tracks/vendor/rails/railties/lib/rails_generator/generators/components/plugin/templates/init.rb b/tracks/vendor/rails/railties/lib/rails_generator/generators/components/plugin/templates/init.rb deleted file mode 100644 index ada2eece..00000000 --- a/tracks/vendor/rails/railties/lib/rails_generator/generators/components/plugin/templates/init.rb +++ /dev/null @@ -1 +0,0 @@ -# Include hook code here \ No newline at end of file diff --git a/tracks/vendor/rails/railties/lib/rails_generator/generators/components/plugin/templates/plugin.rb b/tracks/vendor/rails/railties/lib/rails_generator/generators/components/plugin/templates/plugin.rb deleted file mode 100644 index 1fa5b902..00000000 --- a/tracks/vendor/rails/railties/lib/rails_generator/generators/components/plugin/templates/plugin.rb +++ /dev/null @@ -1 +0,0 @@ -# <%= class_name %> \ No newline at end of file diff --git a/tracks/vendor/rails/railties/lib/rails_generator/generators/components/plugin/templates/tasks.rake b/tracks/vendor/rails/railties/lib/rails_generator/generators/components/plugin/templates/tasks.rake deleted file mode 100644 index 5222b22c..00000000 --- a/tracks/vendor/rails/railties/lib/rails_generator/generators/components/plugin/templates/tasks.rake +++ /dev/null @@ -1,4 +0,0 @@ -# desc "Explaining what the task does" -# task :<%= file_name %> do -# # Task goes here -# end \ No newline at end of file diff --git a/tracks/vendor/rails/railties/lib/rails_generator/generators/components/plugin/templates/unit_test.rb b/tracks/vendor/rails/railties/lib/rails_generator/generators/components/plugin/templates/unit_test.rb deleted file mode 100644 index 9028b84b..00000000 --- a/tracks/vendor/rails/railties/lib/rails_generator/generators/components/plugin/templates/unit_test.rb +++ /dev/null @@ -1,8 +0,0 @@ -require 'test/unit' - -class <%= class_name %>Test < Test::Unit::TestCase - # Replace this with your real tests. - def test_this_plugin - flunk - end -end diff --git a/tracks/vendor/rails/railties/lib/rails_generator/generators/components/scaffold/USAGE b/tracks/vendor/rails/railties/lib/rails_generator/generators/components/scaffold/USAGE deleted file mode 100644 index 1b6eaa2d..00000000 --- a/tracks/vendor/rails/railties/lib/rails_generator/generators/components/scaffold/USAGE +++ /dev/null @@ -1,32 +0,0 @@ -Description: - The scaffold generator creates a controller to interact with a model. - If the model does not exist, it creates the model as well. The generated - code is equivalent to the "scaffold :model" declaration, making it easy - to migrate when you wish to customize your controller and views. - - The generator takes a model name, an optional controller name, and a - list of views as arguments. Scaffolded actions and views are created - automatically. Any views left over generate empty stubs. - - The scaffolded actions and views are: - index, list, show, new, create, edit, update, destroy - - If a controller name is not given, the plural form of the model name - will be used. The model and controller names may be given in CamelCase - or under_score and should not be suffixed with 'Model' or 'Controller'. - Both model and controller names may be prefixed with a module like a - file path; see the Modules Example for usage. - -Example: - ./script/generate scaffold Account Bank debit credit - - This will generate an Account model and BankController with a full test - suite and a basic user interface. Now create the accounts table in your - database and browse to http://localhost/bank/ -- voila, you're on Rails! - -Modules Example: - ./script/generate scaffold CreditCard 'admin/credit_card' suspend late_fee - - This will generate a CreditCard model and CreditCardController controller - in the admin module. - diff --git a/tracks/vendor/rails/railties/lib/rails_generator/generators/components/scaffold/scaffold_generator.rb b/tracks/vendor/rails/railties/lib/rails_generator/generators/components/scaffold/scaffold_generator.rb deleted file mode 100644 index e589a9e2..00000000 --- a/tracks/vendor/rails/railties/lib/rails_generator/generators/components/scaffold/scaffold_generator.rb +++ /dev/null @@ -1,184 +0,0 @@ -class ScaffoldingSandbox - include ActionView::Helpers::ActiveRecordHelper - - attr_accessor :form_action, :singular_name, :suffix, :model_instance - - def sandbox_binding - binding - end - - def default_input_block - Proc.new { |record, column| "


    \n#{input(record, column.name)}

    \n" } - end - -end - -class ActionView::Helpers::InstanceTag - def to_input_field_tag(field_type, options={}) - field_meth = "#{field_type}_field" - "<%= #{field_meth} '#{@object_name}', '#{@method_name}' #{options.empty? ? '' : ', '+options.inspect} %>" - end - - def to_text_area_tag(options = {}) - "<%= text_area '#{@object_name}', '#{@method_name}' #{options.empty? ? '' : ', '+ options.inspect} %>" - end - - def to_date_select_tag(options = {}) - "<%= date_select '#{@object_name}', '#{@method_name}' #{options.empty? ? '' : ', '+ options.inspect} %>" - end - - def to_datetime_select_tag(options = {}) - "<%= datetime_select '#{@object_name}', '#{@method_name}' #{options.empty? ? '' : ', '+ options.inspect} %>" - end -end - -class ScaffoldGenerator < Rails::Generator::NamedBase - 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 - alias_method :controller_file_name, :controller_singular_name - alias_method :controller_table_name, :controller_plural_name - - def initialize(runtime_args, runtime_options = {}) - super - - # Take controller name from the next argument. Default to the pluralized model name. - @controller_name = args.shift - @controller_name ||= ActiveRecord::Base.pluralize_table_names ? @name.pluralize : @name - - 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 - end - - def manifest - record do |m| - # Check for class naming collisions. - m.class_collisions controller_class_path, "#{controller_class_name}Controller", "#{controller_class_name}ControllerTest", "#{controller_class_name}Helper" - - # Controller, helper, views, and test directories. - 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('test/functional', controller_class_path) - - # Depend on model generator but skip if the model exists. - m.dependency 'model', [singular_name], :collision => :skip - - # Scaffolded forms. - m.complex_template "form.rhtml", - File.join('app/views', - controller_class_path, - controller_file_name, - "_form.rhtml"), - :insert => 'form_scaffolding.rhtml', - :sandbox => lambda { create_sandbox }, - :begin_mark => 'form', - :end_mark => 'eoform', - :mark_id => singular_name - - - # Scaffolded views. - scaffold_views.each do |action| - m.template "view_#{action}.rhtml", - File.join('app/views', - controller_class_path, - controller_file_name, - "#{action}.rhtml"), - :assigns => { :action => action } - end - - # Controller class, functional test, helper, and views. - m.template 'controller.rb', - File.join('app/controllers', - controller_class_path, - "#{controller_file_name}_controller.rb") - - m.template 'functional_test.rb', - File.join('test/functional', - controller_class_path, - "#{controller_file_name}_controller_test.rb") - - m.template 'helper.rb', - File.join('app/helpers', - controller_class_path, - "#{controller_file_name}_helper.rb") - - # Layout and stylesheet. - m.template 'layout.rhtml', "app/views/layouts/#{controller_file_name}.rhtml" - m.template 'style.css', 'public/stylesheets/scaffold.css' - - - # Unscaffolded views. - unscaffolded_actions.each do |action| - path = File.join('app/views', - controller_class_path, - controller_file_name, - "#{action}.rhtml") - m.template "controller:view.rhtml", path, - :assigns => { :action => action, :path => path} - end - end - end - - protected - # Override with your own usage banner. - def banner - "Usage: #{$0} scaffold ModelName [ControllerName] [action, ...]" - end - - def scaffold_views - %w(list show new edit) - end - - def scaffold_actions - scaffold_views + %w(index create update destroy) - end - - def model_name - class_name.demodulize - end - - def unscaffolded_actions - args - scaffold_actions - end - - def suffix - "_#{singular_name}" if options[:suffix] - end - - def create_sandbox - sandbox = ScaffoldingSandbox.new - sandbox.singular_name = singular_name - begin - sandbox.model_instance = model_instance - sandbox.instance_variable_set("@#{singular_name}", sandbox.model_instance) - rescue ActiveRecord::StatementInvalid => e - logger.error "Before updating scaffolding from new DB schema, try creating a table for your model (#{class_name})" - raise SystemExit - end - sandbox.suffix = suffix - sandbox - end - - def model_instance - base = class_nesting.split('::').inject(Object) do |base, nested| - break base.const_get(nested) if base.const_defined?(nested) - base.const_set(nested, Module.new) - end - unless base.const_defined?(@class_name_without_nesting) - base.const_set(@class_name_without_nesting, Class.new(ActiveRecord::Base)) - end - class_name.constantize.new - end -end diff --git a/tracks/vendor/rails/railties/lib/rails_generator/generators/components/scaffold/templates/controller.rb b/tracks/vendor/rails/railties/lib/rails_generator/generators/components/scaffold/templates/controller.rb deleted file mode 100644 index ddc03e63..00000000 --- a/tracks/vendor/rails/railties/lib/rails_generator/generators/components/scaffold/templates/controller.rb +++ /dev/null @@ -1,54 +0,0 @@ -class <%= controller_class_name %>Controller < ApplicationController -<% unless suffix -%> - def index - list - render :action => 'list' - end -<% end -%> - -<% for action in unscaffolded_actions -%> - def <%= action %><%= suffix %> - end - -<% end -%> - def list<%= suffix %> - @<%= singular_name %>_pages, @<%= plural_name %> = paginate :<%= plural_name %>, :per_page => 10 - end - - def show<%= suffix %> - @<%= singular_name %> = <%= model_name %>.find(params[:id]) - end - - def new<%= suffix %> - @<%= singular_name %> = <%= model_name %>.new - end - - def create<%= suffix %> - @<%= singular_name %> = <%= model_name %>.new(params[:<%= singular_name %>]) - if @<%= singular_name %>.save - flash[:notice] = '<%= model_name %> was successfully created.' - redirect_to :action => 'list<%= suffix %>' - else - render :action => 'new<%= suffix %>' - end - end - - def edit<%= suffix %> - @<%= singular_name %> = <%= model_name %>.find(params[:id]) - end - - def update - @<%= singular_name %> = <%= model_name %>.find(params[:id]) - if @<%= singular_name %>.update_attributes(params[:<%= singular_name %>]) - flash[:notice] = '<%= model_name %> was successfully updated.' - redirect_to :action => 'show<%= suffix %>', :id => @<%= singular_name %> - else - render :action => 'edit<%= suffix %>' - end - end - - def destroy<%= suffix %> - <%= model_name %>.find(params[:id]).destroy - redirect_to :action => 'list<%= suffix %>' - end -end diff --git a/tracks/vendor/rails/railties/lib/rails_generator/generators/components/scaffold/templates/form.rhtml b/tracks/vendor/rails/railties/lib/rails_generator/generators/components/scaffold/templates/form.rhtml deleted file mode 100644 index d15f0d4e..00000000 --- a/tracks/vendor/rails/railties/lib/rails_generator/generators/components/scaffold/templates/form.rhtml +++ /dev/null @@ -1,3 +0,0 @@ -<%%= error_messages_for '<%= singular_name %>' %> - -<%= template_for_inclusion %> diff --git a/tracks/vendor/rails/railties/lib/rails_generator/generators/components/scaffold/templates/form_scaffolding.rhtml b/tracks/vendor/rails/railties/lib/rails_generator/generators/components/scaffold/templates/form_scaffolding.rhtml deleted file mode 100644 index c7a87553..00000000 --- a/tracks/vendor/rails/railties/lib/rails_generator/generators/components/scaffold/templates/form_scaffolding.rhtml +++ /dev/null @@ -1 +0,0 @@ -<%= all_input_tags(@model_instance, @singular_name, {}) %> \ No newline at end of file diff --git a/tracks/vendor/rails/railties/lib/rails_generator/generators/components/scaffold/templates/functional_test.rb b/tracks/vendor/rails/railties/lib/rails_generator/generators/components/scaffold/templates/functional_test.rb deleted file mode 100644 index 3441b566..00000000 --- a/tracks/vendor/rails/railties/lib/rails_generator/generators/components/scaffold/templates/functional_test.rb +++ /dev/null @@ -1,98 +0,0 @@ -require File.dirname(__FILE__) + '<%= "/.." * controller_class_nesting_depth %>/../test_helper' -require '<%= controller_file_path %>_controller' - -# Re-raise errors caught by the controller. -class <%= controller_class_name %>Controller; def rescue_action(e) raise e end; end - -class <%= controller_class_name %>ControllerTest < Test::Unit::TestCase - fixtures :<%= table_name %> - - def setup - @controller = <%= controller_class_name %>Controller.new - @request = ActionController::TestRequest.new - @response = ActionController::TestResponse.new - end - -<% for action in unscaffolded_actions -%> - def test_<%= action %> - get :<%= action %> - assert_response :success - assert_template '<%= action %>' - end - -<% end -%> -<% unless suffix -%> - def test_index - get :index - assert_response :success - assert_template 'list' - end - -<% end -%> - def test_list<%= suffix %> - get :list<%= suffix %> - - assert_response :success - assert_template 'list<%= suffix %>' - - assert_not_nil assigns(:<%= plural_name %>) - end - - def test_show<%= suffix %> - get :show<%= suffix %>, :id => 1 - - assert_response :success - assert_template 'show' - - assert_not_nil assigns(:<%= singular_name %>) - assert assigns(:<%= singular_name %>).valid? - end - - def test_new<%= suffix %> - get :new<%= suffix %> - - assert_response :success - assert_template 'new<%= suffix %>' - - assert_not_nil assigns(:<%= singular_name %>) - end - - def test_create - num_<%= plural_name %> = <%= model_name %>.count - - post :create<%= suffix %>, :<%= singular_name %> => {} - - assert_response :redirect - assert_redirected_to :action => 'list<%= suffix %>' - - assert_equal num_<%= plural_name %> + 1, <%= model_name %>.count - end - - def test_edit<%= suffix %> - get :edit<%= suffix %>, :id => 1 - - assert_response :success - assert_template 'edit<%= suffix %>' - - assert_not_nil assigns(:<%= singular_name %>) - assert assigns(:<%= singular_name %>).valid? - end - - def test_update<%= suffix %> - post :update<%= suffix %>, :id => 1 - assert_response :redirect - assert_redirected_to :action => 'show<%= suffix %>', :id => 1 - end - - def test_destroy<%= suffix %> - assert_not_nil <%= model_name %>.find(1) - - post :destroy, :id => 1 - assert_response :redirect - assert_redirected_to :action => 'list<%= suffix %>' - - assert_raise(ActiveRecord::RecordNotFound) { - <%= model_name %>.find(1) - } - end -end diff --git a/tracks/vendor/rails/railties/lib/rails_generator/generators/components/scaffold/templates/helper.rb b/tracks/vendor/rails/railties/lib/rails_generator/generators/components/scaffold/templates/helper.rb deleted file mode 100644 index 9bd821b1..00000000 --- a/tracks/vendor/rails/railties/lib/rails_generator/generators/components/scaffold/templates/helper.rb +++ /dev/null @@ -1,2 +0,0 @@ -module <%= controller_class_name %>Helper -end diff --git a/tracks/vendor/rails/railties/lib/rails_generator/generators/components/scaffold/templates/layout.rhtml b/tracks/vendor/rails/railties/lib/rails_generator/generators/components/scaffold/templates/layout.rhtml deleted file mode 100644 index 3e969b9a..00000000 --- a/tracks/vendor/rails/railties/lib/rails_generator/generators/components/scaffold/templates/layout.rhtml +++ /dev/null @@ -1,13 +0,0 @@ - - - <%= controller_class_name %>: <%%= controller.action_name %> - <%%= stylesheet_link_tag 'scaffold' %> - - - -

    <%%= flash[:notice] %>

    - -<%%= @content_for_layout %> - - - diff --git a/tracks/vendor/rails/railties/lib/rails_generator/generators/components/scaffold/templates/style.css b/tracks/vendor/rails/railties/lib/rails_generator/generators/components/scaffold/templates/style.css deleted file mode 100644 index de2ccc57..00000000 --- a/tracks/vendor/rails/railties/lib/rails_generator/generators/components/scaffold/templates/style.css +++ /dev/null @@ -1,74 +0,0 @@ -body { background-color: #fff; color: #333; } - -body, p, ol, ul, td { - font-family: verdana, arial, helvetica, sans-serif; - font-size: 13px; - line-height: 18px; -} - -pre { - background-color: #eee; - padding: 10px; - font-size: 11px; -} - -a { color: #000; } -a:visited { color: #666; } -a:hover { color: #fff; background-color:#000; } - -.fieldWithErrors { - padding: 2px; - background-color: red; - display: table; -} - -#ErrorExplanation { - width: 400px; - border: 2px solid red; - padding: 7px; - padding-bottom: 12px; - margin-bottom: 20px; - background-color: #f0f0f0; -} - -#ErrorExplanation h2 { - text-align: left; - font-weight: bold; - padding: 5px 5px 5px 15px; - font-size: 12px; - margin: -7px; - background-color: #c00; - color: #fff; -} - -#ErrorExplanation p { - color: #333; - margin-bottom: 0; - padding: 5px; -} - -#ErrorExplanation ul li { - font-size: 12px; - list-style: square; -} - -div.uploadStatus { - margin: 5px; -} - -div.progressBar { - margin: 5px; -} - -div.progressBar div.border { - background-color: #fff; - border: 1px solid grey; - width: 100%; -} - -div.progressBar div.background { - background-color: #333; - height: 18px; - width: 0%; -} - diff --git a/tracks/vendor/rails/railties/lib/rails_generator/generators/components/scaffold/templates/view_edit.rhtml b/tracks/vendor/rails/railties/lib/rails_generator/generators/components/scaffold/templates/view_edit.rhtml deleted file mode 100644 index 2db0909c..00000000 --- a/tracks/vendor/rails/railties/lib/rails_generator/generators/components/scaffold/templates/view_edit.rhtml +++ /dev/null @@ -1,9 +0,0 @@ -

    Editing <%= singular_name %>

    - -<%%= start_form_tag :action => 'update<%= @suffix %>', :id => @<%= singular_name %> %> - <%%= render :partial => 'form' %> - <%%= submit_tag 'Edit' %> -<%%= end_form_tag %> - -<%%= link_to 'Show', :action => 'show<%= suffix %>', :id => @<%= singular_name %> %> | -<%%= link_to 'Back', :action => 'list<%= suffix %>' %> diff --git a/tracks/vendor/rails/railties/lib/rails_generator/generators/components/scaffold/templates/view_list.rhtml b/tracks/vendor/rails/railties/lib/rails_generator/generators/components/scaffold/templates/view_list.rhtml deleted file mode 100644 index 09d5f87c..00000000 --- a/tracks/vendor/rails/railties/lib/rails_generator/generators/components/scaffold/templates/view_list.rhtml +++ /dev/null @@ -1,27 +0,0 @@ -

    Listing <%= plural_name %>

    - - - - <%% for column in <%= model_name %>.content_columns %> - - <%% end %> - - -<%% for <%= singular_name %> in @<%= plural_name %> %> - - <%% for column in <%= model_name %>.content_columns %> - - <%% end %> - - - - -<%% end %> -
    <%%= column.human_name %>
    <%%=h <%= singular_name %>.send(column.name) %><%%= link_to 'Show', :action => 'show<%= suffix %>', :id => <%= singular_name %> %><%%= link_to 'Edit', :action => 'edit<%= suffix %>', :id => <%= singular_name %> %><%%= link_to 'Destroy', { :action => 'destroy<%= suffix %>', :id => <%= singular_name %> }, :confirm => 'Are you sure?' %>
    - -<%%= link_to 'Previous page', { :page => @<%= singular_name %>_pages.current.previous } if @<%= singular_name %>_pages.current.previous %> -<%%= link_to 'Next page', { :page => @<%= singular_name %>_pages.current.next } if @<%= singular_name %>_pages.current.next %> - -
    - -<%%= link_to 'New <%= singular_name %>', :action => 'new<%= suffix %>' %> diff --git a/tracks/vendor/rails/railties/lib/rails_generator/generators/components/scaffold/templates/view_new.rhtml b/tracks/vendor/rails/railties/lib/rails_generator/generators/components/scaffold/templates/view_new.rhtml deleted file mode 100644 index 286f8507..00000000 --- a/tracks/vendor/rails/railties/lib/rails_generator/generators/components/scaffold/templates/view_new.rhtml +++ /dev/null @@ -1,8 +0,0 @@ -

    New <%= singular_name %>

    - -<%%= start_form_tag :action => 'create<%= @suffix %>' %> - <%%= render :partial => 'form' %> - <%%= submit_tag "Create" %> -<%%= end_form_tag %> - -<%%= link_to 'Back', :action => 'list<%= suffix %>' %> diff --git a/tracks/vendor/rails/railties/lib/rails_generator/generators/components/scaffold/templates/view_show.rhtml b/tracks/vendor/rails/railties/lib/rails_generator/generators/components/scaffold/templates/view_show.rhtml deleted file mode 100644 index c9245cdf..00000000 --- a/tracks/vendor/rails/railties/lib/rails_generator/generators/components/scaffold/templates/view_show.rhtml +++ /dev/null @@ -1,8 +0,0 @@ -<%% for column in <%= model_name %>.content_columns %> -

    - <%%= column.human_name %>: <%%=h @<%= singular_name %>.send(column.name) %> -

    -<%% end %> - -<%%= link_to 'Edit', :action => 'edit<%= suffix %>', :id => @<%= singular_name %> %> | -<%%= link_to 'Back', :action => 'list<%= suffix %>' %> diff --git a/tracks/vendor/rails/railties/lib/rails_generator/generators/components/session_migration/USAGE b/tracks/vendor/rails/railties/lib/rails_generator/generators/components/session_migration/USAGE deleted file mode 100644 index 43e4e54c..00000000 --- a/tracks/vendor/rails/railties/lib/rails_generator/generators/components/session_migration/USAGE +++ /dev/null @@ -1,15 +0,0 @@ -Description: - The session table migration generator creates a migration for adding a session table - used by CGI::Session::ActiveRecordStore. - - The generator takes a migration name as its argument. The migration name may be - given in CamelCase or under_score. - - The generator creates a migration class in db/migrate prefixed by its number - in the queue. - -Example: - ./script/generate session_migration AddSessionTable - - With 4 existing migrations, this will create an AddSessionTable migration in the - file db/migrate/5_add_session_table.rb \ No newline at end of file diff --git a/tracks/vendor/rails/railties/lib/rails_generator/generators/components/session_migration/session_migration_generator.rb b/tracks/vendor/rails/railties/lib/rails_generator/generators/components/session_migration/session_migration_generator.rb deleted file mode 100644 index a513fa5c..00000000 --- a/tracks/vendor/rails/railties/lib/rails_generator/generators/components/session_migration/session_migration_generator.rb +++ /dev/null @@ -1,12 +0,0 @@ -class SessionMigrationGenerator < Rails::Generator::NamedBase - def initialize(runtime_args, runtime_options = {}) - runtime_args << 'add_session_table' if runtime_args.empty? - super - end - - def manifest - record do |m| - m.migration_template 'migration.rb', 'db/migrate' - end - end -end diff --git a/tracks/vendor/rails/railties/lib/rails_generator/generators/components/session_migration/templates/migration.rb b/tracks/vendor/rails/railties/lib/rails_generator/generators/components/session_migration/templates/migration.rb deleted file mode 100644 index 0ab7fcb1..00000000 --- a/tracks/vendor/rails/railties/lib/rails_generator/generators/components/session_migration/templates/migration.rb +++ /dev/null @@ -1,15 +0,0 @@ -class <%= class_name %> < ActiveRecord::Migration - def self.up - create_table :sessions do |t| - t.column :session_id, :string - t.column :data, :text - t.column :updated_at, :datetime - end - - add_index :sessions, :session_id - end - - def self.down - drop_table :sessions - end -end diff --git a/tracks/vendor/rails/railties/lib/rails_generator/generators/components/web_service/USAGE b/tracks/vendor/rails/railties/lib/rails_generator/generators/components/web_service/USAGE deleted file mode 100644 index d3e45b7f..00000000 --- a/tracks/vendor/rails/railties/lib/rails_generator/generators/components/web_service/USAGE +++ /dev/null @@ -1,28 +0,0 @@ -Description: - The web service generator creates the controller and API definition for - a web service. - - The generator takes a web service name and a list of API methods as arguments. - The web service name may be given in CamelCase or under_score and should - contain no extra suffixes. To create a web service within a - module, specify the web service name as 'module/webservice'. - - The generator creates a controller class in app/controllers, an API definition - in app/apis, and a functional test suite in test/functional. - -Example: - ./script/generate web_service User add edit list remove - - User web service. - Controller: app/controllers/user_controller.rb - API: app/apis/user_api.rb - Test: test/functional/user_api_test.rb - -Modules Example: - ./script/generate web_service 'api/registration' register renew - - Registration web service. - Controller: app/controllers/api/registration_controller.rb - API: app/apis/api/registration_api.rb - Test: test/functional/api/registration_api_test.rb - diff --git a/tracks/vendor/rails/railties/lib/rails_generator/generators/components/web_service/templates/api_definition.rb b/tracks/vendor/rails/railties/lib/rails_generator/generators/components/web_service/templates/api_definition.rb deleted file mode 100644 index 97d0b608..00000000 --- a/tracks/vendor/rails/railties/lib/rails_generator/generators/components/web_service/templates/api_definition.rb +++ /dev/null @@ -1,5 +0,0 @@ -class <%= class_name %>Api < ActionWebService::API::Base -<% for method_name in args -%> - api_method :<%= method_name %> -<% end -%> -end diff --git a/tracks/vendor/rails/railties/lib/rails_generator/generators/components/web_service/templates/controller.rb b/tracks/vendor/rails/railties/lib/rails_generator/generators/components/web_service/templates/controller.rb deleted file mode 100644 index 7b0a8657..00000000 --- a/tracks/vendor/rails/railties/lib/rails_generator/generators/components/web_service/templates/controller.rb +++ /dev/null @@ -1,8 +0,0 @@ -class <%= class_name %>Controller < ApplicationController - wsdl_service_name '<%= class_name %>' -<% for method_name in args -%> - - def <%= method_name %> - end -<% end -%> -end diff --git a/tracks/vendor/rails/railties/lib/rails_generator/generators/components/web_service/templates/functional_test.rb b/tracks/vendor/rails/railties/lib/rails_generator/generators/components/web_service/templates/functional_test.rb deleted file mode 100644 index c4d136f8..00000000 --- a/tracks/vendor/rails/railties/lib/rails_generator/generators/components/web_service/templates/functional_test.rb +++ /dev/null @@ -1,19 +0,0 @@ -require File.dirname(__FILE__) + '<%= '/..' * class_nesting_depth %>/../test_helper' -require '<%= file_path %>_controller' - -class <%= class_name %>Controller; def rescue_action(e) raise e end; end - -class <%= class_name %>ControllerApiTest < Test::Unit::TestCase - def setup - @controller = <%= class_name %>Controller.new - @request = ActionController::TestRequest.new - @response = ActionController::TestResponse.new - end -<% for method_name in args -%> - - def test_<%= method_name %> - result = invoke :<%= method_name %> - assert_equal nil, result - end -<% end -%> -end diff --git a/tracks/vendor/rails/railties/lib/rails_generator/generators/components/web_service/web_service_generator.rb b/tracks/vendor/rails/railties/lib/rails_generator/generators/components/web_service/web_service_generator.rb deleted file mode 100644 index ee18bf80..00000000 --- a/tracks/vendor/rails/railties/lib/rails_generator/generators/components/web_service/web_service_generator.rb +++ /dev/null @@ -1,29 +0,0 @@ -class WebServiceGenerator < Rails::Generator::NamedBase - def manifest - record do |m| - # Check for class naming collisions. - m.class_collisions class_path, "#{class_name}Api", "#{class_name}Controller", "#{class_name}ApiTest" - - # API and test directories. - m.directory File.join('app/apis', class_path) - m.directory File.join('app/controllers', class_path) - m.directory File.join('test/functional', class_path) - - # API definition, controller, and functional test. - m.template 'api_definition.rb', - File.join('app/apis', - class_path, - "#{file_name}_api.rb") - - m.template 'controller.rb', - File.join('app/controllers', - class_path, - "#{file_name}_controller.rb") - - m.template 'functional_test.rb', - File.join('test/functional', - class_path, - "#{file_name}_api_test.rb") - end - end -end diff --git a/tracks/vendor/rails/railties/lib/rails_generator/lookup.rb b/tracks/vendor/rails/railties/lib/rails_generator/lookup.rb deleted file mode 100644 index 6ec68864..00000000 --- a/tracks/vendor/rails/railties/lib/rails_generator/lookup.rb +++ /dev/null @@ -1,210 +0,0 @@ -require File.dirname(__FILE__) + '/spec' - -class Object - class << self - # Lookup missing generators using const_missing. This allows any - # generator to reference another without having to know its location: - # RubyGems, ~/.rails/generators, and RAILS_ROOT/generators. - def lookup_missing_generator(class_id) - if md = /(.+)Generator$/.match(class_id.to_s) - name = md.captures.first.demodulize.underscore - Rails::Generator::Base.lookup(name).klass - else - const_missing_before_generators(class_id) - end - end - - unless respond_to?(:const_missing_before_generators) - alias_method :const_missing_before_generators, :const_missing - alias_method :const_missing, :lookup_missing_generator - end - end -end - -# User home directory lookup adapted from RubyGems. -def Dir.user_home - if ENV['HOME'] - ENV['HOME'] - elsif ENV['USERPROFILE'] - ENV['USERPROFILE'] - elsif ENV['HOMEDRIVE'] and ENV['HOMEPATH'] - "#{ENV['HOMEDRIVE']}:#{ENV['HOMEPATH']}" - else - File.expand_path '~' - end -end - - -module Rails - module Generator - - # Generator lookup is managed by a list of sources which return specs - # describing where to find and how to create generators. This module - # provides class methods for manipulating the source list and looking up - # generator specs, and an #instance wrapper for quickly instantiating - # generators by name. - # - # A spec is not a generator: it's a description of where to find - # the generator and how to create it. A source is anything that - # yields generators from #each. PathSource and GemSource are provided. - module Lookup - def self.append_features(base) - super - base.extend(ClassMethods) - base.use_component_sources! - end - - # Convenience method to instantiate another generator. - def instance(generator_name, args, runtime_options = {}) - self.class.instance(generator_name, args, runtime_options) - end - - module ClassMethods - # The list of sources where we look, in order, for generators. - def sources - read_inheritable_attribute(:sources) or use_component_sources! - end - - # Add a source to the end of the list. - def append_sources(*args) - sources.concat(args.flatten) - invalidate_cache! - end - - # Add a source to the beginning of the list. - def prepend_sources(*args) - write_inheritable_array(:sources, args.flatten + sources) - invalidate_cache! - end - - # Reset the source list. - def reset_sources - write_inheritable_attribute(:sources, []) - invalidate_cache! - end - - # Use application generators (app, ?). - def use_application_sources! - reset_sources - sources << PathSource.new(:builtin, "#{File.dirname(__FILE__)}/generators/applications") - end - - # Use component generators (model, controller, etc). - # 1. Rails application. If RAILS_ROOT is defined we know we're - # generating in the context of a Rails application, so search - # RAILS_ROOT/generators. - # 2. User home directory. Search ~/.rails/generators. - # 3. RubyGems. Search for gems named *_generator. - # 4. Builtins. Model, controller, mailer, scaffold. - def use_component_sources! - reset_sources - if defined? ::RAILS_ROOT - sources << PathSource.new(:lib, "#{::RAILS_ROOT}/lib/generators") - sources << PathSource.new(:vendor, "#{::RAILS_ROOT}/vendor/generators") - sources << PathSource.new(:plugins, "#{::RAILS_ROOT}/vendor/plugins/**/generators") - end - sources << PathSource.new(:user, "#{Dir.user_home}/.rails/generators") - sources << GemSource.new if Object.const_defined?(:Gem) - sources << PathSource.new(:builtin, "#{File.dirname(__FILE__)}/generators/components") - end - - # Lookup knows how to find generators' Specs from a list of Sources. - # Searches the sources, in order, for the first matching name. - def lookup(generator_name) - @found ||= {} - generator_name = generator_name.to_s.downcase - @found[generator_name] ||= cache.find { |spec| spec.name == generator_name } - unless @found[generator_name] - chars = generator_name.scan(/./).map{|c|"#{c}.*?"} - rx = /^#{chars}$/ - gns = cache.select{|spec| spec.name =~ rx } - @found[generator_name] ||= gns.first if gns.length == 1 - raise GeneratorError, "Pattern '#{generator_name}' matches more than one generator: #{gns.map{|sp|sp.name}.join(', ')}" if gns.length > 1 - end - @found[generator_name] or raise GeneratorError, "Couldn't find '#{generator_name}' generator" - end - - # Convenience method to lookup and instantiate a generator. - def instance(generator_name, args = [], runtime_options = {}) - lookup(generator_name).klass.new(args, full_options(runtime_options)) - end - - private - # Lookup and cache every generator from the source list. - def cache - @cache ||= sources.inject([]) { |cache, source| cache + source.map } - end - - # Clear the cache whenever the source list changes. - def invalidate_cache! - @cache = nil - end - end - end - - # Sources enumerate (yield from #each) generator specs which describe - # where to find and how to create generators. Enumerable is mixed in so, - # for example, source.collect will retrieve every generator. - # Sources may be assigned a label to distinguish them. - class Source - include Enumerable - - attr_reader :label - def initialize(label) - @label = label - end - - # The each method must be implemented in subclasses. - # The base implementation raises an error. - def each - raise NotImplementedError - end - - # Return a convenient sorted list of all generator names. - def names - map { |spec| spec.name }.sort - end - end - - - # PathSource looks for generators in a filesystem directory. - class PathSource < Source - attr_reader :path - - def initialize(label, path) - super label - @path = path - end - - # Yield each eligible subdirectory. - def each - Dir["#{path}/[a-z]*"].each do |dir| - if File.directory?(dir) - yield Spec.new(File.basename(dir), dir, label) - end - end - end - end - - - # GemSource hits the mines to quarry for generators. The latest versions - # of gems named *_generator are selected. - class GemSource < Source - def initialize - super :RubyGems - end - - # Yield latest versions of generator gems. - def each - Gem::cache.search(/_generator$/).inject({}) { |latest, gem| - hem = latest[gem.name] - latest[gem.name] = gem if hem.nil? or gem.version > hem.version - latest - }.values.each { |gem| - yield Spec.new(gem.name.sub(/_generator$/, ''), gem.full_gem_path, label) - } - end - end - - end -end diff --git a/tracks/vendor/rails/railties/lib/rails_generator/manifest.rb b/tracks/vendor/rails/railties/lib/rails_generator/manifest.rb deleted file mode 100644 index 702effa7..00000000 --- a/tracks/vendor/rails/railties/lib/rails_generator/manifest.rb +++ /dev/null @@ -1,53 +0,0 @@ -module Rails - module Generator - - # Manifest captures the actions a generator performs. Instantiate - # a manifest with an optional target object, hammer it with actions, - # then replay or rewind on the object of your choice. - # - # Example: - # manifest = Manifest.new { |m| - # m.make_directory '/foo' - # m.create_file '/foo/bar.txt' - # } - # manifest.replay(creator) - # manifest.rewind(destroyer) - class Manifest - attr_reader :target - - # Take a default action target. Yield self if block given. - def initialize(target = nil) - @target, @actions = target, [] - yield self if block_given? - end - - # Record an action. - def method_missing(action, *args, &block) - @actions << [action, args, block] - end - - # Replay recorded actions. - def replay(target = nil) - send_actions(target || @target, @actions) - end - - # Rewind recorded actions. - def rewind(target = nil) - send_actions(target || @target, @actions.reverse) - end - - # Erase recorded actions. - def erase - @actions = [] - end - - private - def send_actions(target, actions) - actions.each do |method, args, block| - target.send(method, *args, &block) - end - end - end - - end -end diff --git a/tracks/vendor/rails/railties/lib/rails_generator/options.rb b/tracks/vendor/rails/railties/lib/rails_generator/options.rb deleted file mode 100644 index df9737f1..00000000 --- a/tracks/vendor/rails/railties/lib/rails_generator/options.rb +++ /dev/null @@ -1,140 +0,0 @@ -require 'optparse' - -module Rails - module Generator - module Options - def self.append_features(base) - super - base.extend(ClassMethods) - class << base - if respond_to?(:inherited) - alias_method :inherited_without_options, :inherited - end - alias_method :inherited, :inherited_with_options - end - end - - module ClassMethods - def inherited_with_options(sub) - inherited_without_options(sub) if respond_to?(:inherited_without_options) - sub.extend(Rails::Generator::Options::ClassMethods) - end - - def mandatory_options(options = nil) - if options - write_inheritable_attribute(:mandatory_options, options) - else - read_inheritable_attribute(:mandatory_options) or write_inheritable_attribute(:mandatory_options, {}) - end - end - - def default_options(options = nil) - if options - write_inheritable_attribute(:default_options, options) - else - read_inheritable_attribute(:default_options) or write_inheritable_attribute(:default_options, {}) - end - end - - # Merge together our class options. In increasing precedence: - # default_options (class default options) - # runtime_options (provided as argument) - # mandatory_options (class mandatory options) - def full_options(runtime_options = {}) - default_options.merge(runtime_options).merge(mandatory_options) - end - - end - - # Each instance has an options hash that's populated by #parse. - def options - @options ||= {} - end - attr_writer :options - - protected - # Convenient access to class mandatory options. - def mandatory_options - self.class.mandatory_options - end - - # Convenient access to class default options. - def default_options - self.class.default_options - end - - # Merge together our instance options. In increasing precedence: - # default_options (class default options) - # options (instance options) - # runtime_options (provided as argument) - # mandatory_options (class mandatory options) - def full_options(runtime_options = {}) - self.class.full_options(options.merge(runtime_options)) - end - - # Parse arguments into the options hash. Classes may customize - # parsing behavior by overriding these methods: - # #banner Usage: ./script/generate [options] - # #add_options! Options: - # some options.. - # #add_general_options! General Options: - # general options.. - def parse!(args, runtime_options = {}) - self.options = {} - - @option_parser = OptionParser.new do |opt| - opt.banner = banner - add_options!(opt) - add_general_options!(opt) - opt.parse!(args) - end - - return args - ensure - self.options = full_options(runtime_options) - end - - # Raise a usage error. Override usage_message to provide a blurb - # after the option parser summary. - def usage - raise UsageError, "#{@option_parser}\n#{usage_message}" - end - - def usage_message - '' - end - - # Override with your own usage banner. - def banner - "Usage: #{$0} [options]" - end - - # Override to add your options to the parser: - # def add_options!(opt) - # opt.on('-v', '--verbose') { |value| options[:verbose] = value } - # end - def add_options!(opt) - end - - # Adds general options like -h and --quiet. Usually don't override. - def add_general_options!(opt) - opt.separator '' - opt.separator 'General Options:' - - opt.on('-p', '--pretend', 'Run but do not make any changes.') { |options[:pretend]| } - opt.on('-f', '--force', 'Overwrite files that already exist.') { options[:collision] = :force } - opt.on('-s', '--skip', 'Skip files that already exist.') { options[:collision] = :skip } - opt.on('-q', '--quiet', 'Suppress normal output.') { |options[:quiet]| } - opt.on('-t', '--backtrace', 'Debugging: show backtrace on errors.') { |options[:backtrace]| } - opt.on('-h', '--help', 'Show this help message.') { |options[:help]| } - opt.on('-c', '--svn', 'Modify files with subversion. (Note: svn must be in path)') do - options[:svn] = `svn status`.inject({}) do |opt, e| - opt[e.chomp[7..-1]] = true - opt - end - end - end - - end - end -end diff --git a/tracks/vendor/rails/railties/lib/rails_generator/scripts.rb b/tracks/vendor/rails/railties/lib/rails_generator/scripts.rb deleted file mode 100644 index 2bf3b1b0..00000000 --- a/tracks/vendor/rails/railties/lib/rails_generator/scripts.rb +++ /dev/null @@ -1,83 +0,0 @@ -require File.dirname(__FILE__) + '/options' - -module Rails - module Generator - module Scripts - - # Generator scripts handle command-line invocation. Each script - # responds to an invoke! class method which handles option parsing - # and generator invocation. - class Base - include Options - default_options :collision => :ask, :quiet => false - - # Run the generator script. Takes an array of unparsed arguments - # and a hash of parsed arguments, takes the generator as an option - # or first remaining argument, and invokes the requested command. - def run(args = [], runtime_options = {}) - begin - parse!(args.dup, runtime_options) - rescue OptionParser::InvalidOption => e - # Don't cry, script. Generators want what you think is invalid. - end - - # Generator name is the only required option. - unless options[:generator] - usage if args.empty? - options[:generator] ||= args.shift - end - - # Look up generator instance and invoke command on it. - Rails::Generator::Base.instance(options[:generator], args, options).command(options[:command]).invoke! - rescue => e - puts e - puts " #{e.backtrace.join("\n ")}\n" if options[:backtrace] - raise SystemExit - end - - protected - # Override with your own script usage banner. - def banner - "Usage: #{$0} [options] generator [args]" - end - - def usage_message - usage = "\nInstalled Generators\n" - Rails::Generator::Base.sources.each do |source| - label = source.label.to_s.capitalize - names = source.names - usage << " #{label}: #{names.join(', ')}\n" unless names.empty? - end - - usage << < :destroy - end -end diff --git a/tracks/vendor/rails/railties/lib/rails_generator/scripts/generate.rb b/tracks/vendor/rails/railties/lib/rails_generator/scripts/generate.rb deleted file mode 100644 index 1fe2f54a..00000000 --- a/tracks/vendor/rails/railties/lib/rails_generator/scripts/generate.rb +++ /dev/null @@ -1,7 +0,0 @@ -require File.dirname(__FILE__) + '/../scripts' - -module Rails::Generator::Scripts - class Generate < Base - mandatory_options :command => :create - end -end diff --git a/tracks/vendor/rails/railties/lib/rails_generator/scripts/update.rb b/tracks/vendor/rails/railties/lib/rails_generator/scripts/update.rb deleted file mode 100644 index 53a9faa3..00000000 --- a/tracks/vendor/rails/railties/lib/rails_generator/scripts/update.rb +++ /dev/null @@ -1,12 +0,0 @@ -require File.dirname(__FILE__) + '/../scripts' - -module Rails::Generator::Scripts - class Update < Base - mandatory_options :command => :update - - protected - def banner - "Usage: #{$0} [options] scaffold" - end - end -end diff --git a/tracks/vendor/rails/railties/lib/rails_generator/simple_logger.rb b/tracks/vendor/rails/railties/lib/rails_generator/simple_logger.rb deleted file mode 100644 index d750f07b..00000000 --- a/tracks/vendor/rails/railties/lib/rails_generator/simple_logger.rb +++ /dev/null @@ -1,46 +0,0 @@ -module Rails - module Generator - class SimpleLogger # :nodoc: - attr_reader :out - attr_accessor :quiet - - def initialize(out = $stdout) - @out = out - @quiet = false - @level = 0 - end - - def log(status, message, &block) - @out.print("%12s %s%s\n" % [status, ' ' * @level, message]) unless quiet - indent(&block) if block_given? - end - - def indent(&block) - @level += 1 - if block_given? - begin - block.call - ensure - outdent - end - end - end - - def outdent - @level -= 1 - if block_given? - begin - block.call - ensure - indent - end - end - end - - private - def method_missing(method, *args, &block) - log(method.to_s, args.first, &block) - end - end - end -end diff --git a/tracks/vendor/rails/railties/lib/rails_generator/spec.rb b/tracks/vendor/rails/railties/lib/rails_generator/spec.rb deleted file mode 100644 index ad609b8f..00000000 --- a/tracks/vendor/rails/railties/lib/rails_generator/spec.rb +++ /dev/null @@ -1,44 +0,0 @@ -module Rails - module Generator - # A spec knows where a generator was found and how to instantiate it. - # Metadata include the generator's name, its base path, and the source - # which yielded it (PathSource, GemSource, etc.) - class Spec - attr_reader :name, :path, :source - - def initialize(name, path, source) - @name, @path, @source = name, path, source - end - - # Look up the generator class. Require its class file, find the class - # in ObjectSpace, tag it with this spec, and return. - def klass - unless @klass - require class_file - @klass = lookup_class - @klass.spec = self - end - @klass - end - - def class_file - "#{path}/#{name}_generator.rb" - end - - def class_name - "#{name.camelize}Generator" - end - - private - # Search for the first Class descending from Rails::Generator::Base - # whose name matches the requested class name. - def lookup_class - ObjectSpace.each_object(Class) do |obj| - return obj if obj.ancestors.include?(Rails::Generator::Base) and - obj.name.split('::').last == class_name - end - raise NameError, "Missing #{class_name} class in #{class_file}" - end - end - end -end diff --git a/tracks/vendor/rails/railties/lib/rails_info.rb b/tracks/vendor/rails/railties/lib/rails_info.rb deleted file mode 100644 index eb60955d..00000000 --- a/tracks/vendor/rails/railties/lib/rails_info.rb +++ /dev/null @@ -1,104 +0,0 @@ -require 'rails_version' - -module Rails - module Info - mattr_accessor :properties - class << (@@properties = []) - def names - map {|(name, )| name} - end - - def value_for(property_name) - find {|(name, )| name == property_name}.last rescue nil - end - end - - class << self #:nodoc: - def property(name, value = nil) - value ||= yield - properties << [name, value] if value - rescue Exception - end - - def components - %w( active_record action_pack action_web_service action_mailer active_support ) - end - - def component_version(component) - require "#{component}/version" - "#{component.classify}::VERSION::STRING".constantize - end - - def edge_rails_revision(info = svn_info) - info[/^Revision: (\d+)/, 1] - end - - def to_s - column_width = properties.names.map {|name| name.length}.max - ["About your application's environment", *properties.map do |property| - "%-#{column_width}s %s" % property - end] * "\n" - end - - alias inspect to_s - - def to_html - returning table = '' do - properties.each do |(name, value)| - table << %() - table << %() - end - table << '
    #{CGI.escapeHTML(name)}#{CGI.escapeHTML(value)}
    ' - end - end - - protected - def svn_info - Dir.chdir("#{RAILS_ROOT}/vendor/rails") do - silence_stderr { `svn info` } - end - end - end - - # The Ruby version and platform, e.g. "1.8.2 (powerpc-darwin8.2.0)". - property 'Ruby version', "#{RUBY_VERSION} (#{RUBY_PLATFORM})" - - # The RubyGems version, if it's installed. - property 'RubyGems version' do - Gem::RubyGemsVersion - end - - # The Rails version. - property 'Rails version' do - Rails::VERSION::STRING - end - - # Versions of each Rails component (Active Record, Action Pack, - # Action Web Service, Action Mailer, and Active Support). - components.each do |component| - property "#{component.titlecase} version" do - component_version(component) - end - end - - # The Rails SVN revision, if it's checked out into vendor/rails. - property 'Edge Rails revision' do - edge_rails_revision - end - - # The application's location on the filesystem. - property 'Application root' do - File.expand_path(RAILS_ROOT) - end - - # The current Rails environment (development, test, or production). - property 'Environment' do - RAILS_ENV - end - - # The name of the database adapter for the current environment. - property 'Database adapter' do - ActiveRecord::Base.configurations[RAILS_ENV]['adapter'] - end - end -end diff --git a/tracks/vendor/rails/railties/lib/rails_version.rb b/tracks/vendor/rails/railties/lib/rails_version.rb deleted file mode 100644 index 5a68bf8d..00000000 --- a/tracks/vendor/rails/railties/lib/rails_version.rb +++ /dev/null @@ -1,9 +0,0 @@ -module Rails - module VERSION #:nodoc: - MAJOR = 1 - MINOR = 0 - TINY = 0 - - STRING = [MAJOR, MINOR, TINY].join('.') - end -end diff --git a/tracks/vendor/rails/railties/lib/railties_path.rb b/tracks/vendor/rails/railties/lib/railties_path.rb deleted file mode 100644 index 81794050..00000000 --- a/tracks/vendor/rails/railties/lib/railties_path.rb +++ /dev/null @@ -1 +0,0 @@ -RAILTIES_PATH = File.expand_path(File.join(File.dirname(__FILE__), '..')) \ No newline at end of file diff --git a/tracks/vendor/rails/railties/lib/rubyprof_ext.rb b/tracks/vendor/rails/railties/lib/rubyprof_ext.rb deleted file mode 100644 index f6e90357..00000000 --- a/tracks/vendor/rails/railties/lib/rubyprof_ext.rb +++ /dev/null @@ -1,35 +0,0 @@ -require 'prof' - -module Prof #:nodoc: - # Adapted from Shugo Maeda's unprof.rb - def self.print_profile(results, io = $stderr) - total = results.detect { |i| - i.method_class.nil? && i.method_id == :"#toplevel" - }.total_time - total = 0.001 if total < 0.001 - - io.puts " %% cumulative self self total" - io.puts " time seconds seconds calls ms/call ms/call name" - - sum = 0.0 - for r in results - sum += r.self_time - - name = if r.method_class.nil? - r.method_id.to_s - elsif r.method_class.is_a?(Class) - "#{r.method_class}##{r.method_id}" - else - "#{r.method_class}.#{r.method_id}" - end - io.printf "%6.2f %8.3f %8.3f %8d %8.2f %8.2f %s\n", - r.self_time / total * 100, - sum, - r.self_time, - r.count, - r.self_time * 1000 / r.count, - r.total_time * 1000 / r.count, - name - end - end -end diff --git a/tracks/vendor/rails/railties/lib/tasks/databases.rake b/tracks/vendor/rails/railties/lib/tasks/databases.rake deleted file mode 100644 index 83140b11..00000000 --- a/tracks/vendor/rails/railties/lib/tasks/databases.rake +++ /dev/null @@ -1,158 +0,0 @@ -desc "Migrate the database according to the migrate scripts in db/migrate (only supported on PG/MySQL). A specific version can be targetted with VERSION=x" -task :migrate => :environment do - ActiveRecord::Migrator.migrate("db/migrate/", ENV["VERSION"] ? ENV["VERSION"].to_i : nil) - Rake::Task[:db_schema_dump].invoke if ActiveRecord::Base.schema_format == :ruby -end - -desc "Load fixtures into the current environment's database" -task :load_fixtures => :environment do - require 'active_record/fixtures' - ActiveRecord::Base.establish_connection(RAILS_ENV.to_sym) - Dir.glob(File.join(RAILS_ROOT, 'test', 'fixtures', '*.{yml,csv}')).each do |fixture_file| - Fixtures.create_fixtures('test/fixtures', File.basename(fixture_file, '.*')) - end -end - -desc "Create a db/schema.rb file that can be portably used against any DB supported by AR." -task :db_schema_dump => :environment do - require 'active_record/schema_dumper' - File.open(ENV['SCHEMA'] || "db/schema.rb", "w") do |file| - ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, file) - end -end - -desc "Import a schema.rb file into the database." -task :db_schema_import => :environment do - file = ENV['SCHEMA'] || "db/schema.rb" - load file -end - -desc "Recreate the test database from the current environment's database schema." -task :clone_schema_to_test => :db_schema_dump do - ActiveRecord::Base.establish_connection(ActiveRecord::Base.configurations['test']) - Rake::Task[:db_schema_import].invoke -end - -desc "Dump the database structure to a SQL file" -task :db_structure_dump => :environment do - abcs = ActiveRecord::Base.configurations - case abcs[RAILS_ENV]["adapter"] - when "mysql", "oci" - ActiveRecord::Base.establish_connection(abcs[RAILS_ENV]) - File.open("db/#{RAILS_ENV}_structure.sql", "w+") { |f| f << ActiveRecord::Base.connection.structure_dump } - when "postgresql" - ENV['PGHOST'] = abcs[RAILS_ENV]["host"] if abcs[RAILS_ENV]["host"] - ENV['PGPORT'] = abcs[RAILS_ENV]["port"].to_s if abcs[RAILS_ENV]["port"] - ENV['PGPASSWORD'] = abcs[RAILS_ENV]["password"].to_s if abcs[RAILS_ENV]["password"] - search_path = abcs[RAILS_ENV]["schema_search_path"] - search_path = "--schema=#{search_path}" if search_path - `pg_dump -U "#{abcs[RAILS_ENV]["username"]}" -s -x -O -f db/#{RAILS_ENV}_structure.sql #{search_path} #{abcs[RAILS_ENV]["database"]}` - when "sqlite", "sqlite3" - dbfile = abcs[RAILS_ENV]["database"] || abcs[RAILS_ENV]["dbfile"] - `#{abcs[RAILS_ENV]["adapter"]} #{dbfile} .schema > db/#{RAILS_ENV}_structure.sql` - when "sqlserver" - `scptxfr /s #{abcs[RAILS_ENV]["host"]} /d #{abcs[RAILS_ENV]["database"]} /I /f db\\#{RAILS_ENV}_structure.sql /q /A /r` - `scptxfr /s #{abcs[RAILS_ENV]["host"]} /d #{abcs[RAILS_ENV]["database"]} /I /F db\ /q /A /r` - else - raise "Task not supported by '#{abcs["test"]["adapter"]}'" - end - - if ActiveRecord::Base.connection.supports_migrations? - File.open("db/#{RAILS_ENV}_structure.sql", "a") { |f| f << ActiveRecord::Base.connection.dump_schema_information } - end -end - -desc "Recreate the test databases from the development structure" -task :clone_structure_to_test => [ :db_structure_dump, :purge_test_database ] do - abcs = ActiveRecord::Base.configurations - case abcs["test"]["adapter"] - when "mysql" - ActiveRecord::Base.establish_connection(:test) - ActiveRecord::Base.connection.execute('SET foreign_key_checks = 0') - IO.readlines("db/#{RAILS_ENV}_structure.sql").join.split("\n\n").each do |table| - ActiveRecord::Base.connection.execute(table) - end - when "postgresql" - ENV['PGHOST'] = abcs["test"]["host"] if abcs["test"]["host"] - ENV['PGPORT'] = abcs["test"]["port"].to_s if abcs["test"]["port"] - ENV['PGPASSWORD'] = abcs["test"]["password"].to_s if abcs["test"]["password"] - `psql -U "#{abcs["test"]["username"]}" -f db/#{RAILS_ENV}_structure.sql #{abcs["test"]["database"]}` - when "sqlite", "sqlite3" - dbfile = abcs["test"]["database"] || abcs["test"]["dbfile"] - `#{abcs["test"]["adapter"]} #{dbfile} < db/#{RAILS_ENV}_structure.sql` - when "sqlserver" - `osql -E -S #{abcs["test"]["host"]} -d #{abcs["test"]["database"]} -i db\\#{RAILS_ENV}_structure.sql` - when "oci" - ActiveRecord::Base.establish_connection(:test) - IO.readlines("db/#{RAILS_ENV}_structure.sql").join.split(";\n\n").each do |ddl| - ActiveRecord::Base.connection.execute(ddl) - end - else - raise "Task not supported by '#{abcs["test"]["adapter"]}'" - end -end - -desc "Empty the test database" -task :purge_test_database => :environment do - abcs = ActiveRecord::Base.configurations - case abcs["test"]["adapter"] - when "mysql" - ActiveRecord::Base.establish_connection(:test) - ActiveRecord::Base.connection.recreate_database(abcs["test"]["database"]) - when "postgresql" - ENV['PGHOST'] = abcs["test"]["host"] if abcs["test"]["host"] - ENV['PGPORT'] = abcs["test"]["port"].to_s if abcs["test"]["port"] - ENV['PGPASSWORD'] = abcs["test"]["password"].to_s if abcs["test"]["password"] - enc_option = "-E #{abcs["test"]["encoding"]}" if abcs["test"]["encoding"] - `dropdb -U "#{abcs["test"]["username"]}" #{abcs["test"]["database"]}` - `createdb #{enc_option} -U "#{abcs["test"]["username"]}" #{abcs["test"]["database"]}` - when "sqlite","sqlite3" - dbfile = abcs["test"]["database"] || abcs["test"]["dbfile"] - File.delete(dbfile) if File.exist?(dbfile) - when "sqlserver" - dropfkscript = "#{abcs["test"]["host"]}.#{abcs["test"]["database"]}.DP1".gsub(/\\/,'-') - `osql -E -S #{abcs["test"]["host"]} -d #{abcs["test"]["database"]} -i db\\#{dropfkscript}` - `osql -E -S #{abcs["test"]["host"]} -d #{abcs["test"]["database"]} -i db\\#{RAILS_ENV}_structure.sql` - when "oci" - ActiveRecord::Base.establish_connection(:test) - ActiveRecord::Base.connection.structure_drop.split(";\n\n").each do |ddl| - ActiveRecord::Base.connection.execute(ddl) - end - else - raise "Task not supported by '#{abcs["test"]["adapter"]}'" - end -end - -def prepare_test_database_task - {:sql => :clone_structure_to_test, - :ruby => :clone_schema_to_test}[ActiveRecord::Base.schema_format] -end - -desc 'Prepare the test database and load the schema' -task :prepare_test_database => :environment do - Rake::Task[prepare_test_database_task].invoke -end - -desc "Creates a sessions table for use with CGI::Session::ActiveRecordStore" -task :create_sessions_table => :environment do - raise "Task unavailable to this database (no migration support)" unless ActiveRecord::Base.connection.supports_migrations? - - ActiveRecord::Base.connection.create_table :sessions do |t| - t.column :session_id, :string - t.column :data, :text - t.column :updated_at, :datetime - end - - ActiveRecord::Base.connection.add_index :sessions, :session_id -end - -desc "Drop the sessions table" -task :drop_sessions_table => :environment do - raise "Task unavailable to this database (no migration support)" unless ActiveRecord::Base.connection.supports_migrations? - - ActiveRecord::Base.connection.drop_table :sessions -end - -desc "Drop and recreate the session table (much faster than 'DELETE * FROM sessions')" -task :purge_sessions_table => [ :drop_sessions_table, :create_sessions_table ] do -end diff --git a/tracks/vendor/rails/railties/lib/tasks/documentation.rake b/tracks/vendor/rails/railties/lib/tasks/documentation.rake deleted file mode 100644 index e0ed801b..00000000 --- a/tracks/vendor/rails/railties/lib/tasks/documentation.rake +++ /dev/null @@ -1,76 +0,0 @@ -desc "Generate documentation for the application" -Rake::RDocTask.new("appdoc") { |rdoc| - rdoc.rdoc_dir = 'doc/app' - rdoc.title = "Rails Application Documentation" - rdoc.options << '--line-numbers --inline-source' - rdoc.rdoc_files.include('doc/README_FOR_APP') - rdoc.rdoc_files.include('app/**/*.rb') -} - -plugins = FileList['vendor/plugins/**'].map {|plugin| File.basename(plugin)} -# Define doc tasks for each plugin -plugins.each do |plugin| - task :"#{plugin}_plugindoc" => :environment do - plugin_base = "vendor/plugins/#{plugin}" - options = [] - files = Rake::FileList.new - options << "-o doc/plugins/#{plugin}" - options << "--title '#{plugin.titlecase} Plugin Documentation'" - options << '--line-numbers --inline-source' - options << '-T html' - - files.include("#{plugin_base}/lib/**/*.rb") - if File.exists?("#{plugin_base}/README") - files.include("#{plugin_base}/README") - options << "--main '#{plugin_base}/README'" - end - files.include("#{plugin_base}/CHANGELOG") if File.exists?("#{plugin_base}/CHANGELOG") - - options << files.to_s - - sh %(rdoc #{options * ' '}) - end -end - -desc "Generate documation for all installed plugins" -task :plugindoc => plugins.map {|plugin| :"#{plugin}_plugindoc"} - -desc "Remove plugin documentation" -task :clobber_plugindoc do - rm_rf 'doc/plugins' rescue nil -end - -desc "Generate documentation for the Rails framework" -Rake::RDocTask.new("apidoc") { |rdoc| - rdoc.rdoc_dir = 'doc/api' - rdoc.template = "#{ENV['template']}.rb" if ENV['template'] - rdoc.title = "Rails Framework Documentation" - rdoc.options << '--line-numbers --inline-source' - rdoc.rdoc_files.include('README') - rdoc.rdoc_files.include('vendor/rails/railties/CHANGELOG') - rdoc.rdoc_files.include('vendor/rails/railties/MIT-LICENSE') - rdoc.rdoc_files.include('vendor/rails/activerecord/README') - rdoc.rdoc_files.include('vendor/rails/activerecord/CHANGELOG') - rdoc.rdoc_files.include('vendor/rails/activerecord/lib/active_record/**/*.rb') - rdoc.rdoc_files.exclude('vendor/rails/activerecord/lib/active_record/vendor/*') - rdoc.rdoc_files.include('vendor/rails/actionpack/README') - rdoc.rdoc_files.include('vendor/rails/actionpack/CHANGELOG') - rdoc.rdoc_files.include('vendor/rails/actionpack/lib/action_controller/**/*.rb') - rdoc.rdoc_files.include('vendor/rails/actionpack/lib/action_view/**/*.rb') - rdoc.rdoc_files.include('vendor/rails/actionmailer/README') - rdoc.rdoc_files.include('vendor/rails/actionmailer/CHANGELOG') - rdoc.rdoc_files.include('vendor/rails/actionmailer/lib/action_mailer/base.rb') - rdoc.rdoc_files.include('vendor/rails/actionwebservice/README') - rdoc.rdoc_files.include('vendor/rails/actionwebservice/CHANGELOG') - rdoc.rdoc_files.include('vendor/rails/actionwebservice/lib/action_web_service.rb') - rdoc.rdoc_files.include('vendor/rails/actionwebservice/lib/action_web_service/*.rb') - rdoc.rdoc_files.include('vendor/rails/actionwebservice/lib/action_web_service/api/*.rb') - rdoc.rdoc_files.include('vendor/rails/actionwebservice/lib/action_web_service/client/*.rb') - rdoc.rdoc_files.include('vendor/rails/actionwebservice/lib/action_web_service/container/*.rb') - rdoc.rdoc_files.include('vendor/rails/actionwebservice/lib/action_web_service/dispatcher/*.rb') - rdoc.rdoc_files.include('vendor/rails/actionwebservice/lib/action_web_service/protocol/*.rb') - rdoc.rdoc_files.include('vendor/rails/actionwebservice/lib/action_web_service/support/*.rb') - rdoc.rdoc_files.include('vendor/rails/activesupport/README') - rdoc.rdoc_files.include('vendor/rails/activesupport/CHANGELOG') - rdoc.rdoc_files.include('vendor/rails/activesupport/lib/active_support/**/*.rb') -} diff --git a/tracks/vendor/rails/railties/lib/tasks/framework.rake b/tracks/vendor/rails/railties/lib/tasks/framework.rake deleted file mode 100644 index 59f8f513..00000000 --- a/tracks/vendor/rails/railties/lib/tasks/framework.rake +++ /dev/null @@ -1,71 +0,0 @@ -desc "Lock this application to the current gems (by unpacking them into vendor/rails)" -task :freeze_gems do - deps = %w(actionpack activerecord actionmailer activesupport actionwebservice) - require 'rubygems' - - rails = if version = ENV['VERSION'] - Gem.cache.search('rails', "= #{version}").first - else - Gem.cache.search('rails').sort_by { |g| g.version }.last - end - version ||= rails.version - - unless rails - puts "No rails gem #{version} is installed. Do 'gem list rails' to see what you have available." - exit - end - - puts "Freezing to the gems for Rails #{rails.version}" - rm_rf "vendor/rails" - mkdir_p "vendor/rails" - - rails.dependencies.select { |g| deps.include? g.name }.each do |g| - system "cd vendor/rails; gem unpack -v '#{g.version_requirements}' #{g.name}; mv #{g.name}* #{g.name}" - end - system "cd vendor/rails; gem unpack -v '=#{version}' rails" - - FileUtils.mv(Dir.glob("vendor/rails/rails*").first, "vendor/rails/railties") -end - -desc "Lock this application to the Edge Rails (by exporting from Subversion). Defaults to svn HEAD; do 'rake freeze_edge REVISION=1234' to lock to a specific revision." -task :freeze_edge do - $verbose = false - `svn --version` rescue nil - unless !$?.nil? && $?.success? - $stderr.puts "ERROR: Must have subversion (svn) available in the PATH to lock this application to Edge Rails" - exit 1 - end - - rm_rf "vendor/rails" - mkdir_p "vendor/rails" - - revision_switch = ENV['REVISION'] ? " -r #{ENV['REVISION']}" : '' - for framework in %w( railties actionpack activerecord actionmailer activesupport actionwebservice ) - mkdir_p "vendor/rails/#{framework}" - system "svn export http://dev.rubyonrails.org/svn/rails/trunk/#{framework}/lib vendor/rails/#{framework}/lib #{revision_switch}" - end -end - -desc "Unlock this application from freeze of gems or edge and return to a fluid use of system gems" -task :unfreeze_rails do - rm_rf "vendor/rails" -end - -desc "Add new scripts to the application script/ directory" -task :add_new_scripts do - local_base = "script" - edge_base = "#{File.dirname(__FILE__)}/../../bin" - - local = Dir["#{local_base}/**/*"].reject { |path| File.directory?(path) } - edge = Dir["#{edge_base}/**/*"].reject { |path| File.directory?(path) } - - edge.each do |script| - base_name = script[(edge_base.length+1)..-1] - next if base_name == "rails" - next if local.detect { |path| base_name == path[(local_base.length+1)..-1] } - if !File.directory?("#{local_base}/#{File.dirname(base_name)}") - mkdir_p "#{local_base}/#{File.dirname(base_name)}" - end - install script, "#{local_base}/#{base_name}", :mode => 0755 - end -end diff --git a/tracks/vendor/rails/railties/lib/tasks/javascripts.rake b/tracks/vendor/rails/railties/lib/tasks/javascripts.rake deleted file mode 100644 index 5fc01562..00000000 --- a/tracks/vendor/rails/railties/lib/tasks/javascripts.rake +++ /dev/null @@ -1,6 +0,0 @@ - -desc "Update your javascripts from your current rails install." -task :update_javascripts do - require 'railties_path' - FileUtils.cp(Dir[RAILTIES_PATH + '/html/javascripts/*.js'], RAILS_ROOT + '/public/javascripts/') -end diff --git a/tracks/vendor/rails/railties/lib/tasks/misc.rake b/tracks/vendor/rails/railties/lib/tasks/misc.rake deleted file mode 100644 index 60dc2e21..00000000 --- a/tracks/vendor/rails/railties/lib/tasks/misc.rake +++ /dev/null @@ -1,19 +0,0 @@ -desc "Run all the tests on a fresh test database" -task :default do - Rake::Task[:test_units].invoke rescue got_error = true - Rake::Task[:test_functional].invoke rescue got_error = true - raise "Test failures" if got_error -end - -task :environment do - require(File.join(RAILS_ROOT, 'config', 'environment')) -end - - -desc "Clears all *.log files in log/" -task :clear_logs do - FileList["log/*.log"].each do |log_file| - f = File.open(log_file, "w") - f.close - end -end diff --git a/tracks/vendor/rails/railties/lib/tasks/rails.rb b/tracks/vendor/rails/railties/lib/tasks/rails.rb deleted file mode 100644 index 48a9d67b..00000000 --- a/tracks/vendor/rails/railties/lib/tasks/rails.rb +++ /dev/null @@ -1,8 +0,0 @@ -$VERBOSE = nil - -# Load Rails rakefile extensions -Dir["#{File.dirname(__FILE__)}/*.rake"].each { |ext| load ext } - -# Load any custom rakefile extensions -Dir["./lib/tasks/**/*.rake"].sort.each { |ext| load ext } -Dir["./vendor/plugins/*/tasks/**/*.rake"].sort.each { |ext| load ext } \ No newline at end of file diff --git a/tracks/vendor/rails/railties/lib/tasks/statistics.rake b/tracks/vendor/rails/railties/lib/tasks/statistics.rake deleted file mode 100644 index 01c944d5..00000000 --- a/tracks/vendor/rails/railties/lib/tasks/statistics.rake +++ /dev/null @@ -1,16 +0,0 @@ -STATS_DIRECTORIES = [ - %w(Helpers app/helpers), - %w(Controllers app/controllers), - %w(APIs app/apis), - %w(Components components), - %w(Functional\ tests test/functional), - %w(Models app/models), - %w(Unit\ tests test/unit), - %w(Libraries lib/) -].collect { |name, dir| [ name, "#{RAILS_ROOT}/#{dir}" ] }.select { |name, dir| File.directory?(dir) } - -desc "Report code statistics (KLOCs, etc) from the application" -task :stats do - require 'code_statistics' - CodeStatistics.new(*STATS_DIRECTORIES).to_s -end diff --git a/tracks/vendor/rails/railties/lib/tasks/testing.rake b/tracks/vendor/rails/railties/lib/tasks/testing.rake deleted file mode 100644 index 5792f063..00000000 --- a/tracks/vendor/rails/railties/lib/tasks/testing.rake +++ /dev/null @@ -1,50 +0,0 @@ -TEST_CHANGES_SINCE = Time.now - 600 - -# Look up tests for recently modified sources. -def recent_tests(source_pattern, test_path, touched_since = 10.minutes.ago) - FileList[source_pattern].map do |path| - if File.mtime(path) > touched_since - test = "#{test_path}/#{File.basename(path, '.rb')}_test.rb" - test if File.exists?(test) - end - end.compact -end - -desc 'Test recent changes' -Rake::TestTask.new(:recent => [ :prepare_test_database ]) do |t| - since = TEST_CHANGES_SINCE - touched = FileList['test/**/*_test.rb'].select { |path| File.mtime(path) > since } + - recent_tests('app/models/*.rb', 'test/unit', since) + - recent_tests('app/controllers/*.rb', 'test/functional', since) - - t.libs << 'test' - t.verbose = true - t.test_files = touched.uniq -end - -desc "Run the unit tests in test/unit" -Rake::TestTask.new(:test_units => [ :prepare_test_database ]) do |t| - t.libs << "test" - t.pattern = 'test/unit/**/*_test.rb' - t.verbose = true -end - -desc "Run the functional tests in test/functional" -Rake::TestTask.new(:test_functional => [ :prepare_test_database ]) do |t| - t.libs << "test" - t.pattern = 'test/functional/**/*_test.rb' - t.verbose = true -end - -desc "Run the plugin tests in vendor/plugins/**/test (or specify with PLUGIN=name)" -Rake::TestTask.new(:test_plugins => :environment) do |t| - t.libs << "test" - - if ENV['PLUGIN'] - t.pattern = "vendor/plugins/#{ENV['PLUGIN']}/test/**/*_test.rb" - else - t.pattern = 'vendor/plugins/**/test/**/*_test.rb' - end - - t.verbose = true -end diff --git a/tracks/vendor/rails/railties/lib/test_help.rb b/tracks/vendor/rails/railties/lib/test_help.rb deleted file mode 100644 index 9238d1e2..00000000 --- a/tracks/vendor/rails/railties/lib/test_help.rb +++ /dev/null @@ -1,17 +0,0 @@ -require 'application' - -# Make double-sure the RAILS_ENV is set to test, -# so fixtures are loaded to the right database -silence_warnings { RAILS_ENV = "test" } - -require 'test/unit' -require 'active_record/fixtures' -require 'action_controller/test_process' -require 'action_web_service/test_invoke' -require 'breakpoint' - -Test::Unit::TestCase.fixture_path = RAILS_ROOT + "/test/fixtures/" - -def create_fixtures(*table_names) - Fixtures.create_fixtures(RAILS_ROOT + "/test/fixtures", table_names) -end diff --git a/tracks/vendor/rails/railties/lib/webrick_server.rb b/tracks/vendor/rails/railties/lib/webrick_server.rb deleted file mode 100644 index f356eaf3..00000000 --- a/tracks/vendor/rails/railties/lib/webrick_server.rb +++ /dev/null @@ -1,170 +0,0 @@ -# Donated by Florian Gross - -require 'webrick' -require 'cgi' -require 'stringio' - -include WEBrick - -ABSOLUTE_RAILS_ROOT = File.expand_path(RAILS_ROOT) - -ActiveRecord::Base.threaded_connections = false - -class CGI #:nodoc: - def stdinput - @stdin || $stdin - end - - def env_table - @env_table || ENV - end - - def initialize(type = "query", table = nil, stdin = nil) - @env_table, @stdin = table, stdin - - if defined?(MOD_RUBY) && !ENV.key?("GATEWAY_INTERFACE") - Apache.request.setup_cgi_env - end - - extend QueryExtension - @multipart = false - if defined?(CGI_PARAMS) - warn "do not use CGI_PARAMS and CGI_COOKIES" - @params = CGI_PARAMS.dup - @cookies = CGI_COOKIES.dup - else - initialize_query() # set @params, @cookies - end - @output_cookies = nil - @output_hidden = nil - end -end - -# A custom dispatch servlet for use with WEBrick. It dispatches requests -# (using the Rails Dispatcher) to the appropriate controller/action. By default, -# it restricts WEBrick to a managing a single Rails request at a time, but you -# can change this behavior by setting ActionController::Base.allow_concurrency -# to true. -class DispatchServlet < WEBrick::HTTPServlet::AbstractServlet - REQUEST_MUTEX = Mutex.new - - # Start the WEBrick server with the given options, mounting the - # DispatchServlet at /. - def self.dispatch(options = {}) - Socket.do_not_reverse_lookup = true # patch for OS X - - params = { :Port => options[:port].to_i, - :ServerType => options[:server_type], - :BindAddress => options[:ip] } - params[:MimeTypes] = options[:mime_types] if options[:mime_types] - - server = WEBrick::HTTPServer.new(params) - server.mount('/', DispatchServlet, options) - - trap("INT") { server.shutdown } - - require File.join(@server_options[:server_root], "..", "config", "environment") unless defined?(RAILS_ROOT) - require "dispatcher" - - server.start - end - - def initialize(server, options) #:nodoc: - @server_options = options - @file_handler = WEBrick::HTTPServlet::FileHandler.new(server, options[:server_root]) - Dir.chdir(ABSOLUTE_RAILS_ROOT) - super - end - - def service(req, res) #:nodoc: - begin - unless handle_file(req, res) - REQUEST_MUTEX.lock unless ActionController::Base.allow_concurrency - unless handle_dispatch(req, res) - raise WEBrick::HTTPStatus::NotFound, "`#{req.path}' not found." - end - end - ensure - unless ActionController::Base.allow_concurrency - REQUEST_MUTEX.unlock if REQUEST_MUTEX.locked? - end - end - end - - def handle_file(req, res) #:nodoc: - begin - req = req.dup - path = req.path.dup - - # Add .html if the last path piece has no . in it - path << '.html' if path != '/' && (%r{(^|/)[^./]+$} =~ path) - path.gsub!('+', ' ') # Unescape + since FileHandler doesn't do so. - - req.instance_variable_set(:@path_info, path) # Set the modified path... - - @file_handler.send(:service, req, res) - return true - rescue HTTPStatus::PartialContent, HTTPStatus::NotModified => err - res.set_error(err) - return true - rescue => err - return false - end - end - - def handle_dispatch(req, res, origin = nil) #:nodoc: - data = StringIO.new - Dispatcher.dispatch( - CGI.new("query", create_env_table(req, origin), StringIO.new(req.body || "")), - ActionController::CgiRequest::DEFAULT_SESSION_OPTIONS, - data - ) - - header, body = extract_header_and_body(data) - - set_charset(header) - assign_status(res, header) - res.cookies.concat(header.delete('set-cookie') || []) - header.each { |key, val| res[key] = val.join(", ") } - - res.body = body - return true - rescue => err - p err, err.backtrace - return false - end - - private - def create_env_table(req, origin) - env = req.meta_vars.clone - env.delete "SCRIPT_NAME" - env["QUERY_STRING"] = req.request_uri.query - env["REQUEST_URI"] = origin if origin - return env - end - - def extract_header_and_body(data) - data.rewind - data = data.read - - raw_header, body = *data.split(/^[\xd\xa]+/on, 2) - header = WEBrick::HTTPUtils::parse_header(raw_header) - - return header, body - end - - def set_charset(header) - ct = header["content-type"] - if ct.any? { |x| x =~ /^text\// } && ! ct.any? { |x| x =~ /charset=/ } - ch = @server_options[:charset] || "UTF-8" - ct.find { |x| x =~ /^text\// } << ("; charset=" + ch) - end - end - - def assign_status(res, header) - if /^(\d+)/ =~ header['status'][0] - res.status = $1.to_i - header.delete('status') - end - end -end