").append( jQuery.parseHTML( responseText ) ).find( selector ) :
+
+ // Otherwise use the full result
+ responseText );
+
+ }).complete( callback && function( jqXHR, status ) {
+ self.each( callback, response || [ jqXHR.responseText, status, jqXHR ] );
+ });
+ }
+
+ return this;
+};
+
+// Attach a bunch of functions for handling common AJAX events
+jQuery.each( [ "ajaxStart", "ajaxStop", "ajaxComplete", "ajaxError", "ajaxSuccess", "ajaxSend" ], function( i, type ){
+ jQuery.fn[ type ] = function( fn ){
+ return this.on( type, fn );
+ };
+});
+
+jQuery.extend({
+
+ // Counter for holding the number of active queries
+ active: 0,
+
+ // Last-Modified header cache for next request
+ lastModified: {},
+ etag: {},
+
+ ajaxSettings: {
+ url: ajaxLocation,
+ type: "GET",
+ isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ),
+ global: true,
+ processData: true,
+ async: true,
+ contentType: "application/x-www-form-urlencoded; charset=UTF-8",
+ /*
+ timeout: 0,
+ data: null,
+ dataType: null,
+ username: null,
+ password: null,
+ cache: null,
+ throws: false,
+ traditional: false,
+ headers: {},
+ */
+
+ accepts: {
+ "*": allTypes,
+ text: "text/plain",
+ html: "text/html",
+ xml: "application/xml, text/xml",
+ json: "application/json, text/javascript"
+ },
+
+ contents: {
+ xml: /xml/,
+ html: /html/,
+ json: /json/
+ },
+
+ responseFields: {
+ xml: "responseXML",
+ text: "responseText",
+ json: "responseJSON"
+ },
+
+ // Data converters
+ // Keys separate source (or catchall "*") and destination types with a single space
+ converters: {
+
+ // Convert anything to text
+ "* text": String,
+
+ // Text to html (true = no transformation)
+ "text html": true,
+
+ // Evaluate text as a json expression
+ "text json": jQuery.parseJSON,
+
+ // Parse text as xml
+ "text xml": jQuery.parseXML
+ },
+
+ // For options that shouldn't be deep extended:
+ // you can add your own custom options here if
+ // and when you create one that shouldn't be
+ // deep extended (see ajaxExtend)
+ flatOptions: {
+ url: true,
+ context: true
+ }
+ },
+
+ // Creates a full fledged settings object into target
+ // with both ajaxSettings and settings fields.
+ // If target is omitted, writes into ajaxSettings.
+ ajaxSetup: function( target, settings ) {
+ return settings ?
+
+ // Building a settings object
+ ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :
+
+ // Extending ajaxSettings
+ ajaxExtend( jQuery.ajaxSettings, target );
+ },
+
+ ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
+ ajaxTransport: addToPrefiltersOrTransports( transports ),
+
+ // Main method
+ ajax: function( url, options ) {
+
+ // If url is an object, simulate pre-1.5 signature
+ if ( typeof url === "object" ) {
+ options = url;
+ url = undefined;
+ }
+
+ // Force options to be an object
+ options = options || {};
+
+ var // Cross-domain detection vars
+ parts,
+ // Loop variable
+ i,
+ // URL without anti-cache param
+ cacheURL,
+ // Response headers as string
+ responseHeadersString,
+ // timeout handle
+ timeoutTimer,
+
+ // To know if global events are to be dispatched
+ fireGlobals,
+
+ transport,
+ // Response headers
+ responseHeaders,
+ // Create the final options object
+ s = jQuery.ajaxSetup( {}, options ),
+ // Callbacks context
+ callbackContext = s.context || s,
+ // Context for global events is callbackContext if it is a DOM node or jQuery collection
+ globalEventContext = s.context && ( callbackContext.nodeType || callbackContext.jquery ) ?
+ jQuery( callbackContext ) :
+ jQuery.event,
+ // Deferreds
+ deferred = jQuery.Deferred(),
+ completeDeferred = jQuery.Callbacks("once memory"),
+ // Status-dependent callbacks
+ statusCode = s.statusCode || {},
+ // Headers (they are sent all at once)
+ requestHeaders = {},
+ requestHeadersNames = {},
+ // The jqXHR state
+ state = 0,
+ // Default abort message
+ strAbort = "canceled",
+ // Fake xhr
+ jqXHR = {
+ readyState: 0,
+
+ // Builds headers hashtable if needed
+ getResponseHeader: function( key ) {
+ var match;
+ if ( state === 2 ) {
+ if ( !responseHeaders ) {
+ responseHeaders = {};
+ while ( (match = rheaders.exec( responseHeadersString )) ) {
+ responseHeaders[ match[1].toLowerCase() ] = match[ 2 ];
+ }
+ }
+ match = responseHeaders[ key.toLowerCase() ];
+ }
+ return match == null ? null : match;
+ },
+
+ // Raw string
+ getAllResponseHeaders: function() {
+ return state === 2 ? responseHeadersString : null;
+ },
+
+ // Caches the header
+ setRequestHeader: function( name, value ) {
+ var lname = name.toLowerCase();
+ if ( !state ) {
+ name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name;
+ requestHeaders[ name ] = value;
+ }
+ return this;
+ },
+
+ // Overrides response content-type header
+ overrideMimeType: function( type ) {
+ if ( !state ) {
+ s.mimeType = type;
+ }
+ return this;
+ },
+
+ // Status-dependent callbacks
+ statusCode: function( map ) {
+ var code;
+ if ( map ) {
+ if ( state < 2 ) {
+ for ( code in map ) {
+ // Lazy-add the new callback in a way that preserves old ones
+ statusCode[ code ] = [ statusCode[ code ], map[ code ] ];
+ }
+ } else {
+ // Execute the appropriate callbacks
+ jqXHR.always( map[ jqXHR.status ] );
+ }
+ }
+ return this;
+ },
+
+ // Cancel the request
+ abort: function( statusText ) {
+ var finalText = statusText || strAbort;
+ if ( transport ) {
+ transport.abort( finalText );
+ }
+ done( 0, finalText );
+ return this;
+ }
+ };
+
+ // Attach deferreds
+ deferred.promise( jqXHR ).complete = completeDeferred.add;
+ jqXHR.success = jqXHR.done;
+ jqXHR.error = jqXHR.fail;
+
+ // Remove hash character (#7531: and string promotion)
+ // Add protocol if not provided (#5866: IE7 issue with protocol-less urls)
+ // Handle falsy url in the settings object (#10093: consistency with old signature)
+ // We also use the url parameter if available
+ s.url = ( ( url || s.url || ajaxLocation ) + "" ).replace( rhash, "" ).replace( rprotocol, ajaxLocParts[ 1 ] + "//" );
+
+ // Alias method option to type as per ticket #12004
+ s.type = options.method || options.type || s.method || s.type;
+
+ // Extract dataTypes list
+ s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().match( core_rnotwhite ) || [""];
+
+ // A cross-domain request is in order when we have a protocol:host:port mismatch
+ if ( s.crossDomain == null ) {
+ parts = rurl.exec( s.url.toLowerCase() );
+ s.crossDomain = !!( parts &&
+ ( parts[ 1 ] !== ajaxLocParts[ 1 ] || parts[ 2 ] !== ajaxLocParts[ 2 ] ||
+ ( parts[ 3 ] || ( parts[ 1 ] === "http:" ? "80" : "443" ) ) !==
+ ( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === "http:" ? "80" : "443" ) ) )
+ );
+ }
+
+ // Convert data if not already a string
+ if ( s.data && s.processData && typeof s.data !== "string" ) {
+ s.data = jQuery.param( s.data, s.traditional );
+ }
+
+ // Apply prefilters
+ inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );
+
+ // If request was aborted inside a prefilter, stop there
+ if ( state === 2 ) {
+ return jqXHR;
+ }
+
+ // We can fire global events as of now if asked to
+ fireGlobals = s.global;
+
+ // Watch for a new set of requests
+ if ( fireGlobals && jQuery.active++ === 0 ) {
+ jQuery.event.trigger("ajaxStart");
+ }
+
+ // Uppercase the type
+ s.type = s.type.toUpperCase();
+
+ // Determine if request has content
+ s.hasContent = !rnoContent.test( s.type );
+
+ // Save the URL in case we're toying with the If-Modified-Since
+ // and/or If-None-Match header later on
+ cacheURL = s.url;
+
+ // More options handling for requests with no content
+ if ( !s.hasContent ) {
+
+ // If data is available, append data to url
+ if ( s.data ) {
+ cacheURL = ( s.url += ( ajax_rquery.test( cacheURL ) ? "&" : "?" ) + s.data );
+ // #9682: remove data so that it's not used in an eventual retry
+ delete s.data;
+ }
+
+ // Add anti-cache in url if needed
+ if ( s.cache === false ) {
+ s.url = rts.test( cacheURL ) ?
+
+ // If there is already a '_' parameter, set its value
+ cacheURL.replace( rts, "$1_=" + ajax_nonce++ ) :
+
+ // Otherwise add one to the end
+ cacheURL + ( ajax_rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ajax_nonce++;
+ }
+ }
+
+ // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
+ if ( s.ifModified ) {
+ if ( jQuery.lastModified[ cacheURL ] ) {
+ jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] );
+ }
+ if ( jQuery.etag[ cacheURL ] ) {
+ jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] );
+ }
+ }
+
+ // Set the correct header, if data is being sent
+ if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
+ jqXHR.setRequestHeader( "Content-Type", s.contentType );
+ }
+
+ // Set the Accepts header for the server, depending on the dataType
+ jqXHR.setRequestHeader(
+ "Accept",
+ s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ?
+ s.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) :
+ s.accepts[ "*" ]
+ );
+
+ // Check for headers option
+ for ( i in s.headers ) {
+ jqXHR.setRequestHeader( i, s.headers[ i ] );
+ }
+
+ // Allow custom headers/mimetypes and early abort
+ if ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) {
+ // Abort if not done already and return
+ return jqXHR.abort();
+ }
+
+ // aborting is no longer a cancellation
+ strAbort = "abort";
+
+ // Install callbacks on deferreds
+ for ( i in { success: 1, error: 1, complete: 1 } ) {
+ jqXHR[ i ]( s[ i ] );
+ }
+
+ // Get transport
+ transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );
+
+ // If no transport, we auto-abort
+ if ( !transport ) {
+ done( -1, "No Transport" );
+ } else {
+ jqXHR.readyState = 1;
+
+ // Send global event
+ if ( fireGlobals ) {
+ globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
+ }
+ // Timeout
+ if ( s.async && s.timeout > 0 ) {
+ timeoutTimer = setTimeout(function() {
+ jqXHR.abort("timeout");
+ }, s.timeout );
+ }
+
+ try {
+ state = 1;
+ transport.send( requestHeaders, done );
+ } catch ( e ) {
+ // Propagate exception as error if not done
+ if ( state < 2 ) {
+ done( -1, e );
+ // Simply rethrow otherwise
+ } else {
+ throw e;
+ }
+ }
+ }
+
+ // Callback for when everything is done
+ function done( status, nativeStatusText, responses, headers ) {
+ var isSuccess, success, error, response, modified,
+ statusText = nativeStatusText;
+
+ // Called once
+ if ( state === 2 ) {
+ return;
+ }
+
+ // State is "done" now
+ state = 2;
+
+ // Clear timeout if it exists
+ if ( timeoutTimer ) {
+ clearTimeout( timeoutTimer );
+ }
+
+ // Dereference transport for early garbage collection
+ // (no matter how long the jqXHR object will be used)
+ transport = undefined;
+
+ // Cache response headers
+ responseHeadersString = headers || "";
+
+ // Set readyState
+ jqXHR.readyState = status > 0 ? 4 : 0;
+
+ // Determine if successful
+ isSuccess = status >= 200 && status < 300 || status === 304;
+
+ // Get response data
+ if ( responses ) {
+ response = ajaxHandleResponses( s, jqXHR, responses );
+ }
+
+ // Convert no matter what (that way responseXXX fields are always set)
+ response = ajaxConvert( s, response, jqXHR, isSuccess );
+
+ // If successful, handle type chaining
+ if ( isSuccess ) {
+
+ // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
+ if ( s.ifModified ) {
+ modified = jqXHR.getResponseHeader("Last-Modified");
+ if ( modified ) {
+ jQuery.lastModified[ cacheURL ] = modified;
+ }
+ modified = jqXHR.getResponseHeader("etag");
+ if ( modified ) {
+ jQuery.etag[ cacheURL ] = modified;
+ }
+ }
+
+ // if no content
+ if ( status === 204 || s.type === "HEAD" ) {
+ statusText = "nocontent";
+
+ // if not modified
+ } else if ( status === 304 ) {
+ statusText = "notmodified";
+
+ // If we have data, let's convert it
+ } else {
+ statusText = response.state;
+ success = response.data;
+ error = response.error;
+ isSuccess = !error;
+ }
+ } else {
+ // We extract error from statusText
+ // then normalize statusText and status for non-aborts
+ error = statusText;
+ if ( status || !statusText ) {
+ statusText = "error";
+ if ( status < 0 ) {
+ status = 0;
+ }
+ }
+ }
+
+ // Set data for the fake xhr object
+ jqXHR.status = status;
+ jqXHR.statusText = ( nativeStatusText || statusText ) + "";
+
+ // Success/Error
+ if ( isSuccess ) {
+ deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
+ } else {
+ deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
+ }
+
+ // Status-dependent callbacks
+ jqXHR.statusCode( statusCode );
+ statusCode = undefined;
+
+ if ( fireGlobals ) {
+ globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError",
+ [ jqXHR, s, isSuccess ? success : error ] );
+ }
+
+ // Complete
+ completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );
+
+ if ( fireGlobals ) {
+ globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] );
+ // Handle the global AJAX counter
+ if ( !( --jQuery.active ) ) {
+ jQuery.event.trigger("ajaxStop");
+ }
+ }
+ }
+
+ return jqXHR;
+ },
+
+ getJSON: function( url, data, callback ) {
+ return jQuery.get( url, data, callback, "json" );
+ },
+
+ getScript: function( url, callback ) {
+ return jQuery.get( url, undefined, callback, "script" );
+ }
+});
+
+jQuery.each( [ "get", "post" ], function( i, method ) {
+ jQuery[ method ] = function( url, data, callback, type ) {
+ // shift arguments if data argument was omitted
+ if ( jQuery.isFunction( data ) ) {
+ type = type || callback;
+ callback = data;
+ data = undefined;
+ }
+
+ return jQuery.ajax({
+ url: url,
+ type: method,
+ dataType: type,
+ data: data,
+ success: callback
+ });
+ };
+});
+
+/* Handles responses to an ajax request:
+ * - finds the right dataType (mediates between content-type and expected dataType)
+ * - returns the corresponding response
+ */
+function ajaxHandleResponses( s, jqXHR, responses ) {
+ var firstDataType, ct, finalDataType, type,
+ contents = s.contents,
+ dataTypes = s.dataTypes;
+
+ // Remove auto dataType and get content-type in the process
+ while( dataTypes[ 0 ] === "*" ) {
+ dataTypes.shift();
+ if ( ct === undefined ) {
+ ct = s.mimeType || jqXHR.getResponseHeader("Content-Type");
+ }
+ }
+
+ // Check if we're dealing with a known content-type
+ if ( ct ) {
+ for ( type in contents ) {
+ if ( contents[ type ] && contents[ type ].test( ct ) ) {
+ dataTypes.unshift( type );
+ break;
+ }
+ }
+ }
+
+ // Check to see if we have a response for the expected dataType
+ if ( dataTypes[ 0 ] in responses ) {
+ finalDataType = dataTypes[ 0 ];
+ } else {
+ // Try convertible dataTypes
+ for ( type in responses ) {
+ if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[0] ] ) {
+ finalDataType = type;
+ break;
+ }
+ if ( !firstDataType ) {
+ firstDataType = type;
+ }
+ }
+ // Or just use first one
+ finalDataType = finalDataType || firstDataType;
+ }
+
+ // If we found a dataType
+ // We add the dataType to the list if needed
+ // and return the corresponding response
+ if ( finalDataType ) {
+ if ( finalDataType !== dataTypes[ 0 ] ) {
+ dataTypes.unshift( finalDataType );
+ }
+ return responses[ finalDataType ];
+ }
+}
+
+/* Chain conversions given the request and the original response
+ * Also sets the responseXXX fields on the jqXHR instance
+ */
+function ajaxConvert( s, response, jqXHR, isSuccess ) {
+ var conv2, current, conv, tmp, prev,
+ converters = {},
+ // Work with a copy of dataTypes in case we need to modify it for conversion
+ dataTypes = s.dataTypes.slice();
+
+ // Create converters map with lowercased keys
+ if ( dataTypes[ 1 ] ) {
+ for ( conv in s.converters ) {
+ converters[ conv.toLowerCase() ] = s.converters[ conv ];
+ }
+ }
+
+ current = dataTypes.shift();
+
+ // Convert to each sequential dataType
+ while ( current ) {
+
+ if ( s.responseFields[ current ] ) {
+ jqXHR[ s.responseFields[ current ] ] = response;
+ }
+
+ // Apply the dataFilter if provided
+ if ( !prev && isSuccess && s.dataFilter ) {
+ response = s.dataFilter( response, s.dataType );
+ }
+
+ prev = current;
+ current = dataTypes.shift();
+
+ if ( current ) {
+
+ // There's only work to do if current dataType is non-auto
+ if ( current === "*" ) {
+
+ current = prev;
+
+ // Convert response if prev dataType is non-auto and differs from current
+ } else if ( prev !== "*" && prev !== current ) {
+
+ // Seek a direct converter
+ conv = converters[ prev + " " + current ] || converters[ "* " + current ];
+
+ // If none found, seek a pair
+ if ( !conv ) {
+ for ( conv2 in converters ) {
+
+ // If conv2 outputs current
+ tmp = conv2.split( " " );
+ if ( tmp[ 1 ] === current ) {
+
+ // If prev can be converted to accepted input
+ conv = converters[ prev + " " + tmp[ 0 ] ] ||
+ converters[ "* " + tmp[ 0 ] ];
+ if ( conv ) {
+ // Condense equivalence converters
+ if ( conv === true ) {
+ conv = converters[ conv2 ];
+
+ // Otherwise, insert the intermediate dataType
+ } else if ( converters[ conv2 ] !== true ) {
+ current = tmp[ 0 ];
+ dataTypes.unshift( tmp[ 1 ] );
+ }
+ break;
+ }
+ }
+ }
+ }
+
+ // Apply converter (if not an equivalence)
+ if ( conv !== true ) {
+
+ // Unless errors are allowed to bubble, catch and return them
+ if ( conv && s[ "throws" ] ) {
+ response = conv( response );
+ } else {
+ try {
+ response = conv( response );
+ } catch ( e ) {
+ return { state: "parsererror", error: conv ? e : "No conversion from " + prev + " to " + current };
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return { state: "success", data: response };
+}
+// Install script dataType
+jQuery.ajaxSetup({
+ accepts: {
+ script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"
+ },
+ contents: {
+ script: /(?:java|ecma)script/
+ },
+ converters: {
+ "text script": function( text ) {
+ jQuery.globalEval( text );
+ return text;
+ }
+ }
+});
+
+// Handle cache's special case and global
+jQuery.ajaxPrefilter( "script", function( s ) {
+ if ( s.cache === undefined ) {
+ s.cache = false;
+ }
+ if ( s.crossDomain ) {
+ s.type = "GET";
+ s.global = false;
+ }
+});
+
+// Bind script tag hack transport
+jQuery.ajaxTransport( "script", function(s) {
+
+ // This transport only deals with cross domain requests
+ if ( s.crossDomain ) {
+
+ var script,
+ head = document.head || jQuery("head")[0] || document.documentElement;
+
+ return {
+
+ send: function( _, callback ) {
+
+ script = document.createElement("script");
+
+ script.async = true;
+
+ if ( s.scriptCharset ) {
+ script.charset = s.scriptCharset;
+ }
+
+ script.src = s.url;
+
+ // Attach handlers for all browsers
+ script.onload = script.onreadystatechange = function( _, isAbort ) {
+
+ if ( isAbort || !script.readyState || /loaded|complete/.test( script.readyState ) ) {
+
+ // Handle memory leak in IE
+ script.onload = script.onreadystatechange = null;
+
+ // Remove the script
+ if ( script.parentNode ) {
+ script.parentNode.removeChild( script );
+ }
+
+ // Dereference the script
+ script = null;
+
+ // Callback if not abort
+ if ( !isAbort ) {
+ callback( 200, "success" );
+ }
+ }
+ };
+
+ // Circumvent IE6 bugs with base elements (#2709 and #4378) by prepending
+ // Use native DOM manipulation to avoid our domManip AJAX trickery
+ head.insertBefore( script, head.firstChild );
+ },
+
+ abort: function() {
+ if ( script ) {
+ script.onload( undefined, true );
+ }
+ }
+ };
+ }
+});
+var oldCallbacks = [],
+ rjsonp = /(=)\?(?=&|$)|\?\?/;
+
+// Default jsonp settings
+jQuery.ajaxSetup({
+ jsonp: "callback",
+ jsonpCallback: function() {
+ var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( ajax_nonce++ ) );
+ this[ callback ] = true;
+ return callback;
+ }
+});
+
+// Detect, normalize options and install callbacks for jsonp requests
+jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
+
+ var callbackName, overwritten, responseContainer,
+ jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?
+ "url" :
+ typeof s.data === "string" && !( s.contentType || "" ).indexOf("application/x-www-form-urlencoded") && rjsonp.test( s.data ) && "data"
+ );
+
+ // Handle iff the expected data type is "jsonp" or we have a parameter to set
+ if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) {
+
+ // Get callback name, remembering preexisting value associated with it
+ callbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ?
+ s.jsonpCallback() :
+ s.jsonpCallback;
+
+ // Insert callback into url or form data
+ if ( jsonProp ) {
+ s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName );
+ } else if ( s.jsonp !== false ) {
+ s.url += ( ajax_rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName;
+ }
+
+ // Use data converter to retrieve json after script execution
+ s.converters["script json"] = function() {
+ if ( !responseContainer ) {
+ jQuery.error( callbackName + " was not called" );
+ }
+ return responseContainer[ 0 ];
+ };
+
+ // force json dataType
+ s.dataTypes[ 0 ] = "json";
+
+ // Install callback
+ overwritten = window[ callbackName ];
+ window[ callbackName ] = function() {
+ responseContainer = arguments;
+ };
+
+ // Clean-up function (fires after converters)
+ jqXHR.always(function() {
+ // Restore preexisting value
+ window[ callbackName ] = overwritten;
+
+ // Save back as free
+ if ( s[ callbackName ] ) {
+ // make sure that re-using the options doesn't screw things around
+ s.jsonpCallback = originalSettings.jsonpCallback;
+
+ // save the callback name for future use
+ oldCallbacks.push( callbackName );
+ }
+
+ // Call if it was a function and we have a response
+ if ( responseContainer && jQuery.isFunction( overwritten ) ) {
+ overwritten( responseContainer[ 0 ] );
+ }
+
+ responseContainer = overwritten = undefined;
+ });
+
+ // Delegate to script
+ return "script";
+ }
+});
+var xhrCallbacks, xhrSupported,
+ xhrId = 0,
+ // #5280: Internet Explorer will keep connections alive if we don't abort on unload
+ xhrOnUnloadAbort = window.ActiveXObject && function() {
+ // Abort all pending requests
+ var key;
+ for ( key in xhrCallbacks ) {
+ xhrCallbacks[ key ]( undefined, true );
+ }
+ };
+
+// Functions to create xhrs
+function createStandardXHR() {
+ try {
+ return new window.XMLHttpRequest();
+ } catch( e ) {}
+}
+
+function createActiveXHR() {
+ try {
+ return new window.ActiveXObject("Microsoft.XMLHTTP");
+ } catch( e ) {}
+}
+
+// Create the request object
+// (This is still attached to ajaxSettings for backward compatibility)
+jQuery.ajaxSettings.xhr = window.ActiveXObject ?
+ /* Microsoft failed to properly
+ * implement the XMLHttpRequest in IE7 (can't request local files),
+ * so we use the ActiveXObject when it is available
+ * Additionally XMLHttpRequest can be disabled in IE7/IE8 so
+ * we need a fallback.
+ */
+ function() {
+ return !this.isLocal && createStandardXHR() || createActiveXHR();
+ } :
+ // For all other browsers, use the standard XMLHttpRequest object
+ createStandardXHR;
+
+// Determine support properties
+xhrSupported = jQuery.ajaxSettings.xhr();
+jQuery.support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported );
+xhrSupported = jQuery.support.ajax = !!xhrSupported;
+
+// Create transport if the browser can provide an xhr
+if ( xhrSupported ) {
+
+ jQuery.ajaxTransport(function( s ) {
+ // Cross domain only allowed if supported through XMLHttpRequest
+ if ( !s.crossDomain || jQuery.support.cors ) {
+
+ var callback;
+
+ return {
+ send: function( headers, complete ) {
+
+ // Get a new xhr
+ var handle, i,
+ xhr = s.xhr();
+
+ // Open the socket
+ // Passing null username, generates a login popup on Opera (#2865)
+ if ( s.username ) {
+ xhr.open( s.type, s.url, s.async, s.username, s.password );
+ } else {
+ xhr.open( s.type, s.url, s.async );
+ }
+
+ // Apply custom fields if provided
+ if ( s.xhrFields ) {
+ for ( i in s.xhrFields ) {
+ xhr[ i ] = s.xhrFields[ i ];
+ }
+ }
+
+ // Override mime type if needed
+ if ( s.mimeType && xhr.overrideMimeType ) {
+ xhr.overrideMimeType( s.mimeType );
+ }
+
+ // X-Requested-With header
+ // For cross-domain requests, seeing as conditions for a preflight are
+ // akin to a jigsaw puzzle, we simply never set it to be sure.
+ // (it can always be set on a per-request basis or even using ajaxSetup)
+ // For same-domain requests, won't change header if already provided.
+ if ( !s.crossDomain && !headers["X-Requested-With"] ) {
+ headers["X-Requested-With"] = "XMLHttpRequest";
+ }
+
+ // Need an extra try/catch for cross domain requests in Firefox 3
+ try {
+ for ( i in headers ) {
+ xhr.setRequestHeader( i, headers[ i ] );
+ }
+ } catch( err ) {}
+
+ // Do send the request
+ // This may raise an exception which is actually
+ // handled in jQuery.ajax (so no try/catch here)
+ xhr.send( ( s.hasContent && s.data ) || null );
+
+ // Listener
+ callback = function( _, isAbort ) {
+ var status, responseHeaders, statusText, responses;
+
+ // Firefox throws exceptions when accessing properties
+ // of an xhr when a network error occurred
+ // http://helpful.knobs-dials.com/index.php/Component_returned_failure_code:_0x80040111_(NS_ERROR_NOT_AVAILABLE)
+ try {
+
+ // Was never called and is aborted or complete
+ if ( callback && ( isAbort || xhr.readyState === 4 ) ) {
+
+ // Only called once
+ callback = undefined;
+
+ // Do not keep as active anymore
+ if ( handle ) {
+ xhr.onreadystatechange = jQuery.noop;
+ if ( xhrOnUnloadAbort ) {
+ delete xhrCallbacks[ handle ];
+ }
+ }
+
+ // If it's an abort
+ if ( isAbort ) {
+ // Abort it manually if needed
+ if ( xhr.readyState !== 4 ) {
+ xhr.abort();
+ }
+ } else {
+ responses = {};
+ status = xhr.status;
+ responseHeaders = xhr.getAllResponseHeaders();
+
+ // When requesting binary data, IE6-9 will throw an exception
+ // on any attempt to access responseText (#11426)
+ if ( typeof xhr.responseText === "string" ) {
+ responses.text = xhr.responseText;
+ }
+
+ // Firefox throws an exception when accessing
+ // statusText for faulty cross-domain requests
+ try {
+ statusText = xhr.statusText;
+ } catch( e ) {
+ // We normalize with Webkit giving an empty statusText
+ statusText = "";
+ }
+
+ // Filter status for non standard behaviors
+
+ // If the request is local and we have data: assume a success
+ // (success with no data won't get notified, that's the best we
+ // can do given current implementations)
+ if ( !status && s.isLocal && !s.crossDomain ) {
+ status = responses.text ? 200 : 404;
+ // IE - #1450: sometimes returns 1223 when it should be 204
+ } else if ( status === 1223 ) {
+ status = 204;
+ }
+ }
+ }
+ } catch( firefoxAccessException ) {
+ if ( !isAbort ) {
+ complete( -1, firefoxAccessException );
+ }
+ }
+
+ // Call complete if needed
+ if ( responses ) {
+ complete( status, statusText, responses, responseHeaders );
+ }
+ };
+
+ if ( !s.async ) {
+ // if we're in sync mode we fire the callback
+ callback();
+ } else if ( xhr.readyState === 4 ) {
+ // (IE6 & IE7) if it's in cache and has been
+ // retrieved directly we need to fire the callback
+ setTimeout( callback );
+ } else {
+ handle = ++xhrId;
+ if ( xhrOnUnloadAbort ) {
+ // Create the active xhrs callbacks list if needed
+ // and attach the unload handler
+ if ( !xhrCallbacks ) {
+ xhrCallbacks = {};
+ jQuery( window ).unload( xhrOnUnloadAbort );
+ }
+ // Add to list of active xhrs callbacks
+ xhrCallbacks[ handle ] = callback;
+ }
+ xhr.onreadystatechange = callback;
+ }
+ },
+
+ abort: function() {
+ if ( callback ) {
+ callback( undefined, true );
+ }
+ }
+ };
+ }
+ });
+}
+var fxNow, timerId,
+ rfxtypes = /^(?:toggle|show|hide)$/,
+ rfxnum = new RegExp( "^(?:([+-])=|)(" + core_pnum + ")([a-z%]*)$", "i" ),
+ rrun = /queueHooks$/,
+ animationPrefilters = [ defaultPrefilter ],
+ tweeners = {
+ "*": [function( prop, value ) {
+ var tween = this.createTween( prop, value ),
+ target = tween.cur(),
+ parts = rfxnum.exec( value ),
+ unit = parts && parts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ),
+
+ // Starting value computation is required for potential unit mismatches
+ start = ( jQuery.cssNumber[ prop ] || unit !== "px" && +target ) &&
+ rfxnum.exec( jQuery.css( tween.elem, prop ) ),
+ scale = 1,
+ maxIterations = 20;
+
+ if ( start && start[ 3 ] !== unit ) {
+ // Trust units reported by jQuery.css
+ unit = unit || start[ 3 ];
+
+ // Make sure we update the tween properties later on
+ parts = parts || [];
+
+ // Iteratively approximate from a nonzero starting point
+ start = +target || 1;
+
+ do {
+ // If previous iteration zeroed out, double until we get *something*
+ // Use a string for doubling factor so we don't accidentally see scale as unchanged below
+ scale = scale || ".5";
+
+ // Adjust and apply
+ start = start / scale;
+ jQuery.style( tween.elem, prop, start + unit );
+
+ // Update scale, tolerating zero or NaN from tween.cur()
+ // And breaking the loop if scale is unchanged or perfect, or if we've just had enough
+ } while ( scale !== (scale = tween.cur() / target) && scale !== 1 && --maxIterations );
+ }
+
+ // Update tween properties
+ if ( parts ) {
+ start = tween.start = +start || +target || 0;
+ tween.unit = unit;
+ // If a +=/-= token was provided, we're doing a relative animation
+ tween.end = parts[ 1 ] ?
+ start + ( parts[ 1 ] + 1 ) * parts[ 2 ] :
+ +parts[ 2 ];
+ }
+
+ return tween;
+ }]
+ };
+
+// Animations created synchronously will run synchronously
+function createFxNow() {
+ setTimeout(function() {
+ fxNow = undefined;
+ });
+ return ( fxNow = jQuery.now() );
+}
+
+function createTween( value, prop, animation ) {
+ var tween,
+ collection = ( tweeners[ prop ] || [] ).concat( tweeners[ "*" ] ),
+ index = 0,
+ length = collection.length;
+ for ( ; index < length; index++ ) {
+ if ( (tween = collection[ index ].call( animation, prop, value )) ) {
+
+ // we're done with this property
+ return tween;
+ }
+ }
+}
+
+function Animation( elem, properties, options ) {
+ var result,
+ stopped,
+ index = 0,
+ length = animationPrefilters.length,
+ deferred = jQuery.Deferred().always( function() {
+ // don't match elem in the :animated selector
+ delete tick.elem;
+ }),
+ tick = function() {
+ if ( stopped ) {
+ return false;
+ }
+ var currentTime = fxNow || createFxNow(),
+ remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),
+ // archaic crash bug won't allow us to use 1 - ( 0.5 || 0 ) (#12497)
+ temp = remaining / animation.duration || 0,
+ percent = 1 - temp,
+ index = 0,
+ length = animation.tweens.length;
+
+ for ( ; index < length ; index++ ) {
+ animation.tweens[ index ].run( percent );
+ }
+
+ deferred.notifyWith( elem, [ animation, percent, remaining ]);
+
+ if ( percent < 1 && length ) {
+ return remaining;
+ } else {
+ deferred.resolveWith( elem, [ animation ] );
+ return false;
+ }
+ },
+ animation = deferred.promise({
+ elem: elem,
+ props: jQuery.extend( {}, properties ),
+ opts: jQuery.extend( true, { specialEasing: {} }, options ),
+ originalProperties: properties,
+ originalOptions: options,
+ startTime: fxNow || createFxNow(),
+ duration: options.duration,
+ tweens: [],
+ createTween: function( prop, end ) {
+ var tween = jQuery.Tween( elem, animation.opts, prop, end,
+ animation.opts.specialEasing[ prop ] || animation.opts.easing );
+ animation.tweens.push( tween );
+ return tween;
+ },
+ stop: function( gotoEnd ) {
+ var index = 0,
+ // if we are going to the end, we want to run all the tweens
+ // otherwise we skip this part
+ length = gotoEnd ? animation.tweens.length : 0;
+ if ( stopped ) {
+ return this;
+ }
+ stopped = true;
+ for ( ; index < length ; index++ ) {
+ animation.tweens[ index ].run( 1 );
+ }
+
+ // resolve when we played the last frame
+ // otherwise, reject
+ if ( gotoEnd ) {
+ deferred.resolveWith( elem, [ animation, gotoEnd ] );
+ } else {
+ deferred.rejectWith( elem, [ animation, gotoEnd ] );
+ }
+ return this;
+ }
+ }),
+ props = animation.props;
+
+ propFilter( props, animation.opts.specialEasing );
+
+ for ( ; index < length ; index++ ) {
+ result = animationPrefilters[ index ].call( animation, elem, props, animation.opts );
+ if ( result ) {
+ return result;
+ }
+ }
+
+ jQuery.map( props, createTween, animation );
+
+ if ( jQuery.isFunction( animation.opts.start ) ) {
+ animation.opts.start.call( elem, animation );
+ }
+
+ jQuery.fx.timer(
+ jQuery.extend( tick, {
+ elem: elem,
+ anim: animation,
+ queue: animation.opts.queue
+ })
+ );
+
+ // attach callbacks from options
+ return animation.progress( animation.opts.progress )
+ .done( animation.opts.done, animation.opts.complete )
+ .fail( animation.opts.fail )
+ .always( animation.opts.always );
+}
+
+function propFilter( props, specialEasing ) {
+ var index, name, easing, value, hooks;
+
+ // camelCase, specialEasing and expand cssHook pass
+ for ( index in props ) {
+ name = jQuery.camelCase( index );
+ easing = specialEasing[ name ];
+ value = props[ index ];
+ if ( jQuery.isArray( value ) ) {
+ easing = value[ 1 ];
+ value = props[ index ] = value[ 0 ];
+ }
+
+ if ( index !== name ) {
+ props[ name ] = value;
+ delete props[ index ];
+ }
+
+ hooks = jQuery.cssHooks[ name ];
+ if ( hooks && "expand" in hooks ) {
+ value = hooks.expand( value );
+ delete props[ name ];
+
+ // not quite $.extend, this wont overwrite keys already present.
+ // also - reusing 'index' from above because we have the correct "name"
+ for ( index in value ) {
+ if ( !( index in props ) ) {
+ props[ index ] = value[ index ];
+ specialEasing[ index ] = easing;
+ }
+ }
+ } else {
+ specialEasing[ name ] = easing;
+ }
+ }
+}
+
+jQuery.Animation = jQuery.extend( Animation, {
+
+ tweener: function( props, callback ) {
+ if ( jQuery.isFunction( props ) ) {
+ callback = props;
+ props = [ "*" ];
+ } else {
+ props = props.split(" ");
+ }
+
+ var prop,
+ index = 0,
+ length = props.length;
+
+ for ( ; index < length ; index++ ) {
+ prop = props[ index ];
+ tweeners[ prop ] = tweeners[ prop ] || [];
+ tweeners[ prop ].unshift( callback );
+ }
+ },
+
+ prefilter: function( callback, prepend ) {
+ if ( prepend ) {
+ animationPrefilters.unshift( callback );
+ } else {
+ animationPrefilters.push( callback );
+ }
+ }
+});
+
+function defaultPrefilter( elem, props, opts ) {
+ /* jshint validthis: true */
+ var prop, value, toggle, tween, hooks, oldfire,
+ anim = this,
+ orig = {},
+ style = elem.style,
+ hidden = elem.nodeType && isHidden( elem ),
+ dataShow = jQuery._data( elem, "fxshow" );
+
+ // handle queue: false promises
+ if ( !opts.queue ) {
+ hooks = jQuery._queueHooks( elem, "fx" );
+ if ( hooks.unqueued == null ) {
+ hooks.unqueued = 0;
+ oldfire = hooks.empty.fire;
+ hooks.empty.fire = function() {
+ if ( !hooks.unqueued ) {
+ oldfire();
+ }
+ };
+ }
+ hooks.unqueued++;
+
+ anim.always(function() {
+ // doing this makes sure that the complete handler will be called
+ // before this completes
+ anim.always(function() {
+ hooks.unqueued--;
+ if ( !jQuery.queue( elem, "fx" ).length ) {
+ hooks.empty.fire();
+ }
+ });
+ });
+ }
+
+ // height/width overflow pass
+ if ( elem.nodeType === 1 && ( "height" in props || "width" in props ) ) {
+ // Make sure that nothing sneaks out
+ // Record all 3 overflow attributes because IE does not
+ // change the overflow attribute when overflowX and
+ // overflowY are set to the same value
+ opts.overflow = [ style.overflow, style.overflowX, style.overflowY ];
+
+ // Set display property to inline-block for height/width
+ // animations on inline elements that are having width/height animated
+ if ( jQuery.css( elem, "display" ) === "inline" &&
+ jQuery.css( elem, "float" ) === "none" ) {
+
+ // inline-level elements accept inline-block;
+ // block-level elements need to be inline with layout
+ if ( !jQuery.support.inlineBlockNeedsLayout || css_defaultDisplay( elem.nodeName ) === "inline" ) {
+ style.display = "inline-block";
+
+ } else {
+ style.zoom = 1;
+ }
+ }
+ }
+
+ if ( opts.overflow ) {
+ style.overflow = "hidden";
+ if ( !jQuery.support.shrinkWrapBlocks ) {
+ anim.always(function() {
+ style.overflow = opts.overflow[ 0 ];
+ style.overflowX = opts.overflow[ 1 ];
+ style.overflowY = opts.overflow[ 2 ];
+ });
+ }
+ }
+
+
+ // show/hide pass
+ for ( prop in props ) {
+ value = props[ prop ];
+ if ( rfxtypes.exec( value ) ) {
+ delete props[ prop ];
+ toggle = toggle || value === "toggle";
+ if ( value === ( hidden ? "hide" : "show" ) ) {
+ continue;
+ }
+ orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );
+ }
+ }
+
+ if ( !jQuery.isEmptyObject( orig ) ) {
+ if ( dataShow ) {
+ if ( "hidden" in dataShow ) {
+ hidden = dataShow.hidden;
+ }
+ } else {
+ dataShow = jQuery._data( elem, "fxshow", {} );
+ }
+
+ // store state if its toggle - enables .stop().toggle() to "reverse"
+ if ( toggle ) {
+ dataShow.hidden = !hidden;
+ }
+ if ( hidden ) {
+ jQuery( elem ).show();
+ } else {
+ anim.done(function() {
+ jQuery( elem ).hide();
+ });
+ }
+ anim.done(function() {
+ var prop;
+ jQuery._removeData( elem, "fxshow" );
+ for ( prop in orig ) {
+ jQuery.style( elem, prop, orig[ prop ] );
+ }
+ });
+ for ( prop in orig ) {
+ tween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );
+
+ if ( !( prop in dataShow ) ) {
+ dataShow[ prop ] = tween.start;
+ if ( hidden ) {
+ tween.end = tween.start;
+ tween.start = prop === "width" || prop === "height" ? 1 : 0;
+ }
+ }
+ }
+ }
+}
+
+function Tween( elem, options, prop, end, easing ) {
+ return new Tween.prototype.init( elem, options, prop, end, easing );
+}
+jQuery.Tween = Tween;
+
+Tween.prototype = {
+ constructor: Tween,
+ init: function( elem, options, prop, end, easing, unit ) {
+ this.elem = elem;
+ this.prop = prop;
+ this.easing = easing || "swing";
+ this.options = options;
+ this.start = this.now = this.cur();
+ this.end = end;
+ this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" );
+ },
+ cur: function() {
+ var hooks = Tween.propHooks[ this.prop ];
+
+ return hooks && hooks.get ?
+ hooks.get( this ) :
+ Tween.propHooks._default.get( this );
+ },
+ run: function( percent ) {
+ var eased,
+ hooks = Tween.propHooks[ this.prop ];
+
+ if ( this.options.duration ) {
+ this.pos = eased = jQuery.easing[ this.easing ](
+ percent, this.options.duration * percent, 0, 1, this.options.duration
+ );
+ } else {
+ this.pos = eased = percent;
+ }
+ this.now = ( this.end - this.start ) * eased + this.start;
+
+ if ( this.options.step ) {
+ this.options.step.call( this.elem, this.now, this );
+ }
+
+ if ( hooks && hooks.set ) {
+ hooks.set( this );
+ } else {
+ Tween.propHooks._default.set( this );
+ }
+ return this;
+ }
+};
+
+Tween.prototype.init.prototype = Tween.prototype;
+
+Tween.propHooks = {
+ _default: {
+ get: function( tween ) {
+ var result;
+
+ if ( tween.elem[ tween.prop ] != null &&
+ (!tween.elem.style || tween.elem.style[ tween.prop ] == null) ) {
+ return tween.elem[ tween.prop ];
+ }
+
+ // passing an empty string as a 3rd parameter to .css will automatically
+ // attempt a parseFloat and fallback to a string if the parse fails
+ // so, simple values such as "10px" are parsed to Float.
+ // complex values such as "rotate(1rad)" are returned as is.
+ result = jQuery.css( tween.elem, tween.prop, "" );
+ // Empty strings, null, undefined and "auto" are converted to 0.
+ return !result || result === "auto" ? 0 : result;
+ },
+ set: function( tween ) {
+ // use step hook for back compat - use cssHook if its there - use .style if its
+ // available and use plain properties where available
+ if ( jQuery.fx.step[ tween.prop ] ) {
+ jQuery.fx.step[ tween.prop ]( tween );
+ } else if ( tween.elem.style && ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null || jQuery.cssHooks[ tween.prop ] ) ) {
+ jQuery.style( tween.elem, tween.prop, tween.now + tween.unit );
+ } else {
+ tween.elem[ tween.prop ] = tween.now;
+ }
+ }
+ }
+};
+
+// Support: IE <=9
+// Panic based approach to setting things on disconnected nodes
+
+Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {
+ set: function( tween ) {
+ if ( tween.elem.nodeType && tween.elem.parentNode ) {
+ tween.elem[ tween.prop ] = tween.now;
+ }
+ }
+};
+
+jQuery.each([ "toggle", "show", "hide" ], function( i, name ) {
+ var cssFn = jQuery.fn[ name ];
+ jQuery.fn[ name ] = function( speed, easing, callback ) {
+ return speed == null || typeof speed === "boolean" ?
+ cssFn.apply( this, arguments ) :
+ this.animate( genFx( name, true ), speed, easing, callback );
+ };
+});
+
+jQuery.fn.extend({
+ fadeTo: function( speed, to, easing, callback ) {
+
+ // show any hidden elements after setting opacity to 0
+ return this.filter( isHidden ).css( "opacity", 0 ).show()
+
+ // animate to the value specified
+ .end().animate({ opacity: to }, speed, easing, callback );
+ },
+ animate: function( prop, speed, easing, callback ) {
+ var empty = jQuery.isEmptyObject( prop ),
+ optall = jQuery.speed( speed, easing, callback ),
+ doAnimation = function() {
+ // Operate on a copy of prop so per-property easing won't be lost
+ var anim = Animation( this, jQuery.extend( {}, prop ), optall );
+
+ // Empty animations, or finishing resolves immediately
+ if ( empty || jQuery._data( this, "finish" ) ) {
+ anim.stop( true );
+ }
+ };
+ doAnimation.finish = doAnimation;
+
+ return empty || optall.queue === false ?
+ this.each( doAnimation ) :
+ this.queue( optall.queue, doAnimation );
+ },
+ stop: function( type, clearQueue, gotoEnd ) {
+ var stopQueue = function( hooks ) {
+ var stop = hooks.stop;
+ delete hooks.stop;
+ stop( gotoEnd );
+ };
+
+ if ( typeof type !== "string" ) {
+ gotoEnd = clearQueue;
+ clearQueue = type;
+ type = undefined;
+ }
+ if ( clearQueue && type !== false ) {
+ this.queue( type || "fx", [] );
+ }
+
+ return this.each(function() {
+ var dequeue = true,
+ index = type != null && type + "queueHooks",
+ timers = jQuery.timers,
+ data = jQuery._data( this );
+
+ if ( index ) {
+ if ( data[ index ] && data[ index ].stop ) {
+ stopQueue( data[ index ] );
+ }
+ } else {
+ for ( index in data ) {
+ if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {
+ stopQueue( data[ index ] );
+ }
+ }
+ }
+
+ for ( index = timers.length; index--; ) {
+ if ( timers[ index ].elem === this && (type == null || timers[ index ].queue === type) ) {
+ timers[ index ].anim.stop( gotoEnd );
+ dequeue = false;
+ timers.splice( index, 1 );
+ }
+ }
+
+ // start the next in the queue if the last step wasn't forced
+ // timers currently will call their complete callbacks, which will dequeue
+ // but only if they were gotoEnd
+ if ( dequeue || !gotoEnd ) {
+ jQuery.dequeue( this, type );
+ }
+ });
+ },
+ finish: function( type ) {
+ if ( type !== false ) {
+ type = type || "fx";
+ }
+ return this.each(function() {
+ var index,
+ data = jQuery._data( this ),
+ queue = data[ type + "queue" ],
+ hooks = data[ type + "queueHooks" ],
+ timers = jQuery.timers,
+ length = queue ? queue.length : 0;
+
+ // enable finishing flag on private data
+ data.finish = true;
+
+ // empty the queue first
+ jQuery.queue( this, type, [] );
+
+ if ( hooks && hooks.stop ) {
+ hooks.stop.call( this, true );
+ }
+
+ // look for any active animations, and finish them
+ for ( index = timers.length; index--; ) {
+ if ( timers[ index ].elem === this && timers[ index ].queue === type ) {
+ timers[ index ].anim.stop( true );
+ timers.splice( index, 1 );
+ }
+ }
+
+ // look for any animations in the old queue and finish them
+ for ( index = 0; index < length; index++ ) {
+ if ( queue[ index ] && queue[ index ].finish ) {
+ queue[ index ].finish.call( this );
+ }
+ }
+
+ // turn off finishing flag
+ delete data.finish;
+ });
+ }
+});
+
+// Generate parameters to create a standard animation
+function genFx( type, includeWidth ) {
+ var which,
+ attrs = { height: type },
+ i = 0;
+
+ // if we include width, step value is 1 to do all cssExpand values,
+ // if we don't include width, step value is 2 to skip over Left and Right
+ includeWidth = includeWidth? 1 : 0;
+ for( ; i < 4 ; i += 2 - includeWidth ) {
+ which = cssExpand[ i ];
+ attrs[ "margin" + which ] = attrs[ "padding" + which ] = type;
+ }
+
+ if ( includeWidth ) {
+ attrs.opacity = attrs.width = type;
+ }
+
+ return attrs;
+}
+
+// Generate shortcuts for custom animations
+jQuery.each({
+ slideDown: genFx("show"),
+ slideUp: genFx("hide"),
+ slideToggle: genFx("toggle"),
+ fadeIn: { opacity: "show" },
+ fadeOut: { opacity: "hide" },
+ fadeToggle: { opacity: "toggle" }
+}, function( name, props ) {
+ jQuery.fn[ name ] = function( speed, easing, callback ) {
+ return this.animate( props, speed, easing, callback );
+ };
+});
+
+jQuery.speed = function( speed, easing, fn ) {
+ var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : {
+ complete: fn || !fn && easing ||
+ jQuery.isFunction( speed ) && speed,
+ duration: speed,
+ easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing
+ };
+
+ opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
+ opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default;
+
+ // normalize opt.queue - true/undefined/null -> "fx"
+ if ( opt.queue == null || opt.queue === true ) {
+ opt.queue = "fx";
+ }
+
+ // Queueing
+ opt.old = opt.complete;
+
+ opt.complete = function() {
+ if ( jQuery.isFunction( opt.old ) ) {
+ opt.old.call( this );
+ }
+
+ if ( opt.queue ) {
+ jQuery.dequeue( this, opt.queue );
+ }
+ };
+
+ return opt;
+};
+
+jQuery.easing = {
+ linear: function( p ) {
+ return p;
+ },
+ swing: function( p ) {
+ return 0.5 - Math.cos( p*Math.PI ) / 2;
+ }
+};
+
+jQuery.timers = [];
+jQuery.fx = Tween.prototype.init;
+jQuery.fx.tick = function() {
+ var timer,
+ timers = jQuery.timers,
+ i = 0;
+
+ fxNow = jQuery.now();
+
+ for ( ; i < timers.length; i++ ) {
+ timer = timers[ i ];
+ // Checks the timer has not already been removed
+ if ( !timer() && timers[ i ] === timer ) {
+ timers.splice( i--, 1 );
+ }
+ }
+
+ if ( !timers.length ) {
+ jQuery.fx.stop();
+ }
+ fxNow = undefined;
+};
+
+jQuery.fx.timer = function( timer ) {
+ if ( timer() && jQuery.timers.push( timer ) ) {
+ jQuery.fx.start();
+ }
+};
+
+jQuery.fx.interval = 13;
+
+jQuery.fx.start = function() {
+ if ( !timerId ) {
+ timerId = setInterval( jQuery.fx.tick, jQuery.fx.interval );
+ }
+};
+
+jQuery.fx.stop = function() {
+ clearInterval( timerId );
+ timerId = null;
+};
+
+jQuery.fx.speeds = {
+ slow: 600,
+ fast: 200,
+ // Default speed
+ _default: 400
+};
+
+// Back Compat <1.8 extension point
+jQuery.fx.step = {};
+
+if ( jQuery.expr && jQuery.expr.filters ) {
+ jQuery.expr.filters.animated = function( elem ) {
+ return jQuery.grep(jQuery.timers, function( fn ) {
+ return elem === fn.elem;
+ }).length;
+ };
+}
+jQuery.fn.offset = function( options ) {
+ if ( arguments.length ) {
+ return options === undefined ?
+ this :
+ this.each(function( i ) {
+ jQuery.offset.setOffset( this, options, i );
+ });
+ }
+
+ var docElem, win,
+ box = { top: 0, left: 0 },
+ elem = this[ 0 ],
+ doc = elem && elem.ownerDocument;
+
+ if ( !doc ) {
+ return;
+ }
+
+ docElem = doc.documentElement;
+
+ // Make sure it's not a disconnected DOM node
+ if ( !jQuery.contains( docElem, elem ) ) {
+ return box;
+ }
+
+ // If we don't have gBCR, just use 0,0 rather than error
+ // BlackBerry 5, iOS 3 (original iPhone)
+ if ( typeof elem.getBoundingClientRect !== core_strundefined ) {
+ box = elem.getBoundingClientRect();
+ }
+ win = getWindow( doc );
+ return {
+ top: box.top + ( win.pageYOffset || docElem.scrollTop ) - ( docElem.clientTop || 0 ),
+ left: box.left + ( win.pageXOffset || docElem.scrollLeft ) - ( docElem.clientLeft || 0 )
+ };
+};
+
+jQuery.offset = {
+
+ setOffset: function( elem, options, i ) {
+ var position = jQuery.css( elem, "position" );
+
+ // set position first, in-case top/left are set even on static elem
+ if ( position === "static" ) {
+ elem.style.position = "relative";
+ }
+
+ var curElem = jQuery( elem ),
+ curOffset = curElem.offset(),
+ curCSSTop = jQuery.css( elem, "top" ),
+ curCSSLeft = jQuery.css( elem, "left" ),
+ calculatePosition = ( position === "absolute" || position === "fixed" ) && jQuery.inArray("auto", [curCSSTop, curCSSLeft]) > -1,
+ props = {}, curPosition = {}, curTop, curLeft;
+
+ // need to be able to calculate position if either top or left is auto and position is either absolute or fixed
+ if ( calculatePosition ) {
+ curPosition = curElem.position();
+ curTop = curPosition.top;
+ curLeft = curPosition.left;
+ } else {
+ curTop = parseFloat( curCSSTop ) || 0;
+ curLeft = parseFloat( curCSSLeft ) || 0;
+ }
+
+ if ( jQuery.isFunction( options ) ) {
+ options = options.call( elem, i, curOffset );
+ }
+
+ if ( options.top != null ) {
+ props.top = ( options.top - curOffset.top ) + curTop;
+ }
+ if ( options.left != null ) {
+ props.left = ( options.left - curOffset.left ) + curLeft;
+ }
+
+ if ( "using" in options ) {
+ options.using.call( elem, props );
+ } else {
+ curElem.css( props );
+ }
+ }
+};
+
+
+jQuery.fn.extend({
+
+ position: function() {
+ if ( !this[ 0 ] ) {
+ return;
+ }
+
+ var offsetParent, offset,
+ parentOffset = { top: 0, left: 0 },
+ elem = this[ 0 ];
+
+ // fixed elements are offset from window (parentOffset = {top:0, left: 0}, because it is it's only offset parent
+ if ( jQuery.css( elem, "position" ) === "fixed" ) {
+ // we assume that getBoundingClientRect is available when computed position is fixed
+ offset = elem.getBoundingClientRect();
+ } else {
+ // Get *real* offsetParent
+ offsetParent = this.offsetParent();
+
+ // Get correct offsets
+ offset = this.offset();
+ if ( !jQuery.nodeName( offsetParent[ 0 ], "html" ) ) {
+ parentOffset = offsetParent.offset();
+ }
+
+ // Add offsetParent borders
+ parentOffset.top += jQuery.css( offsetParent[ 0 ], "borderTopWidth", true );
+ parentOffset.left += jQuery.css( offsetParent[ 0 ], "borderLeftWidth", true );
+ }
+
+ // Subtract parent offsets and element margins
+ // note: when an element has margin: auto the offsetLeft and marginLeft
+ // are the same in Safari causing offset.left to incorrectly be 0
+ return {
+ top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ),
+ left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true)
+ };
+ },
+
+ offsetParent: function() {
+ return this.map(function() {
+ var offsetParent = this.offsetParent || docElem;
+ while ( offsetParent && ( !jQuery.nodeName( offsetParent, "html" ) && jQuery.css( offsetParent, "position") === "static" ) ) {
+ offsetParent = offsetParent.offsetParent;
+ }
+ return offsetParent || docElem;
+ });
+ }
+});
+
+
+// Create scrollLeft and scrollTop methods
+jQuery.each( {scrollLeft: "pageXOffset", scrollTop: "pageYOffset"}, function( method, prop ) {
+ var top = /Y/.test( prop );
+
+ jQuery.fn[ method ] = function( val ) {
+ return jQuery.access( this, function( elem, method, val ) {
+ var win = getWindow( elem );
+
+ if ( val === undefined ) {
+ return win ? (prop in win) ? win[ prop ] :
+ win.document.documentElement[ method ] :
+ elem[ method ];
+ }
+
+ if ( win ) {
+ win.scrollTo(
+ !top ? val : jQuery( win ).scrollLeft(),
+ top ? val : jQuery( win ).scrollTop()
+ );
+
+ } else {
+ elem[ method ] = val;
+ }
+ }, method, val, arguments.length, null );
+ };
+});
+
+function getWindow( elem ) {
+ return jQuery.isWindow( elem ) ?
+ elem :
+ elem.nodeType === 9 ?
+ elem.defaultView || elem.parentWindow :
+ false;
+}
+// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods
+jQuery.each( { Height: "height", Width: "width" }, function( name, type ) {
+ jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name }, function( defaultExtra, funcName ) {
+ // margin is only for outerHeight, outerWidth
+ jQuery.fn[ funcName ] = function( margin, value ) {
+ var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ),
+ extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" );
+
+ return jQuery.access( this, function( elem, type, value ) {
+ var doc;
+
+ if ( jQuery.isWindow( elem ) ) {
+ // As of 5/8/2012 this will yield incorrect results for Mobile Safari, but there
+ // isn't a whole lot we can do. See pull request at this URL for discussion:
+ // https://github.com/jquery/jquery/pull/764
+ return elem.document.documentElement[ "client" + name ];
+ }
+
+ // Get document width or height
+ if ( elem.nodeType === 9 ) {
+ doc = elem.documentElement;
+
+ // Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height], whichever is greatest
+ // unfortunately, this causes bug #3838 in IE6/8 only, but there is currently no good, small way to fix it.
+ return Math.max(
+ elem.body[ "scroll" + name ], doc[ "scroll" + name ],
+ elem.body[ "offset" + name ], doc[ "offset" + name ],
+ doc[ "client" + name ]
+ );
+ }
+
+ return value === undefined ?
+ // Get width or height on the element, requesting but not forcing parseFloat
+ jQuery.css( elem, type, extra ) :
+
+ // Set width or height on the element
+ jQuery.style( elem, type, value, extra );
+ }, type, chainable ? margin : undefined, chainable, null );
+ };
+ });
+});
+// Limit scope pollution from any deprecated API
+// (function() {
+
+// The number of elements contained in the matched element set
+jQuery.fn.size = function() {
+ return this.length;
+};
+
+jQuery.fn.andSelf = jQuery.fn.addBack;
+
+// })();
+if ( typeof module === "object" && module && typeof module.exports === "object" ) {
+ // Expose jQuery as module.exports in loaders that implement the Node
+ // module pattern (including browserify). Do not create the global, since
+ // the user will be storing it themselves locally, and globals are frowned
+ // upon in the Node module world.
+ module.exports = jQuery;
+} else {
+ // Otherwise expose jQuery to the global object as usual
+ window.jQuery = window.$ = jQuery;
+
+ // Register as a named AMD module, since jQuery can be concatenated with other
+ // files that may use define, but not via a proper concatenation script that
+ // understands anonymous AMD modules. A named AMD is safest and most robust
+ // way to register. Lowercase jquery is used because AMD module names are
+ // derived from file names, and jQuery is normally delivered in a lowercase
+ // file name. Do this after creating the global so that if an AMD module wants
+ // to call noConflict to hide this version of jQuery, it will work.
+ if ( typeof define === "function" && define.amd ) {
+ define( "jquery", [], function () { return jQuery; } );
+ }
+}
+
+})( window );
diff --git a/js/projectDocumentationWidget.js b/js/projectDocumentationWidget.js
new file mode 100644
index 00000000..2e30a358
--- /dev/null
+++ b/js/projectDocumentationWidget.js
@@ -0,0 +1,192 @@
+window.Spring = window.Spring || {};
+
+/* ERB style templates conflict with Jekyll HTML escaping */
+_.templateSettings = {
+ evaluate : /\{@([\s\S]+?)@\}/g,
+ interpolate : /\{@=([\s\S]+?)@\}/g,
+ escape : /\{@-([\s\S]+?)@\}/g
+};
+
+Spring.ProjectDocumentationWidget = function () {
+ var quickStartEl = $('[data-download-widget-controls]');
+ var mavenWidgetEl = $('.js-download-maven-widget');
+ var documentationEl = $('.js-documentation-widget');
+
+ var projectUrl = apiBaseUrl + "/project_metadata/" + projectId;
+ var promise = Spring.loadProject(projectUrl);
+
+ promise.then(function (project) {
+ Spring.buildDocumentationWidget(documentationEl, project);
+ Spring.buildQuickStartWidget(quickStartEl, mavenWidgetEl, project);
+ });
+};
+
+Spring.buildDocumentationWidget = function (documentationEl, project) {
+ new Spring.DocumentationWidgetView({
+ el: documentationEl,
+ model: project,
+ template: $("#project-documentation-widget-template").text()
+ }).render();
+
+}
+Spring.buildQuickStartWidget = function (quickStartEl, mavenWidgetEl, project) {
+ new Spring.QuickStartSelectorView({
+ el: quickStartEl,
+ model: project,
+ template: $("#project-download-widget-controls-template").text(),
+ snippetWidgetEl: mavenWidgetEl
+ }).render();
+}
+
+Spring.loadProject = function (url) {
+ return $.ajax(url, {
+ dataType: 'jsonp',
+ processData: false
+ }).then(function (value) {
+ return new Spring.Project(value);
+ });
+}
+
+Spring.Release = function (data) {
+ _.extend(this, data);
+}
+
+Spring.Release.prototype = {
+ statusIconClass: function () {
+ if (this.preRelease) {
+ return "spring-icon-pre-release";
+ } else if (this.generalAvailability) {
+ return "spring-icon-ga-release";
+ } else {
+ return "spring-icon-snapshot-release";
+ }
+ }
+}
+
+Spring.Project = function (data) {
+ _.extend(this, data);
+ var self = this;
+ this.releases = _.map(this.projectReleases, function (r) {
+ return new Spring.Release(r);
+ });
+
+ return this;
+};
+
+Spring.DocumentationWidgetView = Backbone.View.extend({
+ initialize: function () {
+ this.template = _.template(this.options.template);
+ _.bindAll(this, "render");
+ },
+
+ render: function () {
+ this.$el.html(
+ this.template(this.model)
+ );
+ return this;
+ }
+});
+
+Spring.SnippetView = Backbone.View.extend({
+ initialize: function () {
+ var snippetType = this.options.snippetType;
+ var downloadTemplate = $(document.createElement('div')).html($("#project-download-" + snippetType + "-widget-template").text());
+ var repositoryTemplate = $(document.createElement('div')).html($("#project-repository-" + snippetType + "-widget-template").text());
+ this.combinedTemplate = _.template(
+ "
" +
+ downloadTemplate.find("code:first").html() +
+ "{@ if (repository) { @}" +
+ repositoryTemplate.find("code:first").html() +
+ "{@ } @}" +
+ ""
+ );
+ _.bindAll(this, "render");
+ },
+
+ render: function () {
+
+ var html = $(this.combinedTemplate(this.model));
+ this.$el.html(html);
+ Spring.buildCopyButton(html.find(":first"), "snippet");
+ return this;
+ },
+
+ remove: function() {
+ this.undelegateEvents();
+ this.$el.empty();
+ this.unbind();
+ }
+});
+
+Spring.QuickStartSelectorView = Backbone.View.extend({
+ events: {
+ "change .selector": "renderActiveWidget",
+ "click .js-item": "changeDownloadSource"
+ },
+
+ initialize: function () {
+ this.template = _.template(this.options.template);
+ this.snippetWidgetEl = this.options.snippetWidgetEl;
+ _.bindAll(this, "render", "renderActiveWidget", "changeDownloadSource", "_moveItemSlider", "selectCurrent");
+ },
+
+ render: function () {
+ this.$el.html(
+ this.template(this.model)
+ );
+ this.renderActiveWidget();
+ this.selectCurrent();
+ this.$('.selectpicker').selectpicker();
+ return this;
+ },
+
+ selectCurrent: function() {
+ var selectedIndex = $('.selectpicker [data-current="true"]').val();
+ if(selectedIndex == undefined) {
+ selectedIndex = 0;
+ }
+ this.$('.selectpicker').val(selectedIndex).change();
+ },
+
+ renderActiveWidget: function() {
+ if(this.activeWidget != null) this.activeWidget.remove();
+
+ this.activeWidget = new Spring.SnippetView({
+ el: this.snippetWidgetEl,
+ model: this.model.releases[this.$('.selector :selected').val()],
+ snippetType: this.$('.js-active').data('snippet-type')
+ });
+ this.activeWidget.render();
+
+ },
+
+ changeDownloadSource: function (event) {
+ var target = $(event.target);
+
+ target.addClass("js-active");
+ target.siblings().removeClass("js-active");
+
+ this._moveItemSlider();
+ this.renderActiveWidget();
+ },
+
+ _moveItemSlider: function () {
+ var activeItem = $(".js-item-slider--wrapper .js-item.js-active");
+ if (activeItem.length == 0) {
+ return;
+ } else {
+ var activeItemPosition = activeItem.position();
+ var activeItemOffset = activeItemPosition.left;
+ var activeItemWidth = activeItem.outerWidth();
+
+ var slider = $(".js-item--slider");
+ var sliderPosition = slider.position();
+ var sliderOffset = sliderPosition.left;
+ var sliderTarget = activeItemOffset - sliderOffset;
+
+ slider.width(activeItemWidth);
+ slider.css("margin-left", sliderTarget);
+ }
+ }
+
+});
diff --git a/js/test/SpecRunner.html b/js/test/SpecRunner.html
new file mode 100644
index 00000000..877cfa2b
--- /dev/null
+++ b/js/test/SpecRunner.html
@@ -0,0 +1,66 @@
+---
+layout: spec_layout
+title: Your Project Name Here
+---
+
+
+
+
+
Jasmine Spec Runner
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {% include widget_templates.html %}
+
+
+
+
+
+
+
+
diff --git a/js/test/lib/jasmine-1.3.1/MIT.LICENSE b/js/test/lib/jasmine-1.3.1/MIT.LICENSE
new file mode 100644
index 00000000..7c435baa
--- /dev/null
+++ b/js/test/lib/jasmine-1.3.1/MIT.LICENSE
@@ -0,0 +1,20 @@
+Copyright (c) 2008-2011 Pivotal Labs
+
+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/js/test/lib/jasmine-1.3.1/jasmine-html.js b/js/test/lib/jasmine-1.3.1/jasmine-html.js
new file mode 100644
index 00000000..fa1863d1
--- /dev/null
+++ b/js/test/lib/jasmine-1.3.1/jasmine-html.js
@@ -0,0 +1,681 @@
+jasmine.HtmlReporterHelpers = {};
+
+jasmine.HtmlReporterHelpers.createDom = function(type, attrs, childrenVarArgs) {
+ var el = document.createElement(type);
+
+ for (var i = 2; i < arguments.length; i++) {
+ var child = arguments[i];
+
+ if (typeof child === 'string') {
+ el.appendChild(document.createTextNode(child));
+ } else {
+ if (child) {
+ el.appendChild(child);
+ }
+ }
+ }
+
+ for (var attr in attrs) {
+ if (attr == "className") {
+ el[attr] = attrs[attr];
+ } else {
+ el.setAttribute(attr, attrs[attr]);
+ }
+ }
+
+ return el;
+};
+
+jasmine.HtmlReporterHelpers.getSpecStatus = function(child) {
+ var results = child.results();
+ var status = results.passed() ? 'passed' : 'failed';
+ if (results.skipped) {
+ status = 'skipped';
+ }
+
+ return status;
+};
+
+jasmine.HtmlReporterHelpers.appendToSummary = function(child, childElement) {
+ var parentDiv = this.dom.summary;
+ var parentSuite = (typeof child.parentSuite == 'undefined') ? 'suite' : 'parentSuite';
+ var parent = child[parentSuite];
+
+ if (parent) {
+ if (typeof this.views.suites[parent.id] == 'undefined') {
+ this.views.suites[parent.id] = new jasmine.HtmlReporter.SuiteView(parent, this.dom, this.views);
+ }
+ parentDiv = this.views.suites[parent.id].element;
+ }
+
+ parentDiv.appendChild(childElement);
+};
+
+
+jasmine.HtmlReporterHelpers.addHelpers = function(ctor) {
+ for(var fn in jasmine.HtmlReporterHelpers) {
+ ctor.prototype[fn] = jasmine.HtmlReporterHelpers[fn];
+ }
+};
+
+jasmine.HtmlReporter = function(_doc) {
+ var self = this;
+ var doc = _doc || window.document;
+
+ var reporterView;
+
+ var dom = {};
+
+ // Jasmine Reporter Public Interface
+ self.logRunningSpecs = false;
+
+ self.reportRunnerStarting = function(runner) {
+ var specs = runner.specs() || [];
+
+ if (specs.length == 0) {
+ return;
+ }
+
+ createReporterDom(runner.env.versionString());
+ doc.body.appendChild(dom.reporter);
+ setExceptionHandling();
+
+ reporterView = new jasmine.HtmlReporter.ReporterView(dom);
+ reporterView.addSpecs(specs, self.specFilter);
+ };
+
+ self.reportRunnerResults = function(runner) {
+ reporterView && reporterView.complete();
+ };
+
+ self.reportSuiteResults = function(suite) {
+ reporterView.suiteComplete(suite);
+ };
+
+ self.reportSpecStarting = function(spec) {
+ if (self.logRunningSpecs) {
+ self.log('>> Jasmine Running ' + spec.suite.description + ' ' + spec.description + '...');
+ }
+ };
+
+ self.reportSpecResults = function(spec) {
+ reporterView.specComplete(spec);
+ };
+
+ self.log = function() {
+ var console = jasmine.getGlobal().console;
+ if (console && console.log) {
+ if (console.log.apply) {
+ console.log.apply(console, arguments);
+ } else {
+ console.log(arguments); // ie fix: console.log.apply doesn't exist on ie
+ }
+ }
+ };
+
+ self.specFilter = function(spec) {
+ if (!focusedSpecName()) {
+ return true;
+ }
+
+ return spec.getVersion().indexOf(focusedSpecName()) === 0;
+ };
+
+ return self;
+
+ function focusedSpecName() {
+ var specName;
+
+ (function memoizeFocusedSpec() {
+ if (specName) {
+ return;
+ }
+
+ var paramMap = [];
+ var params = jasmine.HtmlReporter.parameters(doc);
+
+ for (var i = 0; i < params.length; i++) {
+ var p = params[i].split('=');
+ paramMap[decodeURIComponent(p[0])] = decodeURIComponent(p[1]);
+ }
+
+ specName = paramMap.spec;
+ })();
+
+ return specName;
+ }
+
+ function createReporterDom(version) {
+ dom.reporter = self.createDom('div', { id: 'HTMLReporter', className: 'jasmine_reporter' },
+ dom.banner = self.createDom('div', { className: 'banner' },
+ self.createDom('span', { className: 'title' }, "Jasmine "),
+ self.createDom('span', { className: 'version' }, version)),
+
+ dom.symbolSummary = self.createDom('ul', {className: 'symbolSummary'}),
+ dom.alert = self.createDom('div', {className: 'alert'},
+ self.createDom('span', { className: 'exceptions' },
+ self.createDom('label', { className: 'label', 'for': 'no_try_catch' }, 'No try/catch'),
+ self.createDom('input', { id: 'no_try_catch', type: 'checkbox' }))),
+ dom.results = self.createDom('div', {className: 'results'},
+ dom.summary = self.createDom('div', { className: 'summary' }),
+ dom.details = self.createDom('div', { id: 'details' }))
+ );
+ }
+
+ function noTryCatch() {
+ return window.location.search.match(/catch=false/);
+ }
+
+ function searchWithCatch() {
+ var params = jasmine.HtmlReporter.parameters(window.document);
+ var removed = false;
+ var i = 0;
+
+ while (!removed && i < params.length) {
+ if (params[i].match(/catch=/)) {
+ params.splice(i, 1);
+ removed = true;
+ }
+ i++;
+ }
+ if (jasmine.CATCH_EXCEPTIONS) {
+ params.push("catch=false");
+ }
+
+ return params.join("&");
+ }
+
+ function setExceptionHandling() {
+ var chxCatch = document.getElementById('no_try_catch');
+
+ if (noTryCatch()) {
+ chxCatch.setAttribute('checked', true);
+ jasmine.CATCH_EXCEPTIONS = false;
+ }
+ chxCatch.onclick = function() {
+ window.location.search = searchWithCatch();
+ };
+ }
+};
+jasmine.HtmlReporter.parameters = function(doc) {
+ var paramStr = doc.location.search.substring(1);
+ var params = [];
+
+ if (paramStr.length > 0) {
+ params = paramStr.split('&');
+ }
+ return params;
+}
+jasmine.HtmlReporter.sectionLink = function(sectionName) {
+ var link = '?';
+ var params = [];
+
+ if (sectionName) {
+ params.push('spec=' + encodeURIComponent(sectionName));
+ }
+ if (!jasmine.CATCH_EXCEPTIONS) {
+ params.push("catch=false");
+ }
+ if (params.length > 0) {
+ link += params.join("&");
+ }
+
+ return link;
+};
+jasmine.HtmlReporterHelpers.addHelpers(jasmine.HtmlReporter);
+jasmine.HtmlReporter.ReporterView = function(dom) {
+ this.startedAt = new Date();
+ this.runningSpecCount = 0;
+ this.completeSpecCount = 0;
+ this.passedCount = 0;
+ this.failedCount = 0;
+ this.skippedCount = 0;
+
+ this.createResultsMenu = function() {
+ this.resultsMenu = this.createDom('span', {className: 'resultsMenu bar'},
+ this.summaryMenuItem = this.createDom('a', {className: 'summaryMenuItem', href: "#"}, '0 specs'),
+ ' | ',
+ this.detailsMenuItem = this.createDom('a', {className: 'detailsMenuItem', href: "#"}, '0 failing'));
+
+ this.summaryMenuItem.onclick = function() {
+ dom.reporter.className = dom.reporter.className.replace(/ showDetails/g, '');
+ };
+
+ this.detailsMenuItem.onclick = function() {
+ showDetails();
+ };
+ };
+
+ this.addSpecs = function(specs, specFilter) {
+ this.totalSpecCount = specs.length;
+
+ this.views = {
+ specs: {},
+ suites: {}
+ };
+
+ for (var i = 0; i < specs.length; i++) {
+ var spec = specs[i];
+ this.views.specs[spec.id] = new jasmine.HtmlReporter.SpecView(spec, dom, this.views);
+ if (specFilter(spec)) {
+ this.runningSpecCount++;
+ }
+ }
+ };
+
+ this.specComplete = function(spec) {
+ this.completeSpecCount++;
+
+ if (isUndefined(this.views.specs[spec.id])) {
+ this.views.specs[spec.id] = new jasmine.HtmlReporter.SpecView(spec, dom);
+ }
+
+ var specView = this.views.specs[spec.id];
+
+ switch (specView.status()) {
+ case 'passed':
+ this.passedCount++;
+ break;
+
+ case 'failed':
+ this.failedCount++;
+ break;
+
+ case 'skipped':
+ this.skippedCount++;
+ break;
+ }
+
+ specView.refresh();
+ this.refresh();
+ };
+
+ this.suiteComplete = function(suite) {
+ var suiteView = this.views.suites[suite.id];
+ if (isUndefined(suiteView)) {
+ return;
+ }
+ suiteView.refresh();
+ };
+
+ this.refresh = function() {
+
+ if (isUndefined(this.resultsMenu)) {
+ this.createResultsMenu();
+ }
+
+ // currently running UI
+ if (isUndefined(this.runningAlert)) {
+ this.runningAlert = this.createDom('a', { href: jasmine.HtmlReporter.sectionLink(), className: "runningAlert bar" });
+ dom.alert.appendChild(this.runningAlert);
+ }
+ this.runningAlert.innerHTML = "Running " + this.completeSpecCount + " of " + specPluralizedFor(this.totalSpecCount);
+
+ // skipped specs UI
+ if (isUndefined(this.skippedAlert)) {
+ this.skippedAlert = this.createDom('a', { href: jasmine.HtmlReporter.sectionLink(), className: "skippedAlert bar" });
+ }
+
+ this.skippedAlert.innerHTML = "Skipping " + this.skippedCount + " of " + specPluralizedFor(this.totalSpecCount) + " - run all";
+
+ if (this.skippedCount === 1 && isDefined(dom.alert)) {
+ dom.alert.appendChild(this.skippedAlert);
+ }
+
+ // passing specs UI
+ if (isUndefined(this.passedAlert)) {
+ this.passedAlert = this.createDom('span', { href: jasmine.HtmlReporter.sectionLink(), className: "passingAlert bar" });
+ }
+ this.passedAlert.innerHTML = "Passing " + specPluralizedFor(this.passedCount);
+
+ // failing specs UI
+ if (isUndefined(this.failedAlert)) {
+ this.failedAlert = this.createDom('span', {href: "?", className: "failingAlert bar"});
+ }
+ this.failedAlert.innerHTML = "Failing " + specPluralizedFor(this.failedCount);
+
+ if (this.failedCount === 1 && isDefined(dom.alert)) {
+ dom.alert.appendChild(this.failedAlert);
+ dom.alert.appendChild(this.resultsMenu);
+ }
+
+ // summary info
+ this.summaryMenuItem.innerHTML = "" + specPluralizedFor(this.runningSpecCount);
+ this.detailsMenuItem.innerHTML = "" + this.failedCount + " failing";
+ };
+
+ this.complete = function() {
+ dom.alert.removeChild(this.runningAlert);
+
+ this.skippedAlert.innerHTML = "Ran " + this.runningSpecCount + " of " + specPluralizedFor(this.totalSpecCount) + " - run all";
+
+ if (this.failedCount === 0) {
+ dom.alert.appendChild(this.createDom('span', {className: 'passingAlert bar'}, "Passing " + specPluralizedFor(this.passedCount)));
+ } else {
+ showDetails();
+ }
+
+ dom.banner.appendChild(this.createDom('span', {className: 'duration'}, "finished in " + ((new Date().getTime() - this.startedAt.getTime()) / 1000) + "s"));
+ };
+
+ return this;
+
+ function showDetails() {
+ if (dom.reporter.className.search(/showDetails/) === -1) {
+ dom.reporter.className += " showDetails";
+ }
+ }
+
+ function isUndefined(obj) {
+ return typeof obj === 'undefined';
+ }
+
+ function isDefined(obj) {
+ return !isUndefined(obj);
+ }
+
+ function specPluralizedFor(count) {
+ var str = count + " spec";
+ if (count > 1) {
+ str += "s"
+ }
+ return str;
+ }
+
+};
+
+jasmine.HtmlReporterHelpers.addHelpers(jasmine.HtmlReporter.ReporterView);
+
+
+jasmine.HtmlReporter.SpecView = function(spec, dom, views) {
+ this.spec = spec;
+ this.dom = dom;
+ this.views = views;
+
+ this.symbol = this.createDom('li', { className: 'pending' });
+ this.dom.symbolSummary.appendChild(this.symbol);
+
+ this.summary = this.createDom('div', { className: 'specSummary' },
+ this.createDom('a', {
+ className: 'description',
+ href: jasmine.HtmlReporter.sectionLink(this.spec.getVersion()),
+ title: this.spec.getVersion()
+ }, this.spec.description)
+ );
+
+ this.detail = this.createDom('div', { className: 'specDetail' },
+ this.createDom('a', {
+ className: 'description',
+ href: '?spec=' + encodeURIComponent(this.spec.getVersion()),
+ title: this.spec.getVersion()
+ }, this.spec.getVersion())
+ );
+};
+
+jasmine.HtmlReporter.SpecView.prototype.status = function() {
+ return this.getSpecStatus(this.spec);
+};
+
+jasmine.HtmlReporter.SpecView.prototype.refresh = function() {
+ this.symbol.className = this.status();
+
+ switch (this.status()) {
+ case 'skipped':
+ break;
+
+ case 'passed':
+ this.appendSummaryToSuiteDiv();
+ break;
+
+ case 'failed':
+ this.appendSummaryToSuiteDiv();
+ this.appendFailureDetail();
+ break;
+ }
+};
+
+jasmine.HtmlReporter.SpecView.prototype.appendSummaryToSuiteDiv = function() {
+ this.summary.className += ' ' + this.status();
+ this.appendToSummary(this.spec, this.summary);
+};
+
+jasmine.HtmlReporter.SpecView.prototype.appendFailureDetail = function() {
+ this.detail.className += ' ' + this.status();
+
+ var resultItems = this.spec.results().getItems();
+ var messagesDiv = this.createDom('div', { className: 'messages' });
+
+ for (var i = 0; i < resultItems.length; i++) {
+ var result = resultItems[i];
+
+ if (result.type == 'log') {
+ messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage log'}, result.toString()));
+ } else if (result.type == 'expect' && result.passed && !result.passed()) {
+ messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage fail'}, result.message));
+
+ if (result.trace.stack) {
+ messagesDiv.appendChild(this.createDom('div', {className: 'stackTrace'}, result.trace.stack));
+ }
+ }
+ }
+
+ if (messagesDiv.childNodes.length > 0) {
+ this.detail.appendChild(messagesDiv);
+ this.dom.details.appendChild(this.detail);
+ }
+};
+
+jasmine.HtmlReporterHelpers.addHelpers(jasmine.HtmlReporter.SpecView);jasmine.HtmlReporter.SuiteView = function(suite, dom, views) {
+ this.suite = suite;
+ this.dom = dom;
+ this.views = views;
+
+ this.element = this.createDom('div', { className: 'suite' },
+ this.createDom('a', { className: 'description', href: jasmine.HtmlReporter.sectionLink(this.suite.getVersion()) }, this.suite.description)
+ );
+
+ this.appendToSummary(this.suite, this.element);
+};
+
+jasmine.HtmlReporter.SuiteView.prototype.status = function() {
+ return this.getSpecStatus(this.suite);
+};
+
+jasmine.HtmlReporter.SuiteView.prototype.refresh = function() {
+ this.element.className += " " + this.status();
+};
+
+jasmine.HtmlReporterHelpers.addHelpers(jasmine.HtmlReporter.SuiteView);
+
+/* @deprecated Use jasmine.HtmlReporter instead
+ */
+jasmine.TrivialReporter = function(doc) {
+ this.document = doc || document;
+ this.suiteDivs = {};
+ this.logRunningSpecs = false;
+};
+
+jasmine.TrivialReporter.prototype.createDom = function(type, attrs, childrenVarArgs) {
+ var el = document.createElement(type);
+
+ for (var i = 2; i < arguments.length; i++) {
+ var child = arguments[i];
+
+ if (typeof child === 'string') {
+ el.appendChild(document.createTextNode(child));
+ } else {
+ if (child) { el.appendChild(child); }
+ }
+ }
+
+ for (var attr in attrs) {
+ if (attr == "className") {
+ el[attr] = attrs[attr];
+ } else {
+ el.setAttribute(attr, attrs[attr]);
+ }
+ }
+
+ return el;
+};
+
+jasmine.TrivialReporter.prototype.reportRunnerStarting = function(runner) {
+ var showPassed, showSkipped;
+
+ this.outerDiv = this.createDom('div', { id: 'TrivialReporter', className: 'jasmine_reporter' },
+ this.createDom('div', { className: 'banner' },
+ this.createDom('div', { className: 'logo' },
+ this.createDom('span', { className: 'title' }, "Jasmine"),
+ this.createDom('span', { className: 'version' }, runner.env.versionString())),
+ this.createDom('div', { className: 'options' },
+ "Show ",
+ showPassed = this.createDom('input', { id: "__jasmine_TrivialReporter_showPassed__", type: 'checkbox' }),
+ this.createDom('label', { "for": "__jasmine_TrivialReporter_showPassed__" }, " passed "),
+ showSkipped = this.createDom('input', { id: "__jasmine_TrivialReporter_showSkipped__", type: 'checkbox' }),
+ this.createDom('label', { "for": "__jasmine_TrivialReporter_showSkipped__" }, " skipped")
+ )
+ ),
+
+ this.runnerDiv = this.createDom('div', { className: 'runner running' },
+ this.createDom('a', { className: 'run_spec', href: '?' }, "run all"),
+ this.runnerMessageSpan = this.createDom('span', {}, "Running..."),
+ this.finishedAtSpan = this.createDom('span', { className: 'finished-at' }, ""))
+ );
+
+ this.document.body.appendChild(this.outerDiv);
+
+ var suites = runner.suites();
+ for (var i = 0; i < suites.length; i++) {
+ var suite = suites[i];
+ var suiteDiv = this.createDom('div', { className: 'suite' },
+ this.createDom('a', { className: 'run_spec', href: '?spec=' + encodeURIComponent(suite.getVersion()) }, "run"),
+ this.createDom('a', { className: 'description', href: '?spec=' + encodeURIComponent(suite.getVersion()) }, suite.description));
+ this.suiteDivs[suite.id] = suiteDiv;
+ var parentDiv = this.outerDiv;
+ if (suite.parentSuite) {
+ parentDiv = this.suiteDivs[suite.parentSuite.id];
+ }
+ parentDiv.appendChild(suiteDiv);
+ }
+
+ this.startedAt = new Date();
+
+ var self = this;
+ showPassed.onclick = function(evt) {
+ if (showPassed.checked) {
+ self.outerDiv.className += ' show-passed';
+ } else {
+ self.outerDiv.className = self.outerDiv.className.replace(/ show-passed/, '');
+ }
+ };
+
+ showSkipped.onclick = function(evt) {
+ if (showSkipped.checked) {
+ self.outerDiv.className += ' show-skipped';
+ } else {
+ self.outerDiv.className = self.outerDiv.className.replace(/ show-skipped/, '');
+ }
+ };
+};
+
+jasmine.TrivialReporter.prototype.reportRunnerResults = function(runner) {
+ var results = runner.results();
+ var className = (results.failedCount > 0) ? "runner failed" : "runner passed";
+ this.runnerDiv.setAttribute("class", className);
+ //do it twice for IE
+ this.runnerDiv.setAttribute("className", className);
+ var specs = runner.specs();
+ var specCount = 0;
+ for (var i = 0; i < specs.length; i++) {
+ if (this.specFilter(specs[i])) {
+ specCount++;
+ }
+ }
+ var message = "" + specCount + " spec" + (specCount == 1 ? "" : "s" ) + ", " + results.failedCount + " failure" + ((results.failedCount == 1) ? "" : "s");
+ message += " in " + ((new Date().getTime() - this.startedAt.getTime()) / 1000) + "s";
+ this.runnerMessageSpan.replaceChild(this.createDom('a', { className: 'description', href: '?'}, message), this.runnerMessageSpan.firstChild);
+
+ this.finishedAtSpan.appendChild(document.createTextNode("Finished at " + new Date().toString()));
+};
+
+jasmine.TrivialReporter.prototype.reportSuiteResults = function(suite) {
+ var results = suite.results();
+ var status = results.passed() ? 'passed' : 'failed';
+ if (results.totalCount === 0) { // todo: change this to check results.skipped
+ status = 'skipped';
+ }
+ this.suiteDivs[suite.id].className += " " + status;
+};
+
+jasmine.TrivialReporter.prototype.reportSpecStarting = function(spec) {
+ if (this.logRunningSpecs) {
+ this.log('>> Jasmine Running ' + spec.suite.description + ' ' + spec.description + '...');
+ }
+};
+
+jasmine.TrivialReporter.prototype.reportSpecResults = function(spec) {
+ var results = spec.results();
+ var status = results.passed() ? 'passed' : 'failed';
+ if (results.skipped) {
+ status = 'skipped';
+ }
+ var specDiv = this.createDom('div', { className: 'spec ' + status },
+ this.createDom('a', { className: 'run_spec', href: '?spec=' + encodeURIComponent(spec.getVersion()) }, "run"),
+ this.createDom('a', {
+ className: 'description',
+ href: '?spec=' + encodeURIComponent(spec.getVersion()),
+ title: spec.getVersion()
+ }, spec.description));
+
+
+ var resultItems = results.getItems();
+ var messagesDiv = this.createDom('div', { className: 'messages' });
+ for (var i = 0; i < resultItems.length; i++) {
+ var result = resultItems[i];
+
+ if (result.type == 'log') {
+ messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage log'}, result.toString()));
+ } else if (result.type == 'expect' && result.passed && !result.passed()) {
+ messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage fail'}, result.message));
+
+ if (result.trace.stack) {
+ messagesDiv.appendChild(this.createDom('div', {className: 'stackTrace'}, result.trace.stack));
+ }
+ }
+ }
+
+ if (messagesDiv.childNodes.length > 0) {
+ specDiv.appendChild(messagesDiv);
+ }
+
+ this.suiteDivs[spec.suite.id].appendChild(specDiv);
+};
+
+jasmine.TrivialReporter.prototype.log = function() {
+ var console = jasmine.getGlobal().console;
+ if (console && console.log) {
+ if (console.log.apply) {
+ console.log.apply(console, arguments);
+ } else {
+ console.log(arguments); // ie fix: console.log.apply doesn't exist on ie
+ }
+ }
+};
+
+jasmine.TrivialReporter.prototype.getLocation = function() {
+ return this.document.location;
+};
+
+jasmine.TrivialReporter.prototype.specFilter = function(spec) {
+ var paramMap = {};
+ var params = this.getLocation().search.substring(1).split('&');
+ for (var i = 0; i < params.length; i++) {
+ var p = params[i].split('=');
+ paramMap[decodeURIComponent(p[0])] = decodeURIComponent(p[1]);
+ }
+
+ if (!paramMap.spec) {
+ return true;
+ }
+ return spec.getVersion().indexOf(paramMap.spec) === 0;
+};
diff --git a/js/test/lib/jasmine-1.3.1/jasmine.css b/js/test/lib/jasmine-1.3.1/jasmine.css
new file mode 100644
index 00000000..8c008dc7
--- /dev/null
+++ b/js/test/lib/jasmine-1.3.1/jasmine.css
@@ -0,0 +1,82 @@
+body { background-color: #eeeeee; padding: 0; margin: 5px; overflow-y: scroll; }
+
+#HTMLReporter { font-size: 11px; font-family: Monaco, "Lucida Console", monospace; line-height: 14px; color: #333333; }
+#HTMLReporter a { text-decoration: none; }
+#HTMLReporter a:hover { text-decoration: underline; }
+#HTMLReporter p, #HTMLReporter h1, #HTMLReporter h2, #HTMLReporter h3, #HTMLReporter h4, #HTMLReporter h5, #HTMLReporter h6 { margin: 0; line-height: 14px; }
+#HTMLReporter .banner, #HTMLReporter .symbolSummary, #HTMLReporter .summary, #HTMLReporter .resultMessage, #HTMLReporter .specDetail .description, #HTMLReporter .alert .bar, #HTMLReporter .stackTrace { padding-left: 9px; padding-right: 9px; }
+#HTMLReporter #jasmine_content { position: fixed; right: 100%; }
+#HTMLReporter .version { color: #aaaaaa; }
+#HTMLReporter .banner { margin-top: 14px; }
+#HTMLReporter .duration { color: #aaaaaa; float: right; }
+#HTMLReporter .symbolSummary { overflow: hidden; *zoom: 1; margin: 14px 0; }
+#HTMLReporter .symbolSummary li { display: block; float: left; height: 7px; width: 14px; margin-bottom: 7px; font-size: 16px; }
+#HTMLReporter .symbolSummary li.passed { font-size: 14px; }
+#HTMLReporter .symbolSummary li.passed:before { color: #5e7d00; content: "\02022"; }
+#HTMLReporter .symbolSummary li.failed { line-height: 9px; }
+#HTMLReporter .symbolSummary li.failed:before { color: #b03911; content: "x"; font-weight: bold; margin-left: -1px; }
+#HTMLReporter .symbolSummary li.skipped { font-size: 14px; }
+#HTMLReporter .symbolSummary li.skipped:before { color: #bababa; content: "\02022"; }
+#HTMLReporter .symbolSummary li.pending { line-height: 11px; }
+#HTMLReporter .symbolSummary li.pending:before { color: #aaaaaa; content: "-"; }
+#HTMLReporter .exceptions { color: #fff; float: right; margin-top: 5px; margin-right: 5px; }
+#HTMLReporter .bar { line-height: 28px; font-size: 14px; display: block; color: #eee; }
+#HTMLReporter .runningAlert { background-color: #666666; }
+#HTMLReporter .skippedAlert { background-color: #aaaaaa; }
+#HTMLReporter .skippedAlert:first-child { background-color: #333333; }
+#HTMLReporter .skippedAlert:hover { text-decoration: none; color: white; text-decoration: underline; }
+#HTMLReporter .passingAlert { background-color: #a6b779; }
+#HTMLReporter .passingAlert:first-child { background-color: #5e7d00; }
+#HTMLReporter .failingAlert { background-color: #cf867e; }
+#HTMLReporter .failingAlert:first-child { background-color: #b03911; }
+#HTMLReporter .results { margin-top: 14px; }
+#HTMLReporter #details { display: none; }
+#HTMLReporter .resultsMenu, #HTMLReporter .resultsMenu a { background-color: #fff; color: #333333; }
+#HTMLReporter.showDetails .summaryMenuItem { font-weight: normal; text-decoration: inherit; }
+#HTMLReporter.showDetails .summaryMenuItem:hover { text-decoration: underline; }
+#HTMLReporter.showDetails .detailsMenuItem { font-weight: bold; text-decoration: underline; }
+#HTMLReporter.showDetails .summary { display: none; }
+#HTMLReporter.showDetails #details { display: block; }
+#HTMLReporter .summaryMenuItem { font-weight: bold; text-decoration: underline; }
+#HTMLReporter .summary { margin-top: 14px; }
+#HTMLReporter .summary .suite .suite, #HTMLReporter .summary .specSummary { margin-left: 14px; }
+#HTMLReporter .summary .specSummary.passed a { color: #5e7d00; }
+#HTMLReporter .summary .specSummary.failed a { color: #b03911; }
+#HTMLReporter .description + .suite { margin-top: 0; }
+#HTMLReporter .suite { margin-top: 14px; }
+#HTMLReporter .suite a { color: #333333; }
+#HTMLReporter #details .specDetail { margin-bottom: 28px; }
+#HTMLReporter #details .specDetail .description { display: block; color: white; background-color: #b03911; }
+#HTMLReporter .resultMessage { padding-top: 14px; color: #333333; }
+#HTMLReporter .resultMessage span.result { display: block; }
+#HTMLReporter .stackTrace { margin: 5px 0 0 0; max-height: 224px; overflow: auto; line-height: 18px; color: #666666; border: 1px solid #ddd; background: white; white-space: pre; }
+
+#TrivialReporter { padding: 8px 13px; position: absolute; top: 0; bottom: 0; left: 0; right: 0; overflow-y: scroll; background-color: white; font-family: "Helvetica Neue Light", "Lucida Grande", "Calibri", "Arial", sans-serif; /*.resultMessage {*/ /*white-space: pre;*/ /*}*/ }
+#TrivialReporter a:visited, #TrivialReporter a { color: #303; }
+#TrivialReporter a:hover, #TrivialReporter a:active { color: blue; }
+#TrivialReporter .run_spec { float: right; padding-right: 5px; font-size: .8em; text-decoration: none; }
+#TrivialReporter .banner { color: #303; background-color: #fef; padding: 5px; }
+#TrivialReporter .logo { float: left; font-size: 1.1em; padding-left: 5px; }
+#TrivialReporter .logo .version { font-size: .6em; padding-left: 1em; }
+#TrivialReporter .runner.running { background-color: yellow; }
+#TrivialReporter .options { text-align: right; font-size: .8em; }
+#TrivialReporter .suite { border: 1px outset gray; margin: 5px 0; padding-left: 1em; }
+#TrivialReporter .suite .suite { margin: 5px; }
+#TrivialReporter .suite.passed { background-color: #dfd; }
+#TrivialReporter .suite.failed { background-color: #fdd; }
+#TrivialReporter .spec { margin: 5px; padding-left: 1em; clear: both; }
+#TrivialReporter .spec.failed, #TrivialReporter .spec.passed, #TrivialReporter .spec.skipped { padding-bottom: 5px; border: 1px solid gray; }
+#TrivialReporter .spec.failed { background-color: #fbb; border-color: red; }
+#TrivialReporter .spec.passed { background-color: #bfb; border-color: green; }
+#TrivialReporter .spec.skipped { background-color: #bbb; }
+#TrivialReporter .messages { border-left: 1px dashed gray; padding-left: 1em; padding-right: 1em; }
+#TrivialReporter .passed { background-color: #cfc; display: none; }
+#TrivialReporter .failed { background-color: #fbb; }
+#TrivialReporter .skipped { color: #777; background-color: #eee; display: none; }
+#TrivialReporter .resultMessage span.result { display: block; line-height: 2em; color: black; }
+#TrivialReporter .resultMessage .mismatch { color: black; }
+#TrivialReporter .stackTrace { white-space: pre; font-size: .8em; margin-left: 10px; max-height: 5em; overflow: auto; border: 1px inset red; padding: 1em; background: #eef; }
+#TrivialReporter .finished-at { padding-left: 1em; font-size: .6em; }
+#TrivialReporter.show-passed .passed, #TrivialReporter.show-skipped .skipped { display: block; }
+#TrivialReporter #jasmine_content { position: fixed; right: 100%; }
+#TrivialReporter .runner { border: 1px solid gray; display: block; margin: 5px 0; padding: 2px 0 2px 10px; }
diff --git a/js/test/lib/jasmine-1.3.1/jasmine.js b/js/test/lib/jasmine-1.3.1/jasmine.js
new file mode 100644
index 00000000..eaf7d426
--- /dev/null
+++ b/js/test/lib/jasmine-1.3.1/jasmine.js
@@ -0,0 +1,2600 @@
+var isCommonJS = typeof window == "undefined" && typeof exports == "object";
+
+/**
+ * Top level namespace for Jasmine, a lightweight JavaScript BDD/spec/testing framework.
+ *
+ * @namespace
+ */
+var jasmine = {};
+if (isCommonJS) exports.jasmine = jasmine;
+/**
+ * @private
+ */
+jasmine.unimplementedMethod_ = function() {
+ throw new Error("unimplemented method");
+};
+
+/**
+ * Use
jasmine.undefined instead of
undefined, since
undefined is just
+ * a plain old variable and may be redefined by somebody else.
+ *
+ * @private
+ */
+jasmine.undefined = jasmine.___undefined___;
+
+/**
+ * Show diagnostic messages in the console if set to true
+ *
+ */
+jasmine.VERBOSE = false;
+
+/**
+ * Default interval in milliseconds for event loop yields (e.g. to allow network activity or to refresh the screen with the HTML-based runner). Small values here may result in slow test running. Zero means no updates until all tests have completed.
+ *
+ */
+jasmine.DEFAULT_UPDATE_INTERVAL = 250;
+
+/**
+ * Maximum levels of nesting that will be included when an object is pretty-printed
+ */
+jasmine.MAX_PRETTY_PRINT_DEPTH = 40;
+
+/**
+ * Default timeout interval in milliseconds for waitsFor() blocks.
+ */
+jasmine.DEFAULT_TIMEOUT_INTERVAL = 5000;
+
+/**
+ * By default exceptions thrown in the context of a test are caught by jasmine so that it can run the remaining tests in the suite.
+ * Set to false to let the exception bubble up in the browser.
+ *
+ */
+jasmine.CATCH_EXCEPTIONS = true;
+
+jasmine.getGlobal = function() {
+ function getGlobal() {
+ return this;
+ }
+
+ return getGlobal();
+};
+
+/**
+ * Allows for bound functions to be compared. Internal use only.
+ *
+ * @ignore
+ * @private
+ * @param base {Object} bound 'this' for the function
+ * @param name {Function} function to find
+ */
+jasmine.bindOriginal_ = function(base, name) {
+ var original = base[name];
+ if (original.apply) {
+ return function() {
+ return original.apply(base, arguments);
+ };
+ } else {
+ // IE support
+ return jasmine.getGlobal()[name];
+ }
+};
+
+jasmine.setTimeout = jasmine.bindOriginal_(jasmine.getGlobal(), 'setTimeout');
+jasmine.clearTimeout = jasmine.bindOriginal_(jasmine.getGlobal(), 'clearTimeout');
+jasmine.setInterval = jasmine.bindOriginal_(jasmine.getGlobal(), 'setInterval');
+jasmine.clearInterval = jasmine.bindOriginal_(jasmine.getGlobal(), 'clearInterval');
+
+jasmine.MessageResult = function(values) {
+ this.type = 'log';
+ this.values = values;
+ this.trace = new Error(); // todo: test better
+};
+
+jasmine.MessageResult.prototype.toString = function() {
+ var text = "";
+ for (var i = 0; i < this.values.length; i++) {
+ if (i > 0) text += " ";
+ if (jasmine.isString_(this.values[i])) {
+ text += this.values[i];
+ } else {
+ text += jasmine.pp(this.values[i]);
+ }
+ }
+ return text;
+};
+
+jasmine.ExpectationResult = function(params) {
+ this.type = 'expect';
+ this.matcherName = params.matcherName;
+ this.passed_ = params.passed;
+ this.expected = params.expected;
+ this.actual = params.actual;
+ this.message = this.passed_ ? 'Passed.' : params.message;
+
+ var trace = (params.trace || new Error(this.message));
+ this.trace = this.passed_ ? '' : trace;
+};
+
+jasmine.ExpectationResult.prototype.toString = function () {
+ return this.message;
+};
+
+jasmine.ExpectationResult.prototype.passed = function () {
+ return this.passed_;
+};
+
+/**
+ * Getter for the Jasmine environment. Ensures one gets created
+ */
+jasmine.getEnv = function() {
+ var env = jasmine.currentEnv_ = jasmine.currentEnv_ || new jasmine.Env();
+ return env;
+};
+
+/**
+ * @ignore
+ * @private
+ * @param value
+ * @returns {Boolean}
+ */
+jasmine.isArray_ = function(value) {
+ return jasmine.isA_("Array", value);
+};
+
+/**
+ * @ignore
+ * @private
+ * @param value
+ * @returns {Boolean}
+ */
+jasmine.isString_ = function(value) {
+ return jasmine.isA_("String", value);
+};
+
+/**
+ * @ignore
+ * @private
+ * @param value
+ * @returns {Boolean}
+ */
+jasmine.isNumber_ = function(value) {
+ return jasmine.isA_("Number", value);
+};
+
+/**
+ * @ignore
+ * @private
+ * @param {String} typeName
+ * @param value
+ * @returns {Boolean}
+ */
+jasmine.isA_ = function(typeName, value) {
+ return Object.prototype.toString.apply(value) === '[object ' + typeName + ']';
+};
+
+/**
+ * Pretty printer for expecations. Takes any object and turns it into a human-readable string.
+ *
+ * @param value {Object} an object to be outputted
+ * @returns {String}
+ */
+jasmine.pp = function(value) {
+ var stringPrettyPrinter = new jasmine.StringPrettyPrinter();
+ stringPrettyPrinter.format(value);
+ return stringPrettyPrinter.string;
+};
+
+/**
+ * Returns true if the object is a DOM Node.
+ *
+ * @param {Object} obj object to check
+ * @returns {Boolean}
+ */
+jasmine.isDomNode = function(obj) {
+ return obj.nodeType > 0;
+};
+
+/**
+ * Returns a matchable 'generic' object of the class type. For use in expecations of type when values don't matter.
+ *
+ * @example
+ * // don't care about which function is passed in, as long as it's a function
+ * expect(mySpy).toHaveBeenCalledWith(jasmine.any(Function));
+ *
+ * @param {Class} clazz
+ * @returns matchable object of the type clazz
+ */
+jasmine.any = function(clazz) {
+ return new jasmine.Matchers.Any(clazz);
+};
+
+/**
+ * Returns a matchable subset of a JSON object. For use in expectations when you don't care about all of the
+ * attributes on the object.
+ *
+ * @example
+ * // don't care about any other attributes than foo.
+ * expect(mySpy).toHaveBeenCalledWith(jasmine.objectContaining({foo: "bar"});
+ *
+ * @param sample {Object} sample
+ * @returns matchable object for the sample
+ */
+jasmine.objectContaining = function (sample) {
+ return new jasmine.Matchers.ObjectContaining(sample);
+};
+
+/**
+ * Jasmine Spies are test doubles that can act as stubs, spies, fakes or when used in an expecation, mocks.
+ *
+ * Spies should be created in test setup, before expectations. They can then be checked, using the standard Jasmine
+ * expectation syntax. Spies can be checked if they were called or not and what the calling params were.
+ *
+ * A Spy has the following fields: wasCalled, callCount, mostRecentCall, and argsForCall (see docs).
+ *
+ * Spies are torn down at the end of every spec.
+ *
+ * Note: Do
not call new jasmine.Spy() directly - a spy must be created using spyOn, jasmine.createSpy or jasmine.createSpyObj.
+ *
+ * @example
+ * // a stub
+ * var myStub = jasmine.createSpy('myStub'); // can be used anywhere
+ *
+ * // spy example
+ * var foo = {
+ * not: function(bool) { return !bool; }
+ * }
+ *
+ * // actual foo.not will not be called, execution stops
+ * spyOn(foo, 'not');
+
+ // foo.not spied upon, execution will continue to implementation
+ * spyOn(foo, 'not').andCallThrough();
+ *
+ * // fake example
+ * var foo = {
+ * not: function(bool) { return !bool; }
+ * }
+ *
+ * // foo.not(val) will return val
+ * spyOn(foo, 'not').andCallFake(function(value) {return value;});
+ *
+ * // mock example
+ * foo.not(7 == 7);
+ * expect(foo.not).toHaveBeenCalled();
+ * expect(foo.not).toHaveBeenCalledWith(true);
+ *
+ * @constructor
+ * @see spyOn, jasmine.createSpy, jasmine.createSpyObj
+ * @param {String} name
+ */
+jasmine.Spy = function(name) {
+ /**
+ * The name of the spy, if provided.
+ */
+ this.identity = name || 'unknown';
+ /**
+ * Is this Object a spy?
+ */
+ this.isSpy = true;
+ /**
+ * The actual function this spy stubs.
+ */
+ this.plan = function() {
+ };
+ /**
+ * Tracking of the most recent call to the spy.
+ * @example
+ * var mySpy = jasmine.createSpy('foo');
+ * mySpy(1, 2);
+ * mySpy.mostRecentCall.args = [1, 2];
+ */
+ this.mostRecentCall = {};
+
+ /**
+ * Holds arguments for each call to the spy, indexed by call count
+ * @example
+ * var mySpy = jasmine.createSpy('foo');
+ * mySpy(1, 2);
+ * mySpy(7, 8);
+ * mySpy.mostRecentCall.args = [7, 8];
+ * mySpy.argsForCall[0] = [1, 2];
+ * mySpy.argsForCall[1] = [7, 8];
+ */
+ this.argsForCall = [];
+ this.calls = [];
+};
+
+/**
+ * Tells a spy to call through to the actual implemenatation.
+ *
+ * @example
+ * var foo = {
+ * bar: function() { // do some stuff }
+ * }
+ *
+ * // defining a spy on an existing property: foo.bar
+ * spyOn(foo, 'bar').andCallThrough();
+ */
+jasmine.Spy.prototype.andCallThrough = function() {
+ this.plan = this.originalValue;
+ return this;
+};
+
+/**
+ * For setting the return value of a spy.
+ *
+ * @example
+ * // defining a spy from scratch: foo() returns 'baz'
+ * var foo = jasmine.createSpy('spy on foo').andReturn('baz');
+ *
+ * // defining a spy on an existing property: foo.bar() returns 'baz'
+ * spyOn(foo, 'bar').andReturn('baz');
+ *
+ * @param {Object} value
+ */
+jasmine.Spy.prototype.andReturn = function(value) {
+ this.plan = function() {
+ return value;
+ };
+ return this;
+};
+
+/**
+ * For throwing an exception when a spy is called.
+ *
+ * @example
+ * // defining a spy from scratch: foo() throws an exception w/ message 'ouch'
+ * var foo = jasmine.createSpy('spy on foo').andThrow('baz');
+ *
+ * // defining a spy on an existing property: foo.bar() throws an exception w/ message 'ouch'
+ * spyOn(foo, 'bar').andThrow('baz');
+ *
+ * @param {String} exceptionMsg
+ */
+jasmine.Spy.prototype.andThrow = function(exceptionMsg) {
+ this.plan = function() {
+ throw exceptionMsg;
+ };
+ return this;
+};
+
+/**
+ * Calls an alternate implementation when a spy is called.
+ *
+ * @example
+ * var baz = function() {
+ * // do some stuff, return something
+ * }
+ * // defining a spy from scratch: foo() calls the function baz
+ * var foo = jasmine.createSpy('spy on foo').andCall(baz);
+ *
+ * // defining a spy on an existing property: foo.bar() calls an anonymnous function
+ * spyOn(foo, 'bar').andCall(function() { return 'baz';} );
+ *
+ * @param {Function} fakeFunc
+ */
+jasmine.Spy.prototype.andCallFake = function(fakeFunc) {
+ this.plan = fakeFunc;
+ return this;
+};
+
+/**
+ * Resets all of a spy's the tracking variables so that it can be used again.
+ *
+ * @example
+ * spyOn(foo, 'bar');
+ *
+ * foo.bar();
+ *
+ * expect(foo.bar.callCount).toEqual(1);
+ *
+ * foo.bar.reset();
+ *
+ * expect(foo.bar.callCount).toEqual(0);
+ */
+jasmine.Spy.prototype.reset = function() {
+ this.wasCalled = false;
+ this.callCount = 0;
+ this.argsForCall = [];
+ this.calls = [];
+ this.mostRecentCall = {};
+};
+
+jasmine.createSpy = function(name) {
+
+ var spyObj = function() {
+ spyObj.wasCalled = true;
+ spyObj.callCount++;
+ var args = jasmine.util.argsToArray(arguments);
+ spyObj.mostRecentCall.object = this;
+ spyObj.mostRecentCall.args = args;
+ spyObj.argsForCall.push(args);
+ spyObj.calls.push({object: this, args: args});
+ return spyObj.plan.apply(this, arguments);
+ };
+
+ var spy = new jasmine.Spy(name);
+
+ for (var prop in spy) {
+ spyObj[prop] = spy[prop];
+ }
+
+ spyObj.reset();
+
+ return spyObj;
+};
+
+/**
+ * Determines whether an object is a spy.
+ *
+ * @param {jasmine.Spy|Object} putativeSpy
+ * @returns {Boolean}
+ */
+jasmine.isSpy = function(putativeSpy) {
+ return putativeSpy && putativeSpy.isSpy;
+};
+
+/**
+ * Creates a more complicated spy: an Object that has every property a function that is a spy. Used for stubbing something
+ * large in one call.
+ *
+ * @param {String} baseName name of spy class
+ * @param {Array} methodNames array of names of methods to make spies
+ */
+jasmine.createSpyObj = function(baseName, methodNames) {
+ if (!jasmine.isArray_(methodNames) || methodNames.length === 0) {
+ throw new Error('createSpyObj requires a non-empty array of method names to create spies for');
+ }
+ var obj = {};
+ for (var i = 0; i < methodNames.length; i++) {
+ obj[methodNames[i]] = jasmine.createSpy(baseName + '.' + methodNames[i]);
+ }
+ return obj;
+};
+
+/**
+ * All parameters are pretty-printed and concatenated together, then written to the current spec's output.
+ *
+ * Be careful not to leave calls to
jasmine.log in production code.
+ */
+jasmine.log = function() {
+ var spec = jasmine.getEnv().currentSpec;
+ spec.log.apply(spec, arguments);
+};
+
+/**
+ * Function that installs a spy on an existing object's method name. Used within a Spec to create a spy.
+ *
+ * @example
+ * // spy example
+ * var foo = {
+ * not: function(bool) { return !bool; }
+ * }
+ * spyOn(foo, 'not'); // actual foo.not will not be called, execution stops
+ *
+ * @see jasmine.createSpy
+ * @param obj
+ * @param methodName
+ * @return {jasmine.Spy} a Jasmine spy that can be chained with all spy methods
+ */
+var spyOn = function(obj, methodName) {
+ return jasmine.getEnv().currentSpec.spyOn(obj, methodName);
+};
+if (isCommonJS) exports.spyOn = spyOn;
+
+/**
+ * Creates a Jasmine spec that will be added to the current suite.
+ *
+ * // TODO: pending tests
+ *
+ * @example
+ * it('should be true', function() {
+ * expect(true).toEqual(true);
+ * });
+ *
+ * @param {String} desc description of this specification
+ * @param {Function} func defines the preconditions and expectations of the spec
+ */
+var it = function(desc, func) {
+ return jasmine.getEnv().it(desc, func);
+};
+if (isCommonJS) exports.it = it;
+
+/**
+ * Creates a
disabled Jasmine spec.
+ *
+ * A convenience method that allows existing specs to be disabled temporarily during development.
+ *
+ * @param {String} desc description of this specification
+ * @param {Function} func defines the preconditions and expectations of the spec
+ */
+var xit = function(desc, func) {
+ return jasmine.getEnv().xit(desc, func);
+};
+if (isCommonJS) exports.xit = xit;
+
+/**
+ * Starts a chain for a Jasmine expectation.
+ *
+ * It is passed an Object that is the actual value and should chain to one of the many
+ * jasmine.Matchers functions.
+ *
+ * @param {Object} actual Actual value to test against and expected value
+ * @return {jasmine.Matchers}
+ */
+var expect = function(actual) {
+ return jasmine.getEnv().currentSpec.expect(actual);
+};
+if (isCommonJS) exports.expect = expect;
+
+/**
+ * Defines part of a jasmine spec. Used in cominbination with waits or waitsFor in asynchrnous specs.
+ *
+ * @param {Function} func Function that defines part of a jasmine spec.
+ */
+var runs = function(func) {
+ jasmine.getEnv().currentSpec.runs(func);
+};
+if (isCommonJS) exports.runs = runs;
+
+/**
+ * Waits a fixed time period before moving to the next block.
+ *
+ * @deprecated Use waitsFor() instead
+ * @param {Number} timeout milliseconds to wait
+ */
+var waits = function(timeout) {
+ jasmine.getEnv().currentSpec.waits(timeout);
+};
+if (isCommonJS) exports.waits = waits;
+
+/**
+ * Waits for the latchFunction to return true before proceeding to the next block.
+ *
+ * @param {Function} latchFunction
+ * @param {String} optional_timeoutMessage
+ * @param {Number} optional_timeout
+ */
+var waitsFor = function(latchFunction, optional_timeoutMessage, optional_timeout) {
+ jasmine.getEnv().currentSpec.waitsFor.apply(jasmine.getEnv().currentSpec, arguments);
+};
+if (isCommonJS) exports.waitsFor = waitsFor;
+
+/**
+ * A function that is called before each spec in a suite.
+ *
+ * Used for spec setup, including validating assumptions.
+ *
+ * @param {Function} beforeEachFunction
+ */
+var beforeEach = function(beforeEachFunction) {
+ jasmine.getEnv().beforeEach(beforeEachFunction);
+};
+if (isCommonJS) exports.beforeEach = beforeEach;
+
+/**
+ * A function that is called after each spec in a suite.
+ *
+ * Used for restoring any state that is hijacked during spec execution.
+ *
+ * @param {Function} afterEachFunction
+ */
+var afterEach = function(afterEachFunction) {
+ jasmine.getEnv().afterEach(afterEachFunction);
+};
+if (isCommonJS) exports.afterEach = afterEach;
+
+/**
+ * Defines a suite of specifications.
+ *
+ * Stores the description and all defined specs in the Jasmine environment as one suite of specs. Variables declared
+ * are accessible by calls to beforeEach, it, and afterEach. Describe blocks can be nested, allowing for specialization
+ * of setup in some tests.
+ *
+ * @example
+ * // TODO: a simple suite
+ *
+ * // TODO: a simple suite with a nested describe block
+ *
+ * @param {String} description A string, usually the class under test.
+ * @param {Function} specDefinitions function that defines several specs.
+ */
+var describe = function(description, specDefinitions) {
+ return jasmine.getEnv().describe(description, specDefinitions);
+};
+if (isCommonJS) exports.describe = describe;
+
+/**
+ * Disables a suite of specifications. Used to disable some suites in a file, or files, temporarily during development.
+ *
+ * @param {String} description A string, usually the class under test.
+ * @param {Function} specDefinitions function that defines several specs.
+ */
+var xdescribe = function(description, specDefinitions) {
+ return jasmine.getEnv().xdescribe(description, specDefinitions);
+};
+if (isCommonJS) exports.xdescribe = xdescribe;
+
+
+// Provide the XMLHttpRequest class for IE 5.x-6.x:
+jasmine.XmlHttpRequest = (typeof XMLHttpRequest == "undefined") ? function() {
+ function tryIt(f) {
+ try {
+ return f();
+ } catch(e) {
+ }
+ return null;
+ }
+
+ var xhr = tryIt(function() {
+ return new ActiveXObject("Msxml2.XMLHTTP.6.0");
+ }) ||
+ tryIt(function() {
+ return new ActiveXObject("Msxml2.XMLHTTP.3.0");
+ }) ||
+ tryIt(function() {
+ return new ActiveXObject("Msxml2.XMLHTTP");
+ }) ||
+ tryIt(function() {
+ return new ActiveXObject("Microsoft.XMLHTTP");
+ });
+
+ if (!xhr) throw new Error("This browser does not support XMLHttpRequest.");
+
+ return xhr;
+} : XMLHttpRequest;
+/**
+ * @namespace
+ */
+jasmine.util = {};
+
+/**
+ * Declare that a child class inherit it's prototype from the parent class.
+ *
+ * @private
+ * @param {Function} childClass
+ * @param {Function} parentClass
+ */
+jasmine.util.inherit = function(childClass, parentClass) {
+ /**
+ * @private
+ */
+ var subclass = function() {
+ };
+ subclass.prototype = parentClass.prototype;
+ childClass.prototype = new subclass();
+};
+
+jasmine.util.formatException = function(e) {
+ var lineNumber;
+ if (e.line) {
+ lineNumber = e.line;
+ }
+ else if (e.lineNumber) {
+ lineNumber = e.lineNumber;
+ }
+
+ var file;
+
+ if (e.sourceURL) {
+ file = e.sourceURL;
+ }
+ else if (e.fileName) {
+ file = e.fileName;
+ }
+
+ var message = (e.name && e.message) ? (e.name + ': ' + e.message) : e.toString();
+
+ if (file && lineNumber) {
+ message += ' in ' + file + ' (line ' + lineNumber + ')';
+ }
+
+ return message;
+};
+
+jasmine.util.htmlEscape = function(str) {
+ if (!str) return str;
+ return str.replace(/&/g, '&')
+ .replace(//g, '>');
+};
+
+jasmine.util.argsToArray = function(args) {
+ var arrayOfArgs = [];
+ for (var i = 0; i < args.length; i++) arrayOfArgs.push(args[i]);
+ return arrayOfArgs;
+};
+
+jasmine.util.extend = function(destination, source) {
+ for (var property in source) destination[property] = source[property];
+ return destination;
+};
+
+/**
+ * Environment for Jasmine
+ *
+ * @constructor
+ */
+jasmine.Env = function() {
+ this.currentSpec = null;
+ this.currentSuite = null;
+ this.currentRunner_ = new jasmine.Runner(this);
+
+ this.reporter = new jasmine.MultiReporter();
+
+ this.updateInterval = jasmine.DEFAULT_UPDATE_INTERVAL;
+ this.defaultTimeoutInterval = jasmine.DEFAULT_TIMEOUT_INTERVAL;
+ this.lastUpdate = 0;
+ this.specFilter = function() {
+ return true;
+ };
+
+ this.nextSpecId_ = 0;
+ this.nextSuiteId_ = 0;
+ this.equalityTesters_ = [];
+
+ // wrap matchers
+ this.matchersClass = function() {
+ jasmine.Matchers.apply(this, arguments);
+ };
+ jasmine.util.inherit(this.matchersClass, jasmine.Matchers);
+
+ jasmine.Matchers.wrapInto_(jasmine.Matchers.prototype, this.matchersClass);
+};
+
+
+jasmine.Env.prototype.setTimeout = jasmine.setTimeout;
+jasmine.Env.prototype.clearTimeout = jasmine.clearTimeout;
+jasmine.Env.prototype.setInterval = jasmine.setInterval;
+jasmine.Env.prototype.clearInterval = jasmine.clearInterval;
+
+/**
+ * @returns an object containing jasmine version build info, if set.
+ */
+jasmine.Env.prototype.version = function () {
+ if (jasmine.version_) {
+ return jasmine.version_;
+ } else {
+ throw new Error('Version not set');
+ }
+};
+
+/**
+ * @returns string containing jasmine version build info, if set.
+ */
+jasmine.Env.prototype.versionString = function() {
+ if (!jasmine.version_) {
+ return "version unknown";
+ }
+
+ var version = this.version();
+ var versionString = version.major + "." + version.minor + "." + version.build;
+ if (version.release_candidate) {
+ versionString += ".rc" + version.release_candidate;
+ }
+ versionString += " revision " + version.revision;
+ return versionString;
+};
+
+/**
+ * @returns a sequential integer starting at 0
+ */
+jasmine.Env.prototype.nextSpecId = function () {
+ return this.nextSpecId_++;
+};
+
+/**
+ * @returns a sequential integer starting at 0
+ */
+jasmine.Env.prototype.nextSuiteId = function () {
+ return this.nextSuiteId_++;
+};
+
+/**
+ * Register a reporter to receive status updates from Jasmine.
+ * @param {jasmine.Reporter} reporter An object which will receive status updates.
+ */
+jasmine.Env.prototype.addReporter = function(reporter) {
+ this.reporter.addReporter(reporter);
+};
+
+jasmine.Env.prototype.execute = function() {
+ this.currentRunner_.execute();
+};
+
+jasmine.Env.prototype.describe = function(description, specDefinitions) {
+ var suite = new jasmine.Suite(this, description, specDefinitions, this.currentSuite);
+
+ var parentSuite = this.currentSuite;
+ if (parentSuite) {
+ parentSuite.add(suite);
+ } else {
+ this.currentRunner_.add(suite);
+ }
+
+ this.currentSuite = suite;
+
+ var declarationError = null;
+ try {
+ specDefinitions.call(suite);
+ } catch(e) {
+ declarationError = e;
+ }
+
+ if (declarationError) {
+ this.it("encountered a declaration exception", function() {
+ throw declarationError;
+ });
+ }
+
+ this.currentSuite = parentSuite;
+
+ return suite;
+};
+
+jasmine.Env.prototype.beforeEach = function(beforeEachFunction) {
+ if (this.currentSuite) {
+ this.currentSuite.beforeEach(beforeEachFunction);
+ } else {
+ this.currentRunner_.beforeEach(beforeEachFunction);
+ }
+};
+
+jasmine.Env.prototype.currentRunner = function () {
+ return this.currentRunner_;
+};
+
+jasmine.Env.prototype.afterEach = function(afterEachFunction) {
+ if (this.currentSuite) {
+ this.currentSuite.afterEach(afterEachFunction);
+ } else {
+ this.currentRunner_.afterEach(afterEachFunction);
+ }
+
+};
+
+jasmine.Env.prototype.xdescribe = function(desc, specDefinitions) {
+ return {
+ execute: function() {
+ }
+ };
+};
+
+jasmine.Env.prototype.it = function(description, func) {
+ var spec = new jasmine.Spec(this, this.currentSuite, description);
+ this.currentSuite.add(spec);
+ this.currentSpec = spec;
+
+ if (func) {
+ spec.runs(func);
+ }
+
+ return spec;
+};
+
+jasmine.Env.prototype.xit = function(desc, func) {
+ return {
+ id: this.nextSpecId(),
+ runs: function() {
+ }
+ };
+};
+
+jasmine.Env.prototype.compareRegExps_ = function(a, b, mismatchKeys, mismatchValues) {
+ if (a.source != b.source)
+ mismatchValues.push("expected pattern /" + b.source + "/ is not equal to the pattern /" + a.source + "/");
+
+ if (a.ignoreCase != b.ignoreCase)
+ mismatchValues.push("expected modifier i was" + (b.ignoreCase ? " " : " not ") + "set and does not equal the origin modifier");
+
+ if (a.global != b.global)
+ mismatchValues.push("expected modifier g was" + (b.global ? " " : " not ") + "set and does not equal the origin modifier");
+
+ if (a.multiline != b.multiline)
+ mismatchValues.push("expected modifier m was" + (b.multiline ? " " : " not ") + "set and does not equal the origin modifier");
+
+ if (a.sticky != b.sticky)
+ mismatchValues.push("expected modifier y was" + (b.sticky ? " " : " not ") + "set and does not equal the origin modifier");
+
+ return (mismatchValues.length === 0);
+};
+
+jasmine.Env.prototype.compareObjects_ = function(a, b, mismatchKeys, mismatchValues) {
+ if (a.__Jasmine_been_here_before__ === b && b.__Jasmine_been_here_before__ === a) {
+ return true;
+ }
+
+ a.__Jasmine_been_here_before__ = b;
+ b.__Jasmine_been_here_before__ = a;
+
+ var hasKey = function(obj, keyName) {
+ return obj !== null && obj[keyName] !== jasmine.undefined;
+ };
+
+ for (var property in b) {
+ if (!hasKey(a, property) && hasKey(b, property)) {
+ mismatchKeys.push("expected has key '" + property + "', but missing from actual.");
+ }
+ }
+ for (property in a) {
+ if (!hasKey(b, property) && hasKey(a, property)) {
+ mismatchKeys.push("expected missing key '" + property + "', but present in actual.");
+ }
+ }
+ for (property in b) {
+ if (property == '__Jasmine_been_here_before__') continue;
+ if (!this.equals_(a[property], b[property], mismatchKeys, mismatchValues)) {
+ mismatchValues.push("'" + property + "' was '" + (b[property] ? jasmine.util.htmlEscape(b[property].toString()) : b[property]) + "' in expected, but was '" + (a[property] ? jasmine.util.htmlEscape(a[property].toString()) : a[property]) + "' in actual.");
+ }
+ }
+
+ if (jasmine.isArray_(a) && jasmine.isArray_(b) && a.length != b.length) {
+ mismatchValues.push("arrays were not the same length");
+ }
+
+ delete a.__Jasmine_been_here_before__;
+ delete b.__Jasmine_been_here_before__;
+ return (mismatchKeys.length === 0 && mismatchValues.length === 0);
+};
+
+jasmine.Env.prototype.equals_ = function(a, b, mismatchKeys, mismatchValues) {
+ mismatchKeys = mismatchKeys || [];
+ mismatchValues = mismatchValues || [];
+
+ for (var i = 0; i < this.equalityTesters_.length; i++) {
+ var equalityTester = this.equalityTesters_[i];
+ var result = equalityTester(a, b, this, mismatchKeys, mismatchValues);
+ if (result !== jasmine.undefined) return result;
+ }
+
+ if (a === b) return true;
+
+ if (a === jasmine.undefined || a === null || b === jasmine.undefined || b === null) {
+ return (a == jasmine.undefined && b == jasmine.undefined);
+ }
+
+ if (jasmine.isDomNode(a) && jasmine.isDomNode(b)) {
+ return a === b;
+ }
+
+ if (a instanceof Date && b instanceof Date) {
+ return a.getTime() == b.getTime();
+ }
+
+ if (a.jasmineMatches) {
+ return a.jasmineMatches(b);
+ }
+
+ if (b.jasmineMatches) {
+ return b.jasmineMatches(a);
+ }
+
+ if (a instanceof jasmine.Matchers.ObjectContaining) {
+ return a.matches(b);
+ }
+
+ if (b instanceof jasmine.Matchers.ObjectContaining) {
+ return b.matches(a);
+ }
+
+ if (jasmine.isString_(a) && jasmine.isString_(b)) {
+ return (a == b);
+ }
+
+ if (jasmine.isNumber_(a) && jasmine.isNumber_(b)) {
+ return (a == b);
+ }
+
+ if (a instanceof RegExp && b instanceof RegExp) {
+ return this.compareRegExps_(a, b, mismatchKeys, mismatchValues);
+ }
+
+ if (typeof a === "object" && typeof b === "object") {
+ return this.compareObjects_(a, b, mismatchKeys, mismatchValues);
+ }
+
+ //Straight check
+ return (a === b);
+};
+
+jasmine.Env.prototype.contains_ = function(haystack, needle) {
+ if (jasmine.isArray_(haystack)) {
+ for (var i = 0; i < haystack.length; i++) {
+ if (this.equals_(haystack[i], needle)) return true;
+ }
+ return false;
+ }
+ return haystack.indexOf(needle) >= 0;
+};
+
+jasmine.Env.prototype.addEqualityTester = function(equalityTester) {
+ this.equalityTesters_.push(equalityTester);
+};
+/** No-op base class for Jasmine reporters.
+ *
+ * @constructor
+ */
+jasmine.Reporter = function() {
+};
+
+//noinspection JSUnusedLocalSymbols
+jasmine.Reporter.prototype.reportRunnerStarting = function(runner) {
+};
+
+//noinspection JSUnusedLocalSymbols
+jasmine.Reporter.prototype.reportRunnerResults = function(runner) {
+};
+
+//noinspection JSUnusedLocalSymbols
+jasmine.Reporter.prototype.reportSuiteResults = function(suite) {
+};
+
+//noinspection JSUnusedLocalSymbols
+jasmine.Reporter.prototype.reportSpecStarting = function(spec) {
+};
+
+//noinspection JSUnusedLocalSymbols
+jasmine.Reporter.prototype.reportSpecResults = function(spec) {
+};
+
+//noinspection JSUnusedLocalSymbols
+jasmine.Reporter.prototype.log = function(str) {
+};
+
+/**
+ * Blocks are functions with executable code that make up a spec.
+ *
+ * @constructor
+ * @param {jasmine.Env} env
+ * @param {Function} func
+ * @param {jasmine.Spec} spec
+ */
+jasmine.Block = function(env, func, spec) {
+ this.env = env;
+ this.func = func;
+ this.spec = spec;
+};
+
+jasmine.Block.prototype.execute = function(onComplete) {
+ if (!jasmine.CATCH_EXCEPTIONS) {
+ this.func.apply(this.spec);
+ }
+ else {
+ try {
+ this.func.apply(this.spec);
+ } catch (e) {
+ this.spec.fail(e);
+ }
+ }
+ onComplete();
+};
+/** JavaScript API reporter.
+ *
+ * @constructor
+ */
+jasmine.JsApiReporter = function() {
+ this.started = false;
+ this.finished = false;
+ this.suites_ = [];
+ this.results_ = {};
+};
+
+jasmine.JsApiReporter.prototype.reportRunnerStarting = function(runner) {
+ this.started = true;
+ var suites = runner.topLevelSuites();
+ for (var i = 0; i < suites.length; i++) {
+ var suite = suites[i];
+ this.suites_.push(this.summarize_(suite));
+ }
+};
+
+jasmine.JsApiReporter.prototype.suites = function() {
+ return this.suites_;
+};
+
+jasmine.JsApiReporter.prototype.summarize_ = function(suiteOrSpec) {
+ var isSuite = suiteOrSpec instanceof jasmine.Suite;
+ var summary = {
+ id: suiteOrSpec.id,
+ name: suiteOrSpec.description,
+ type: isSuite ? 'suite' : 'spec',
+ children: []
+ };
+
+ if (isSuite) {
+ var children = suiteOrSpec.children();
+ for (var i = 0; i < children.length; i++) {
+ summary.children.push(this.summarize_(children[i]));
+ }
+ }
+ return summary;
+};
+
+jasmine.JsApiReporter.prototype.results = function() {
+ return this.results_;
+};
+
+jasmine.JsApiReporter.prototype.resultsForSpec = function(specId) {
+ return this.results_[specId];
+};
+
+//noinspection JSUnusedLocalSymbols
+jasmine.JsApiReporter.prototype.reportRunnerResults = function(runner) {
+ this.finished = true;
+};
+
+//noinspection JSUnusedLocalSymbols
+jasmine.JsApiReporter.prototype.reportSuiteResults = function(suite) {
+};
+
+//noinspection JSUnusedLocalSymbols
+jasmine.JsApiReporter.prototype.reportSpecResults = function(spec) {
+ this.results_[spec.id] = {
+ messages: spec.results().getItems(),
+ result: spec.results().failedCount > 0 ? "failed" : "passed"
+ };
+};
+
+//noinspection JSUnusedLocalSymbols
+jasmine.JsApiReporter.prototype.log = function(str) {
+};
+
+jasmine.JsApiReporter.prototype.resultsForSpecs = function(specIds){
+ var results = {};
+ for (var i = 0; i < specIds.length; i++) {
+ var specId = specIds[i];
+ results[specId] = this.summarizeResult_(this.results_[specId]);
+ }
+ return results;
+};
+
+jasmine.JsApiReporter.prototype.summarizeResult_ = function(result){
+ var summaryMessages = [];
+ var messagesLength = result.messages.length;
+ for (var messageIndex = 0; messageIndex < messagesLength; messageIndex++) {
+ var resultMessage = result.messages[messageIndex];
+ summaryMessages.push({
+ text: resultMessage.type == 'log' ? resultMessage.toString() : jasmine.undefined,
+ passed: resultMessage.passed ? resultMessage.passed() : true,
+ type: resultMessage.type,
+ message: resultMessage.message,
+ trace: {
+ stack: resultMessage.passed && !resultMessage.passed() ? resultMessage.trace.stack : jasmine.undefined
+ }
+ });
+ }
+
+ return {
+ result : result.result,
+ messages : summaryMessages
+ };
+};
+
+/**
+ * @constructor
+ * @param {jasmine.Env} env
+ * @param actual
+ * @param {jasmine.Spec} spec
+ */
+jasmine.Matchers = function(env, actual, spec, opt_isNot) {
+ this.env = env;
+ this.actual = actual;
+ this.spec = spec;
+ this.isNot = opt_isNot || false;
+ this.reportWasCalled_ = false;
+};
+
+// todo: @deprecated as of Jasmine 0.11, remove soon [xw]
+jasmine.Matchers.pp = function(str) {
+ throw new Error("jasmine.Matchers.pp() is no longer supported, please use jasmine.pp() instead!");
+};
+
+// todo: @deprecated Deprecated as of Jasmine 0.10. Rewrite your custom matchers to return true or false. [xw]
+jasmine.Matchers.prototype.report = function(result, failing_message, details) {
+ throw new Error("As of jasmine 0.11, custom matchers must be implemented differently -- please see jasmine docs");
+};
+
+jasmine.Matchers.wrapInto_ = function(prototype, matchersClass) {
+ for (var methodName in prototype) {
+ if (methodName == 'report') continue;
+ var orig = prototype[methodName];
+ matchersClass.prototype[methodName] = jasmine.Matchers.matcherFn_(methodName, orig);
+ }
+};
+
+jasmine.Matchers.matcherFn_ = function(matcherName, matcherFunction) {
+ return function() {
+ var matcherArgs = jasmine.util.argsToArray(arguments);
+ var result = matcherFunction.apply(this, arguments);
+
+ if (this.isNot) {
+ result = !result;
+ }
+
+ if (this.reportWasCalled_) return result;
+
+ var message;
+ if (!result) {
+ if (this.message) {
+ message = this.message.apply(this, arguments);
+ if (jasmine.isArray_(message)) {
+ message = message[this.isNot ? 1 : 0];
+ }
+ } else {
+ var englishyPredicate = matcherName.replace(/[A-Z]/g, function(s) { return ' ' + s.toLowerCase(); });
+ message = "Expected " + jasmine.pp(this.actual) + (this.isNot ? " not " : " ") + englishyPredicate;
+ if (matcherArgs.length > 0) {
+ for (var i = 0; i < matcherArgs.length; i++) {
+ if (i > 0) message += ",";
+ message += " " + jasmine.pp(matcherArgs[i]);
+ }
+ }
+ message += ".";
+ }
+ }
+ var expectationResult = new jasmine.ExpectationResult({
+ matcherName: matcherName,
+ passed: result,
+ expected: matcherArgs.length > 1 ? matcherArgs : matcherArgs[0],
+ actual: this.actual,
+ message: message
+ });
+ this.spec.addMatcherResult(expectationResult);
+ return jasmine.undefined;
+ };
+};
+
+
+
+
+/**
+ * toBe: compares the actual to the expected using ===
+ * @param expected
+ */
+jasmine.Matchers.prototype.toBe = function(expected) {
+ return this.actual === expected;
+};
+
+/**
+ * toNotBe: compares the actual to the expected using !==
+ * @param expected
+ * @deprecated as of 1.0. Use not.toBe() instead.
+ */
+jasmine.Matchers.prototype.toNotBe = function(expected) {
+ return this.actual !== expected;
+};
+
+/**
+ * toEqual: compares the actual to the expected using common sense equality. Handles Objects, Arrays, etc.
+ *
+ * @param expected
+ */
+jasmine.Matchers.prototype.toEqual = function(expected) {
+ return this.env.equals_(this.actual, expected);
+};
+
+/**
+ * toNotEqual: compares the actual to the expected using the ! of jasmine.Matchers.toEqual
+ * @param expected
+ * @deprecated as of 1.0. Use not.toEqual() instead.
+ */
+jasmine.Matchers.prototype.toNotEqual = function(expected) {
+ return !this.env.equals_(this.actual, expected);
+};
+
+/**
+ * Matcher that compares the actual to the expected using a regular expression. Constructs a RegExp, so takes
+ * a pattern or a String.
+ *
+ * @param expected
+ */
+jasmine.Matchers.prototype.toMatch = function(expected) {
+ return new RegExp(expected).test(this.actual);
+};
+
+/**
+ * Matcher that compares the actual to the expected using the boolean inverse of jasmine.Matchers.toMatch
+ * @param expected
+ * @deprecated as of 1.0. Use not.toMatch() instead.
+ */
+jasmine.Matchers.prototype.toNotMatch = function(expected) {
+ return !(new RegExp(expected).test(this.actual));
+};
+
+/**
+ * Matcher that compares the actual to jasmine.undefined.
+ */
+jasmine.Matchers.prototype.toBeDefined = function() {
+ return (this.actual !== jasmine.undefined);
+};
+
+/**
+ * Matcher that compares the actual to jasmine.undefined.
+ */
+jasmine.Matchers.prototype.toBeUndefined = function() {
+ return (this.actual === jasmine.undefined);
+};
+
+/**
+ * Matcher that compares the actual to null.
+ */
+jasmine.Matchers.prototype.toBeNull = function() {
+ return (this.actual === null);
+};
+
+/**
+ * Matcher that compares the actual to NaN.
+ */
+jasmine.Matchers.prototype.toBeNaN = function() {
+ this.message = function() {
+ return [ "Expected " + jasmine.pp(this.actual) + " to be NaN." ];
+ };
+
+ return (this.actual !== this.actual);
+};
+
+/**
+ * Matcher that boolean not-nots the actual.
+ */
+jasmine.Matchers.prototype.toBeTruthy = function() {
+ return !!this.actual;
+};
+
+
+/**
+ * Matcher that boolean nots the actual.
+ */
+jasmine.Matchers.prototype.toBeFalsy = function() {
+ return !this.actual;
+};
+
+
+/**
+ * Matcher that checks to see if the actual, a Jasmine spy, was called.
+ */
+jasmine.Matchers.prototype.toHaveBeenCalled = function() {
+ if (arguments.length > 0) {
+ throw new Error('toHaveBeenCalled does not take arguments, use toHaveBeenCalledWith');
+ }
+
+ if (!jasmine.isSpy(this.actual)) {
+ throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.');
+ }
+
+ this.message = function() {
+ return [
+ "Expected spy " + this.actual.identity + " to have been called.",
+ "Expected spy " + this.actual.identity + " not to have been called."
+ ];
+ };
+
+ return this.actual.wasCalled;
+};
+
+/** @deprecated Use expect(xxx).toHaveBeenCalled() instead */
+jasmine.Matchers.prototype.wasCalled = jasmine.Matchers.prototype.toHaveBeenCalled;
+
+/**
+ * Matcher that checks to see if the actual, a Jasmine spy, was not called.
+ *
+ * @deprecated Use expect(xxx).not.toHaveBeenCalled() instead
+ */
+jasmine.Matchers.prototype.wasNotCalled = function() {
+ if (arguments.length > 0) {
+ throw new Error('wasNotCalled does not take arguments');
+ }
+
+ if (!jasmine.isSpy(this.actual)) {
+ throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.');
+ }
+
+ this.message = function() {
+ return [
+ "Expected spy " + this.actual.identity + " to not have been called.",
+ "Expected spy " + this.actual.identity + " to have been called."
+ ];
+ };
+
+ return !this.actual.wasCalled;
+};
+
+/**
+ * Matcher that checks to see if the actual, a Jasmine spy, was called with a set of parameters.
+ *
+ * @example
+ *
+ */
+jasmine.Matchers.prototype.toHaveBeenCalledWith = function() {
+ var expectedArgs = jasmine.util.argsToArray(arguments);
+ if (!jasmine.isSpy(this.actual)) {
+ throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.');
+ }
+ this.message = function() {
+ var invertedMessage = "Expected spy " + this.actual.identity + " not to have been called with " + jasmine.pp(expectedArgs) + " but it was.";
+ var positiveMessage = "";
+ if (this.actual.callCount === 0) {
+ positiveMessage = "Expected spy " + this.actual.identity + " to have been called with " + jasmine.pp(expectedArgs) + " but it was never called.";
+ } else {
+ positiveMessage = "Expected spy " + this.actual.identity + " to have been called with " + jasmine.pp(expectedArgs) + " but actual calls were " + jasmine.pp(this.actual.argsForCall).replace(/^\[ | \]$/g, '')
+ }
+ return [positiveMessage, invertedMessage];
+ };
+
+ return this.env.contains_(this.actual.argsForCall, expectedArgs);
+};
+
+/** @deprecated Use expect(xxx).toHaveBeenCalledWith() instead */
+jasmine.Matchers.prototype.wasCalledWith = jasmine.Matchers.prototype.toHaveBeenCalledWith;
+
+/** @deprecated Use expect(xxx).not.toHaveBeenCalledWith() instead */
+jasmine.Matchers.prototype.wasNotCalledWith = function() {
+ var expectedArgs = jasmine.util.argsToArray(arguments);
+ if (!jasmine.isSpy(this.actual)) {
+ throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.');
+ }
+
+ this.message = function() {
+ return [
+ "Expected spy not to have been called with " + jasmine.pp(expectedArgs) + " but it was",
+ "Expected spy to have been called with " + jasmine.pp(expectedArgs) + " but it was"
+ ];
+ };
+
+ return !this.env.contains_(this.actual.argsForCall, expectedArgs);
+};
+
+/**
+ * Matcher that checks that the expected item is an element in the actual Array.
+ *
+ * @param {Object} expected
+ */
+jasmine.Matchers.prototype.toContain = function(expected) {
+ return this.env.contains_(this.actual, expected);
+};
+
+/**
+ * Matcher that checks that the expected item is NOT an element in the actual Array.
+ *
+ * @param {Object} expected
+ * @deprecated as of 1.0. Use not.toContain() instead.
+ */
+jasmine.Matchers.prototype.toNotContain = function(expected) {
+ return !this.env.contains_(this.actual, expected);
+};
+
+jasmine.Matchers.prototype.toBeLessThan = function(expected) {
+ return this.actual < expected;
+};
+
+jasmine.Matchers.prototype.toBeGreaterThan = function(expected) {
+ return this.actual > expected;
+};
+
+/**
+ * Matcher that checks that the expected item is equal to the actual item
+ * up to a given level of decimal precision (default 2).
+ *
+ * @param {Number} expected
+ * @param {Number} precision, as number of decimal places
+ */
+jasmine.Matchers.prototype.toBeCloseTo = function(expected, precision) {
+ if (!(precision === 0)) {
+ precision = precision || 2;
+ }
+ return Math.abs(expected - this.actual) < (Math.pow(10, -precision) / 2);
+};
+
+/**
+ * Matcher that checks that the expected exception was thrown by the actual.
+ *
+ * @param {String} [expected]
+ */
+jasmine.Matchers.prototype.toThrow = function(expected) {
+ var result = false;
+ var exception;
+ if (typeof this.actual != 'function') {
+ throw new Error('Actual is not a function');
+ }
+ try {
+ this.actual();
+ } catch (e) {
+ exception = e;
+ }
+ if (exception) {
+ result = (expected === jasmine.undefined || this.env.equals_(exception.message || exception, expected.message || expected));
+ }
+
+ var not = this.isNot ? "not " : "";
+
+ this.message = function() {
+ if (exception && (expected === jasmine.undefined || !this.env.equals_(exception.message || exception, expected.message || expected))) {
+ return ["Expected function " + not + "to throw", expected ? expected.message || expected : "an exception", ", but it threw", exception.message || exception].join(' ');
+ } else {
+ return "Expected function to throw an exception.";
+ }
+ };
+
+ return result;
+};
+
+jasmine.Matchers.Any = function(expectedClass) {
+ this.expectedClass = expectedClass;
+};
+
+jasmine.Matchers.Any.prototype.jasmineMatches = function(other) {
+ if (this.expectedClass == String) {
+ return typeof other == 'string' || other instanceof String;
+ }
+
+ if (this.expectedClass == Number) {
+ return typeof other == 'number' || other instanceof Number;
+ }
+
+ if (this.expectedClass == Function) {
+ return typeof other == 'function' || other instanceof Function;
+ }
+
+ if (this.expectedClass == Object) {
+ return typeof other == 'object';
+ }
+
+ return other instanceof this.expectedClass;
+};
+
+jasmine.Matchers.Any.prototype.jasmineToString = function() {
+ return '
';
+};
+
+jasmine.Matchers.ObjectContaining = function (sample) {
+ this.sample = sample;
+};
+
+jasmine.Matchers.ObjectContaining.prototype.jasmineMatches = function(other, mismatchKeys, mismatchValues) {
+ mismatchKeys = mismatchKeys || [];
+ mismatchValues = mismatchValues || [];
+
+ var env = jasmine.getEnv();
+
+ var hasKey = function(obj, keyName) {
+ return obj != null && obj[keyName] !== jasmine.undefined;
+ };
+
+ for (var property in this.sample) {
+ if (!hasKey(other, property) && hasKey(this.sample, property)) {
+ mismatchKeys.push("expected has key '" + property + "', but missing from actual.");
+ }
+ else if (!env.equals_(this.sample[property], other[property], mismatchKeys, mismatchValues)) {
+ mismatchValues.push("'" + property + "' was '" + (other[property] ? jasmine.util.htmlEscape(other[property].toString()) : other[property]) + "' in expected, but was '" + (this.sample[property] ? jasmine.util.htmlEscape(this.sample[property].toString()) : this.sample[property]) + "' in actual.");
+ }
+ }
+
+ return (mismatchKeys.length === 0 && mismatchValues.length === 0);
+};
+
+jasmine.Matchers.ObjectContaining.prototype.jasmineToString = function () {
+ return "";
+};
+// Mock setTimeout, clearTimeout
+// Contributed by Pivotal Computer Systems, www.pivotalsf.com
+
+jasmine.FakeTimer = function() {
+ this.reset();
+
+ var self = this;
+ self.setTimeout = function(funcToCall, millis) {
+ self.timeoutsMade++;
+ self.scheduleFunction(self.timeoutsMade, funcToCall, millis, false);
+ return self.timeoutsMade;
+ };
+
+ self.setInterval = function(funcToCall, millis) {
+ self.timeoutsMade++;
+ self.scheduleFunction(self.timeoutsMade, funcToCall, millis, true);
+ return self.timeoutsMade;
+ };
+
+ self.clearTimeout = function(timeoutKey) {
+ self.scheduledFunctions[timeoutKey] = jasmine.undefined;
+ };
+
+ self.clearInterval = function(timeoutKey) {
+ self.scheduledFunctions[timeoutKey] = jasmine.undefined;
+ };
+
+};
+
+jasmine.FakeTimer.prototype.reset = function() {
+ this.timeoutsMade = 0;
+ this.scheduledFunctions = {};
+ this.nowMillis = 0;
+};
+
+jasmine.FakeTimer.prototype.tick = function(millis) {
+ var oldMillis = this.nowMillis;
+ var newMillis = oldMillis + millis;
+ this.runFunctionsWithinRange(oldMillis, newMillis);
+ this.nowMillis = newMillis;
+};
+
+jasmine.FakeTimer.prototype.runFunctionsWithinRange = function(oldMillis, nowMillis) {
+ var scheduledFunc;
+ var funcsToRun = [];
+ for (var timeoutKey in this.scheduledFunctions) {
+ scheduledFunc = this.scheduledFunctions[timeoutKey];
+ if (scheduledFunc != jasmine.undefined &&
+ scheduledFunc.runAtMillis >= oldMillis &&
+ scheduledFunc.runAtMillis <= nowMillis) {
+ funcsToRun.push(scheduledFunc);
+ this.scheduledFunctions[timeoutKey] = jasmine.undefined;
+ }
+ }
+
+ if (funcsToRun.length > 0) {
+ funcsToRun.sort(function(a, b) {
+ return a.runAtMillis - b.runAtMillis;
+ });
+ for (var i = 0; i < funcsToRun.length; ++i) {
+ try {
+ var funcToRun = funcsToRun[i];
+ this.nowMillis = funcToRun.runAtMillis;
+ funcToRun.funcToCall();
+ if (funcToRun.recurring) {
+ this.scheduleFunction(funcToRun.timeoutKey,
+ funcToRun.funcToCall,
+ funcToRun.millis,
+ true);
+ }
+ } catch(e) {
+ }
+ }
+ this.runFunctionsWithinRange(oldMillis, nowMillis);
+ }
+};
+
+jasmine.FakeTimer.prototype.scheduleFunction = function(timeoutKey, funcToCall, millis, recurring) {
+ this.scheduledFunctions[timeoutKey] = {
+ runAtMillis: this.nowMillis + millis,
+ funcToCall: funcToCall,
+ recurring: recurring,
+ timeoutKey: timeoutKey,
+ millis: millis
+ };
+};
+
+/**
+ * @namespace
+ */
+jasmine.Clock = {
+ defaultFakeTimer: new jasmine.FakeTimer(),
+
+ reset: function() {
+ jasmine.Clock.assertInstalled();
+ jasmine.Clock.defaultFakeTimer.reset();
+ },
+
+ tick: function(millis) {
+ jasmine.Clock.assertInstalled();
+ jasmine.Clock.defaultFakeTimer.tick(millis);
+ },
+
+ runFunctionsWithinRange: function(oldMillis, nowMillis) {
+ jasmine.Clock.defaultFakeTimer.runFunctionsWithinRange(oldMillis, nowMillis);
+ },
+
+ scheduleFunction: function(timeoutKey, funcToCall, millis, recurring) {
+ jasmine.Clock.defaultFakeTimer.scheduleFunction(timeoutKey, funcToCall, millis, recurring);
+ },
+
+ useMock: function() {
+ if (!jasmine.Clock.isInstalled()) {
+ var spec = jasmine.getEnv().currentSpec;
+ spec.after(jasmine.Clock.uninstallMock);
+
+ jasmine.Clock.installMock();
+ }
+ },
+
+ installMock: function() {
+ jasmine.Clock.installed = jasmine.Clock.defaultFakeTimer;
+ },
+
+ uninstallMock: function() {
+ jasmine.Clock.assertInstalled();
+ jasmine.Clock.installed = jasmine.Clock.real;
+ },
+
+ real: {
+ setTimeout: jasmine.getGlobal().setTimeout,
+ clearTimeout: jasmine.getGlobal().clearTimeout,
+ setInterval: jasmine.getGlobal().setInterval,
+ clearInterval: jasmine.getGlobal().clearInterval
+ },
+
+ assertInstalled: function() {
+ if (!jasmine.Clock.isInstalled()) {
+ throw new Error("Mock clock is not installed, use jasmine.Clock.useMock()");
+ }
+ },
+
+ isInstalled: function() {
+ return jasmine.Clock.installed == jasmine.Clock.defaultFakeTimer;
+ },
+
+ installed: null
+};
+jasmine.Clock.installed = jasmine.Clock.real;
+
+//else for IE support
+jasmine.getGlobal().setTimeout = function(funcToCall, millis) {
+ if (jasmine.Clock.installed.setTimeout.apply) {
+ return jasmine.Clock.installed.setTimeout.apply(this, arguments);
+ } else {
+ return jasmine.Clock.installed.setTimeout(funcToCall, millis);
+ }
+};
+
+jasmine.getGlobal().setInterval = function(funcToCall, millis) {
+ if (jasmine.Clock.installed.setInterval.apply) {
+ return jasmine.Clock.installed.setInterval.apply(this, arguments);
+ } else {
+ return jasmine.Clock.installed.setInterval(funcToCall, millis);
+ }
+};
+
+jasmine.getGlobal().clearTimeout = function(timeoutKey) {
+ if (jasmine.Clock.installed.clearTimeout.apply) {
+ return jasmine.Clock.installed.clearTimeout.apply(this, arguments);
+ } else {
+ return jasmine.Clock.installed.clearTimeout(timeoutKey);
+ }
+};
+
+jasmine.getGlobal().clearInterval = function(timeoutKey) {
+ if (jasmine.Clock.installed.clearTimeout.apply) {
+ return jasmine.Clock.installed.clearInterval.apply(this, arguments);
+ } else {
+ return jasmine.Clock.installed.clearInterval(timeoutKey);
+ }
+};
+
+/**
+ * @constructor
+ */
+jasmine.MultiReporter = function() {
+ this.subReporters_ = [];
+};
+jasmine.util.inherit(jasmine.MultiReporter, jasmine.Reporter);
+
+jasmine.MultiReporter.prototype.addReporter = function(reporter) {
+ this.subReporters_.push(reporter);
+};
+
+(function() {
+ var functionNames = [
+ "reportRunnerStarting",
+ "reportRunnerResults",
+ "reportSuiteResults",
+ "reportSpecStarting",
+ "reportSpecResults",
+ "log"
+ ];
+ for (var i = 0; i < functionNames.length; i++) {
+ var functionName = functionNames[i];
+ jasmine.MultiReporter.prototype[functionName] = (function(functionName) {
+ return function() {
+ for (var j = 0; j < this.subReporters_.length; j++) {
+ var subReporter = this.subReporters_[j];
+ if (subReporter[functionName]) {
+ subReporter[functionName].apply(subReporter, arguments);
+ }
+ }
+ };
+ })(functionName);
+ }
+})();
+/**
+ * Holds results for a set of Jasmine spec. Allows for the results array to hold another jasmine.NestedResults
+ *
+ * @constructor
+ */
+jasmine.NestedResults = function() {
+ /**
+ * The total count of results
+ */
+ this.totalCount = 0;
+ /**
+ * Number of passed results
+ */
+ this.passedCount = 0;
+ /**
+ * Number of failed results
+ */
+ this.failedCount = 0;
+ /**
+ * Was this suite/spec skipped?
+ */
+ this.skipped = false;
+ /**
+ * @ignore
+ */
+ this.items_ = [];
+};
+
+/**
+ * Roll up the result counts.
+ *
+ * @param result
+ */
+jasmine.NestedResults.prototype.rollupCounts = function(result) {
+ this.totalCount += result.totalCount;
+ this.passedCount += result.passedCount;
+ this.failedCount += result.failedCount;
+};
+
+/**
+ * Adds a log message.
+ * @param values Array of message parts which will be concatenated later.
+ */
+jasmine.NestedResults.prototype.log = function(values) {
+ this.items_.push(new jasmine.MessageResult(values));
+};
+
+/**
+ * Getter for the results: message & results.
+ */
+jasmine.NestedResults.prototype.getItems = function() {
+ return this.items_;
+};
+
+/**
+ * Adds a result, tracking counts (total, passed, & failed)
+ * @param {jasmine.ExpectationResult|jasmine.NestedResults} result
+ */
+jasmine.NestedResults.prototype.addResult = function(result) {
+ if (result.type != 'log') {
+ if (result.items_) {
+ this.rollupCounts(result);
+ } else {
+ this.totalCount++;
+ if (result.passed()) {
+ this.passedCount++;
+ } else {
+ this.failedCount++;
+ }
+ }
+ }
+ this.items_.push(result);
+};
+
+/**
+ * @returns {Boolean} True if everything below passed
+ */
+jasmine.NestedResults.prototype.passed = function() {
+ return this.passedCount === this.totalCount;
+};
+/**
+ * Base class for pretty printing for expectation results.
+ */
+jasmine.PrettyPrinter = function() {
+ this.ppNestLevel_ = 0;
+};
+
+/**
+ * Formats a value in a nice, human-readable string.
+ *
+ * @param value
+ */
+jasmine.PrettyPrinter.prototype.format = function(value) {
+ this.ppNestLevel_++;
+ try {
+ if (value === jasmine.undefined) {
+ this.emitScalar('undefined');
+ } else if (value === null) {
+ this.emitScalar('null');
+ } else if (value === jasmine.getGlobal()) {
+ this.emitScalar('');
+ } else if (value.jasmineToString) {
+ this.emitScalar(value.jasmineToString());
+ } else if (typeof value === 'string') {
+ this.emitString(value);
+ } else if (jasmine.isSpy(value)) {
+ this.emitScalar("spy on " + value.identity);
+ } else if (value instanceof RegExp) {
+ this.emitScalar(value.toString());
+ } else if (typeof value === 'function') {
+ this.emitScalar('Function');
+ } else if (typeof value.nodeType === 'number') {
+ this.emitScalar('HTMLNode');
+ } else if (value instanceof Date) {
+ this.emitScalar('Date(' + value + ')');
+ } else if (value.__Jasmine_been_here_before__) {
+ this.emitScalar('');
+ } else if (jasmine.isArray_(value) || typeof value == 'object') {
+ value.__Jasmine_been_here_before__ = true;
+ if (jasmine.isArray_(value)) {
+ this.emitArray(value);
+ } else {
+ this.emitObject(value);
+ }
+ delete value.__Jasmine_been_here_before__;
+ } else {
+ this.emitScalar(value.toString());
+ }
+ } finally {
+ this.ppNestLevel_--;
+ }
+};
+
+jasmine.PrettyPrinter.prototype.iterateObject = function(obj, fn) {
+ for (var property in obj) {
+ if (!obj.hasOwnProperty(property)) continue;
+ if (property == '__Jasmine_been_here_before__') continue;
+ fn(property, obj.__lookupGetter__ ? (obj.__lookupGetter__(property) !== jasmine.undefined &&
+ obj.__lookupGetter__(property) !== null) : false);
+ }
+};
+
+jasmine.PrettyPrinter.prototype.emitArray = jasmine.unimplementedMethod_;
+jasmine.PrettyPrinter.prototype.emitObject = jasmine.unimplementedMethod_;
+jasmine.PrettyPrinter.prototype.emitScalar = jasmine.unimplementedMethod_;
+jasmine.PrettyPrinter.prototype.emitString = jasmine.unimplementedMethod_;
+
+jasmine.StringPrettyPrinter = function() {
+ jasmine.PrettyPrinter.call(this);
+
+ this.string = '';
+};
+jasmine.util.inherit(jasmine.StringPrettyPrinter, jasmine.PrettyPrinter);
+
+jasmine.StringPrettyPrinter.prototype.emitScalar = function(value) {
+ this.append(value);
+};
+
+jasmine.StringPrettyPrinter.prototype.emitString = function(value) {
+ this.append("'" + value + "'");
+};
+
+jasmine.StringPrettyPrinter.prototype.emitArray = function(array) {
+ if (this.ppNestLevel_ > jasmine.MAX_PRETTY_PRINT_DEPTH) {
+ this.append("Array");
+ return;
+ }
+
+ this.append('[ ');
+ for (var i = 0; i < array.length; i++) {
+ if (i > 0) {
+ this.append(', ');
+ }
+ this.format(array[i]);
+ }
+ this.append(' ]');
+};
+
+jasmine.StringPrettyPrinter.prototype.emitObject = function(obj) {
+ if (this.ppNestLevel_ > jasmine.MAX_PRETTY_PRINT_DEPTH) {
+ this.append("Object");
+ return;
+ }
+
+ var self = this;
+ this.append('{ ');
+ var first = true;
+
+ this.iterateObject(obj, function(property, isGetter) {
+ if (first) {
+ first = false;
+ } else {
+ self.append(', ');
+ }
+
+ self.append(property);
+ self.append(' : ');
+ if (isGetter) {
+ self.append('');
+ } else {
+ self.format(obj[property]);
+ }
+ });
+
+ this.append(' }');
+};
+
+jasmine.StringPrettyPrinter.prototype.append = function(value) {
+ this.string += value;
+};
+jasmine.Queue = function(env) {
+ this.env = env;
+
+ // parallel to blocks. each true value in this array means the block will
+ // get executed even if we abort
+ this.ensured = [];
+ this.blocks = [];
+ this.running = false;
+ this.index = 0;
+ this.offset = 0;
+ this.abort = false;
+};
+
+jasmine.Queue.prototype.addBefore = function(block, ensure) {
+ if (ensure === jasmine.undefined) {
+ ensure = false;
+ }
+
+ this.blocks.unshift(block);
+ this.ensured.unshift(ensure);
+};
+
+jasmine.Queue.prototype.add = function(block, ensure) {
+ if (ensure === jasmine.undefined) {
+ ensure = false;
+ }
+
+ this.blocks.push(block);
+ this.ensured.push(ensure);
+};
+
+jasmine.Queue.prototype.insertNext = function(block, ensure) {
+ if (ensure === jasmine.undefined) {
+ ensure = false;
+ }
+
+ this.ensured.splice((this.index + this.offset + 1), 0, ensure);
+ this.blocks.splice((this.index + this.offset + 1), 0, block);
+ this.offset++;
+};
+
+jasmine.Queue.prototype.start = function(onComplete) {
+ this.running = true;
+ this.onComplete = onComplete;
+ this.next_();
+};
+
+jasmine.Queue.prototype.isRunning = function() {
+ return this.running;
+};
+
+jasmine.Queue.LOOP_DONT_RECURSE = true;
+
+jasmine.Queue.prototype.next_ = function() {
+ var self = this;
+ var goAgain = true;
+
+ while (goAgain) {
+ goAgain = false;
+
+ if (self.index < self.blocks.length && !(this.abort && !this.ensured[self.index])) {
+ var calledSynchronously = true;
+ var completedSynchronously = false;
+
+ var onComplete = function () {
+ if (jasmine.Queue.LOOP_DONT_RECURSE && calledSynchronously) {
+ completedSynchronously = true;
+ return;
+ }
+
+ if (self.blocks[self.index].abort) {
+ self.abort = true;
+ }
+
+ self.offset = 0;
+ self.index++;
+
+ var now = new Date().getTime();
+ if (self.env.updateInterval && now - self.env.lastUpdate > self.env.updateInterval) {
+ self.env.lastUpdate = now;
+ self.env.setTimeout(function() {
+ self.next_();
+ }, 0);
+ } else {
+ if (jasmine.Queue.LOOP_DONT_RECURSE && completedSynchronously) {
+ goAgain = true;
+ } else {
+ self.next_();
+ }
+ }
+ };
+ self.blocks[self.index].execute(onComplete);
+
+ calledSynchronously = false;
+ if (completedSynchronously) {
+ onComplete();
+ }
+
+ } else {
+ self.running = false;
+ if (self.onComplete) {
+ self.onComplete();
+ }
+ }
+ }
+};
+
+jasmine.Queue.prototype.results = function() {
+ var results = new jasmine.NestedResults();
+ for (var i = 0; i < this.blocks.length; i++) {
+ if (this.blocks[i].results) {
+ results.addResult(this.blocks[i].results());
+ }
+ }
+ return results;
+};
+
+
+/**
+ * Runner
+ *
+ * @constructor
+ * @param {jasmine.Env} env
+ */
+jasmine.Runner = function(env) {
+ var self = this;
+ self.env = env;
+ self.queue = new jasmine.Queue(env);
+ self.before_ = [];
+ self.after_ = [];
+ self.suites_ = [];
+};
+
+jasmine.Runner.prototype.execute = function() {
+ var self = this;
+ if (self.env.reporter.reportRunnerStarting) {
+ self.env.reporter.reportRunnerStarting(this);
+ }
+ self.queue.start(function () {
+ self.finishCallback();
+ });
+};
+
+jasmine.Runner.prototype.beforeEach = function(beforeEachFunction) {
+ beforeEachFunction.typeName = 'beforeEach';
+ this.before_.splice(0,0,beforeEachFunction);
+};
+
+jasmine.Runner.prototype.afterEach = function(afterEachFunction) {
+ afterEachFunction.typeName = 'afterEach';
+ this.after_.splice(0,0,afterEachFunction);
+};
+
+
+jasmine.Runner.prototype.finishCallback = function() {
+ this.env.reporter.reportRunnerResults(this);
+};
+
+jasmine.Runner.prototype.addSuite = function(suite) {
+ this.suites_.push(suite);
+};
+
+jasmine.Runner.prototype.add = function(block) {
+ if (block instanceof jasmine.Suite) {
+ this.addSuite(block);
+ }
+ this.queue.add(block);
+};
+
+jasmine.Runner.prototype.specs = function () {
+ var suites = this.suites();
+ var specs = [];
+ for (var i = 0; i < suites.length; i++) {
+ specs = specs.concat(suites[i].specs());
+ }
+ return specs;
+};
+
+jasmine.Runner.prototype.suites = function() {
+ return this.suites_;
+};
+
+jasmine.Runner.prototype.topLevelSuites = function() {
+ var topLevelSuites = [];
+ for (var i = 0; i < this.suites_.length; i++) {
+ if (!this.suites_[i].parentSuite) {
+ topLevelSuites.push(this.suites_[i]);
+ }
+ }
+ return topLevelSuites;
+};
+
+jasmine.Runner.prototype.results = function() {
+ return this.queue.results();
+};
+/**
+ * Internal representation of a Jasmine specification, or test.
+ *
+ * @constructor
+ * @param {jasmine.Env} env
+ * @param {jasmine.Suite} suite
+ * @param {String} description
+ */
+jasmine.Spec = function(env, suite, description) {
+ if (!env) {
+ throw new Error('jasmine.Env() required');
+ }
+ if (!suite) {
+ throw new Error('jasmine.Suite() required');
+ }
+ var spec = this;
+ spec.id = env.nextSpecId ? env.nextSpecId() : null;
+ spec.env = env;
+ spec.suite = suite;
+ spec.description = description;
+ spec.queue = new jasmine.Queue(env);
+
+ spec.afterCallbacks = [];
+ spec.spies_ = [];
+
+ spec.results_ = new jasmine.NestedResults();
+ spec.results_.description = description;
+ spec.matchersClass = null;
+};
+
+jasmine.Spec.prototype.getVersion = function() {
+ return this.suite.getVersion() + ' ' + this.description + '.';
+};
+
+
+jasmine.Spec.prototype.results = function() {
+ return this.results_;
+};
+
+/**
+ * All parameters are pretty-printed and concatenated together, then written to the spec's output.
+ *
+ * Be careful not to leave calls to jasmine.log in production code.
+ */
+jasmine.Spec.prototype.log = function() {
+ return this.results_.log(arguments);
+};
+
+jasmine.Spec.prototype.runs = function (func) {
+ var block = new jasmine.Block(this.env, func, this);
+ this.addToQueue(block);
+ return this;
+};
+
+jasmine.Spec.prototype.addToQueue = function (block) {
+ if (this.queue.isRunning()) {
+ this.queue.insertNext(block);
+ } else {
+ this.queue.add(block);
+ }
+};
+
+/**
+ * @param {jasmine.ExpectationResult} result
+ */
+jasmine.Spec.prototype.addMatcherResult = function(result) {
+ this.results_.addResult(result);
+};
+
+jasmine.Spec.prototype.expect = function(actual) {
+ var positive = new (this.getMatchersClass_())(this.env, actual, this);
+ positive.not = new (this.getMatchersClass_())(this.env, actual, this, true);
+ return positive;
+};
+
+/**
+ * Waits a fixed time period before moving to the next block.
+ *
+ * @deprecated Use waitsFor() instead
+ * @param {Number} timeout milliseconds to wait
+ */
+jasmine.Spec.prototype.waits = function(timeout) {
+ var waitsFunc = new jasmine.WaitsBlock(this.env, timeout, this);
+ this.addToQueue(waitsFunc);
+ return this;
+};
+
+/**
+ * Waits for the latchFunction to return true before proceeding to the next block.
+ *
+ * @param {Function} latchFunction
+ * @param {String} optional_timeoutMessage
+ * @param {Number} optional_timeout
+ */
+jasmine.Spec.prototype.waitsFor = function(latchFunction, optional_timeoutMessage, optional_timeout) {
+ var latchFunction_ = null;
+ var optional_timeoutMessage_ = null;
+ var optional_timeout_ = null;
+
+ for (var i = 0; i < arguments.length; i++) {
+ var arg = arguments[i];
+ switch (typeof arg) {
+ case 'function':
+ latchFunction_ = arg;
+ break;
+ case 'string':
+ optional_timeoutMessage_ = arg;
+ break;
+ case 'number':
+ optional_timeout_ = arg;
+ break;
+ }
+ }
+
+ var waitsForFunc = new jasmine.WaitsForBlock(this.env, optional_timeout_, latchFunction_, optional_timeoutMessage_, this);
+ this.addToQueue(waitsForFunc);
+ return this;
+};
+
+jasmine.Spec.prototype.fail = function (e) {
+ var expectationResult = new jasmine.ExpectationResult({
+ passed: false,
+ message: e ? jasmine.util.formatException(e) : 'Exception',
+ trace: { stack: e.stack }
+ });
+ this.results_.addResult(expectationResult);
+};
+
+jasmine.Spec.prototype.getMatchersClass_ = function() {
+ return this.matchersClass || this.env.matchersClass;
+};
+
+jasmine.Spec.prototype.addMatchers = function(matchersPrototype) {
+ var parent = this.getMatchersClass_();
+ var newMatchersClass = function() {
+ parent.apply(this, arguments);
+ };
+ jasmine.util.inherit(newMatchersClass, parent);
+ jasmine.Matchers.wrapInto_(matchersPrototype, newMatchersClass);
+ this.matchersClass = newMatchersClass;
+};
+
+jasmine.Spec.prototype.finishCallback = function() {
+ this.env.reporter.reportSpecResults(this);
+};
+
+jasmine.Spec.prototype.finish = function(onComplete) {
+ this.removeAllSpies();
+ this.finishCallback();
+ if (onComplete) {
+ onComplete();
+ }
+};
+
+jasmine.Spec.prototype.after = function(doAfter) {
+ if (this.queue.isRunning()) {
+ this.queue.add(new jasmine.Block(this.env, doAfter, this), true);
+ } else {
+ this.afterCallbacks.unshift(doAfter);
+ }
+};
+
+jasmine.Spec.prototype.execute = function(onComplete) {
+ var spec = this;
+ if (!spec.env.specFilter(spec)) {
+ spec.results_.skipped = true;
+ spec.finish(onComplete);
+ return;
+ }
+
+ this.env.reporter.reportSpecStarting(this);
+
+ spec.env.currentSpec = spec;
+
+ spec.addBeforesAndAftersToQueue();
+
+ spec.queue.start(function () {
+ spec.finish(onComplete);
+ });
+};
+
+jasmine.Spec.prototype.addBeforesAndAftersToQueue = function() {
+ var runner = this.env.currentRunner();
+ var i;
+
+ for (var suite = this.suite; suite; suite = suite.parentSuite) {
+ for (i = 0; i < suite.before_.length; i++) {
+ this.queue.addBefore(new jasmine.Block(this.env, suite.before_[i], this));
+ }
+ }
+ for (i = 0; i < runner.before_.length; i++) {
+ this.queue.addBefore(new jasmine.Block(this.env, runner.before_[i], this));
+ }
+ for (i = 0; i < this.afterCallbacks.length; i++) {
+ this.queue.add(new jasmine.Block(this.env, this.afterCallbacks[i], this), true);
+ }
+ for (suite = this.suite; suite; suite = suite.parentSuite) {
+ for (i = 0; i < suite.after_.length; i++) {
+ this.queue.add(new jasmine.Block(this.env, suite.after_[i], this), true);
+ }
+ }
+ for (i = 0; i < runner.after_.length; i++) {
+ this.queue.add(new jasmine.Block(this.env, runner.after_[i], this), true);
+ }
+};
+
+jasmine.Spec.prototype.explodes = function() {
+ throw 'explodes function should not have been called';
+};
+
+jasmine.Spec.prototype.spyOn = function(obj, methodName, ignoreMethodDoesntExist) {
+ if (obj == jasmine.undefined) {
+ throw "spyOn could not find an object to spy upon for " + methodName + "()";
+ }
+
+ if (!ignoreMethodDoesntExist && obj[methodName] === jasmine.undefined) {
+ throw methodName + '() method does not exist';
+ }
+
+ if (!ignoreMethodDoesntExist && obj[methodName] && obj[methodName].isSpy) {
+ throw new Error(methodName + ' has already been spied upon');
+ }
+
+ var spyObj = jasmine.createSpy(methodName);
+
+ this.spies_.push(spyObj);
+ spyObj.baseObj = obj;
+ spyObj.methodName = methodName;
+ spyObj.originalValue = obj[methodName];
+
+ obj[methodName] = spyObj;
+
+ return spyObj;
+};
+
+jasmine.Spec.prototype.removeAllSpies = function() {
+ for (var i = 0; i < this.spies_.length; i++) {
+ var spy = this.spies_[i];
+ spy.baseObj[spy.methodName] = spy.originalValue;
+ }
+ this.spies_ = [];
+};
+
+/**
+ * Internal representation of a Jasmine suite.
+ *
+ * @constructor
+ * @param {jasmine.Env} env
+ * @param {String} description
+ * @param {Function} specDefinitions
+ * @param {jasmine.Suite} parentSuite
+ */
+jasmine.Suite = function(env, description, specDefinitions, parentSuite) {
+ var self = this;
+ self.id = env.nextSuiteId ? env.nextSuiteId() : null;
+ self.description = description;
+ self.queue = new jasmine.Queue(env);
+ self.parentSuite = parentSuite;
+ self.env = env;
+ self.before_ = [];
+ self.after_ = [];
+ self.children_ = [];
+ self.suites_ = [];
+ self.specs_ = [];
+};
+
+jasmine.Suite.prototype.getVersion = function() {
+ var version = this.description;
+ for (var parentSuite = this.parentSuite; parentSuite; parentSuite = parentSuite.parentSuite) {
+ version = parentSuite.description + ' ' + version;
+ }
+ return version;
+};
+
+jasmine.Suite.prototype.finish = function(onComplete) {
+ this.env.reporter.reportSuiteResults(this);
+ this.finished = true;
+ if (typeof(onComplete) == 'function') {
+ onComplete();
+ }
+};
+
+jasmine.Suite.prototype.beforeEach = function(beforeEachFunction) {
+ beforeEachFunction.typeName = 'beforeEach';
+ this.before_.unshift(beforeEachFunction);
+};
+
+jasmine.Suite.prototype.afterEach = function(afterEachFunction) {
+ afterEachFunction.typeName = 'afterEach';
+ this.after_.unshift(afterEachFunction);
+};
+
+jasmine.Suite.prototype.results = function() {
+ return this.queue.results();
+};
+
+jasmine.Suite.prototype.add = function(suiteOrSpec) {
+ this.children_.push(suiteOrSpec);
+ if (suiteOrSpec instanceof jasmine.Suite) {
+ this.suites_.push(suiteOrSpec);
+ this.env.currentRunner().addSuite(suiteOrSpec);
+ } else {
+ this.specs_.push(suiteOrSpec);
+ }
+ this.queue.add(suiteOrSpec);
+};
+
+jasmine.Suite.prototype.specs = function() {
+ return this.specs_;
+};
+
+jasmine.Suite.prototype.suites = function() {
+ return this.suites_;
+};
+
+jasmine.Suite.prototype.children = function() {
+ return this.children_;
+};
+
+jasmine.Suite.prototype.execute = function(onComplete) {
+ var self = this;
+ this.queue.start(function () {
+ self.finish(onComplete);
+ });
+};
+jasmine.WaitsBlock = function(env, timeout, spec) {
+ this.timeout = timeout;
+ jasmine.Block.call(this, env, null, spec);
+};
+
+jasmine.util.inherit(jasmine.WaitsBlock, jasmine.Block);
+
+jasmine.WaitsBlock.prototype.execute = function (onComplete) {
+ if (jasmine.VERBOSE) {
+ this.env.reporter.log('>> Jasmine waiting for ' + this.timeout + ' ms...');
+ }
+ this.env.setTimeout(function () {
+ onComplete();
+ }, this.timeout);
+};
+/**
+ * A block which waits for some condition to become true, with timeout.
+ *
+ * @constructor
+ * @extends jasmine.Block
+ * @param {jasmine.Env} env The Jasmine environment.
+ * @param {Number} timeout The maximum time in milliseconds to wait for the condition to become true.
+ * @param {Function} latchFunction A function which returns true when the desired condition has been met.
+ * @param {String} message The message to display if the desired condition hasn't been met within the given time period.
+ * @param {jasmine.Spec} spec The Jasmine spec.
+ */
+jasmine.WaitsForBlock = function(env, timeout, latchFunction, message, spec) {
+ this.timeout = timeout || env.defaultTimeoutInterval;
+ this.latchFunction = latchFunction;
+ this.message = message;
+ this.totalTimeSpentWaitingForLatch = 0;
+ jasmine.Block.call(this, env, null, spec);
+};
+jasmine.util.inherit(jasmine.WaitsForBlock, jasmine.Block);
+
+jasmine.WaitsForBlock.TIMEOUT_INCREMENT = 10;
+
+jasmine.WaitsForBlock.prototype.execute = function(onComplete) {
+ if (jasmine.VERBOSE) {
+ this.env.reporter.log('>> Jasmine waiting for ' + (this.message || 'something to happen'));
+ }
+ var latchFunctionResult;
+ try {
+ latchFunctionResult = this.latchFunction.apply(this.spec);
+ } catch (e) {
+ this.spec.fail(e);
+ onComplete();
+ return;
+ }
+
+ if (latchFunctionResult) {
+ onComplete();
+ } else if (this.totalTimeSpentWaitingForLatch >= this.timeout) {
+ var message = 'timed out after ' + this.timeout + ' msec waiting for ' + (this.message || 'something to happen');
+ this.spec.fail({
+ name: 'timeout',
+ message: message
+ });
+
+ this.abort = true;
+ onComplete();
+ } else {
+ this.totalTimeSpentWaitingForLatch += jasmine.WaitsForBlock.TIMEOUT_INCREMENT;
+ var self = this;
+ this.env.setTimeout(function() {
+ self.execute(onComplete);
+ }, jasmine.WaitsForBlock.TIMEOUT_INCREMENT);
+ }
+};
+
+jasmine.version_= {
+ "major": 1,
+ "minor": 3,
+ "build": 1,
+ "revision": 1354556913
+};
diff --git a/js/test/lib/support/jasmine-content.js b/js/test/lib/support/jasmine-content.js
new file mode 100644
index 00000000..969b7c1e
--- /dev/null
+++ b/js/test/lib/support/jasmine-content.js
@@ -0,0 +1,7 @@
+beforeEach(function() {
+ $('body').append('
');
+});
+
+afterEach(function() {
+ $('body #jasmine_content').remove();
+});
\ No newline at end of file
diff --git a/js/test/lib/support/jasmine-jquery.js b/js/test/lib/support/jasmine-jquery.js
new file mode 100644
index 00000000..c04edfb7
--- /dev/null
+++ b/js/test/lib/support/jasmine-jquery.js
@@ -0,0 +1,673 @@
+/*!
+ Jasmine-jQuery: a set of jQuery helpers for Jasmine tests.
+
+ Version 1.5.8
+
+ https://github.com/velesin/jasmine-jquery
+
+ Copyright (c) 2010-2013 Wojciech Zawistowski, Travis Jeffery
+
+ 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.
+*/
+var readFixtures = function() {
+ return jasmine.getFixtures().proxyCallTo_('read', arguments)
+}
+
+var preloadFixtures = function() {
+ jasmine.getFixtures().proxyCallTo_('preload', arguments)
+}
+
+var loadFixtures = function() {
+ jasmine.getFixtures().proxyCallTo_('load', arguments)
+}
+
+var appendLoadFixtures = function() {
+ jasmine.getFixtures().proxyCallTo_('appendLoad', arguments)
+}
+
+var setFixtures = function(html) {
+ return jasmine.getFixtures().proxyCallTo_('set', arguments)
+}
+
+var appendSetFixtures = function() {
+ jasmine.getFixtures().proxyCallTo_('appendSet', arguments)
+}
+
+var sandbox = function(attributes) {
+ return jasmine.getFixtures().sandbox(attributes)
+}
+
+var spyOnEvent = function(selector, eventName) {
+ return jasmine.JQuery.events.spyOn(selector, eventName)
+}
+
+var preloadStyleFixtures = function() {
+ jasmine.getStyleFixtures().proxyCallTo_('preload', arguments)
+}
+
+var loadStyleFixtures = function() {
+ jasmine.getStyleFixtures().proxyCallTo_('load', arguments)
+}
+
+var appendLoadStyleFixtures = function() {
+ jasmine.getStyleFixtures().proxyCallTo_('appendLoad', arguments)
+}
+
+var setStyleFixtures = function(html) {
+ jasmine.getStyleFixtures().proxyCallTo_('set', arguments)
+}
+
+var appendSetStyleFixtures = function(html) {
+ jasmine.getStyleFixtures().proxyCallTo_('appendSet', arguments)
+}
+
+var loadJSONFixtures = function() {
+ return jasmine.getJSONFixtures().proxyCallTo_('load', arguments)
+}
+
+var getJSONFixture = function(url) {
+ return jasmine.getJSONFixtures().proxyCallTo_('read', arguments)[url]
+}
+
+jasmine.spiedEventsKey = function (selector, eventName) {
+ return [$(selector).selector, eventName].toString()
+}
+
+jasmine.getFixtures = function() {
+ return jasmine.currentFixtures_ = jasmine.currentFixtures_ || new jasmine.Fixtures()
+}
+
+jasmine.getStyleFixtures = function() {
+ return jasmine.currentStyleFixtures_ = jasmine.currentStyleFixtures_ || new jasmine.StyleFixtures()
+}
+
+jasmine.Fixtures = function() {
+ this.containerId = 'jasmine-fixtures'
+ this.fixturesCache_ = {}
+ this.fixturesPath = 'spec/javascripts/fixtures'
+}
+
+jasmine.Fixtures.prototype.set = function(html) {
+ this.cleanUp()
+ return this.createContainer_(html)
+}
+
+jasmine.Fixtures.prototype.appendSet= function(html) {
+ this.addToContainer_(html)
+}
+
+jasmine.Fixtures.prototype.preload = function() {
+ this.read.apply(this, arguments)
+}
+
+jasmine.Fixtures.prototype.load = function() {
+ this.cleanUp()
+ this.createContainer_(this.read.apply(this, arguments))
+}
+
+jasmine.Fixtures.prototype.appendLoad = function() {
+ this.addToContainer_(this.read.apply(this, arguments))
+}
+
+jasmine.Fixtures.prototype.read = function() {
+ var htmlChunks = []
+
+ var fixtureUrls = arguments
+ for(var urlCount = fixtureUrls.length, urlIndex = 0; urlIndex < urlCount; urlIndex++) {
+ htmlChunks.push(this.getFixtureHtml_(fixtureUrls[urlIndex]))
+ }
+
+ return htmlChunks.join('')
+}
+
+jasmine.Fixtures.prototype.clearCache = function() {
+ this.fixturesCache_ = {}
+}
+
+jasmine.Fixtures.prototype.cleanUp = function() {
+ $('#' + this.containerId).remove()
+}
+
+jasmine.Fixtures.prototype.sandbox = function(attributes) {
+ var attributesToSet = attributes || {}
+ return $('
').attr(attributesToSet)
+}
+
+jasmine.Fixtures.prototype.createContainer_ = function(html) {
+ var container = $('')
+ .attr('id', this.containerId)
+ .html(html);
+ $(document.body).append(container)
+ return container
+}
+
+jasmine.Fixtures.prototype.addToContainer_ = function(html){
+ var container = $(document.body).find('#'+this.containerId).append(html)
+ if(!container.length){
+ this.createContainer_(html)
+ }
+}
+
+jasmine.Fixtures.prototype.getFixtureHtml_ = function(url) {
+ if (typeof this.fixturesCache_[url] === 'undefined') {
+ this.loadFixtureIntoCache_(url)
+ }
+ return this.fixturesCache_[url]
+}
+
+jasmine.Fixtures.prototype.loadFixtureIntoCache_ = function(relativeUrl) {
+ var url = this.makeFixtureUrl_(relativeUrl)
+ var request = $.ajax({
+ type: "GET",
+ url: url + "?" + new Date().getTime(),
+ async: false
+ })
+ this.fixturesCache_[relativeUrl] = request.responseText
+}
+
+jasmine.Fixtures.prototype.makeFixtureUrl_ = function(relativeUrl){
+ return this.fixturesPath.match('/$') ? this.fixturesPath + relativeUrl : this.fixturesPath + '/' + relativeUrl
+}
+
+jasmine.Fixtures.prototype.proxyCallTo_ = function(methodName, passedArguments) {
+ return this[methodName].apply(this, passedArguments)
+}
+
+
+jasmine.StyleFixtures = function() {
+ this.fixturesCache_ = {}
+ this.fixturesNodes_ = []
+ this.fixturesPath = 'spec/javascripts/fixtures'
+}
+
+jasmine.StyleFixtures.prototype.set = function(css) {
+ this.cleanUp()
+ this.createStyle_(css)
+}
+
+jasmine.StyleFixtures.prototype.appendSet = function(css) {
+ this.createStyle_(css)
+}
+
+jasmine.StyleFixtures.prototype.preload = function() {
+ this.read_.apply(this, arguments)
+}
+
+jasmine.StyleFixtures.prototype.load = function() {
+ this.cleanUp()
+ this.createStyle_(this.read_.apply(this, arguments))
+}
+
+jasmine.StyleFixtures.prototype.appendLoad = function() {
+ this.createStyle_(this.read_.apply(this, arguments))
+}
+
+jasmine.StyleFixtures.prototype.cleanUp = function() {
+ while(this.fixturesNodes_.length) {
+ this.fixturesNodes_.pop().remove()
+ }
+}
+
+jasmine.StyleFixtures.prototype.createStyle_ = function(html) {
+ var styleText = $('
').html(html).text(),
+ style = $('')
+
+ this.fixturesNodes_.push(style)
+
+ $('head').append(style)
+}
+
+jasmine.StyleFixtures.prototype.clearCache = jasmine.Fixtures.prototype.clearCache
+
+jasmine.StyleFixtures.prototype.read_ = jasmine.Fixtures.prototype.read
+
+jasmine.StyleFixtures.prototype.getFixtureHtml_ = jasmine.Fixtures.prototype.getFixtureHtml_
+
+jasmine.StyleFixtures.prototype.loadFixtureIntoCache_ = jasmine.Fixtures.prototype.loadFixtureIntoCache_
+
+jasmine.StyleFixtures.prototype.makeFixtureUrl_ = jasmine.Fixtures.prototype.makeFixtureUrl_
+
+jasmine.StyleFixtures.prototype.proxyCallTo_ = jasmine.Fixtures.prototype.proxyCallTo_
+
+jasmine.getJSONFixtures = function() {
+ return jasmine.currentJSONFixtures_ = jasmine.currentJSONFixtures_ || new jasmine.JSONFixtures()
+}
+
+jasmine.JSONFixtures = function() {
+ this.fixturesCache_ = {}
+ this.fixturesPath = 'spec/javascripts/fixtures/json'
+}
+
+jasmine.JSONFixtures.prototype.load = function() {
+ this.read.apply(this, arguments)
+ return this.fixturesCache_
+}
+
+jasmine.JSONFixtures.prototype.read = function() {
+ var fixtureUrls = arguments
+ for(var urlCount = fixtureUrls.length, urlIndex = 0; urlIndex < urlCount; urlIndex++) {
+ this.getFixtureData_(fixtureUrls[urlIndex])
+ }
+ return this.fixturesCache_
+}
+
+jasmine.JSONFixtures.prototype.clearCache = function() {
+ this.fixturesCache_ = {}
+}
+
+jasmine.JSONFixtures.prototype.getFixtureData_ = function(url) {
+ this.loadFixtureIntoCache_(url)
+ return this.fixturesCache_[url]
+}
+
+jasmine.JSONFixtures.prototype.loadFixtureIntoCache_ = function(relativeUrl) {
+ var self = this
+ var url = this.fixturesPath.match('/$') ? this.fixturesPath + relativeUrl : this.fixturesPath + '/' + relativeUrl
+ $.ajax({
+ async: false, // must be synchronous to guarantee that no tests are run before fixture is loaded
+ cache: false,
+ dataType: 'json',
+ url: url,
+ success: function(data) {
+ self.fixturesCache_[relativeUrl] = data
+ },
+ error: function(jqXHR, status, errorThrown) {
+ throw Error('JSONFixture could not be loaded: ' + url + ' (status: ' + status + ', message: ' + errorThrown.message + ')')
+ }
+ })
+}
+
+jasmine.JSONFixtures.prototype.proxyCallTo_ = function(methodName, passedArguments) {
+ return this[methodName].apply(this, passedArguments)
+}
+
+jasmine.JQuery = function() {}
+
+jasmine.JQuery.browserTagCaseIndependentHtml = function(html) {
+ return $('
').append(html).html()
+}
+
+jasmine.JQuery.elementToString = function(element) {
+ var domEl = $(element).get(0)
+ if (domEl == undefined || domEl.cloneNode)
+ return $('
').append($(element).clone()).html()
+ else
+ return element.toString()
+}
+
+jasmine.JQuery.matchersClass = {}
+
+!function(namespace) {
+ var data = {
+ spiedEvents: {},
+ handlers: []
+ }
+
+ namespace.events = {
+ spyOn: function(selector, eventName) {
+ var handler = function(e) {
+ data.spiedEvents[jasmine.spiedEventsKey(selector, eventName)] = jasmine.util.argsToArray(arguments)
+ }
+ $(selector).on(eventName, handler)
+ data.handlers.push(handler)
+ return {
+ selector: selector,
+ eventName: eventName,
+ handler: handler,
+ reset: function(){
+ delete data.spiedEvents[jasmine.spiedEventsKey(selector, eventName)]
+ }
+ }
+ },
+
+ args: function(selector, eventName) {
+ var actualArgs = data.spiedEvents[jasmine.spiedEventsKey(selector, eventName)];
+
+ if (!actualArgs) {
+ throw "There is no spy for " + eventName + " on " + selector.toString() + ". Make sure to create a spy using spyOnEvent.";
+ }
+
+ return actualArgs;
+ },
+
+ wasTriggered: function(selector, eventName) {
+ return !!(data.spiedEvents[jasmine.spiedEventsKey(selector, eventName)])
+ },
+
+ wasTriggeredWith: function(selector, eventName, expectedArgs, env) {
+ var actualArgs = jasmine.JQuery.events.args(selector, eventName).slice(1);
+ if (Object.prototype.toString.call(expectedArgs) !== '[object Array]') {
+ actualArgs = actualArgs[0];
+ }
+ return env.equals_(expectedArgs, actualArgs);
+ },
+
+ wasPrevented: function(selector, eventName) {
+ var args = data.spiedEvents[jasmine.spiedEventsKey(selector, eventName)],
+ e = args ? args[0] : undefined;
+ return e && e.isDefaultPrevented()
+ },
+
+ wasStopped: function(selector, eventName) {
+ var args = data.spiedEvents[jasmine.spiedEventsKey(selector, eventName)],
+ e = args ? args[0] : undefined;
+ return e && e.isPropagationStopped()
+ },
+
+ cleanUp: function() {
+ data.spiedEvents = {}
+ data.handlers = []
+ }
+ }
+}(jasmine.JQuery)
+
+!function(){
+ var jQueryMatchers = {
+ toHaveClass: function(className) {
+ return this.actual.hasClass(className)
+ },
+
+ toHaveCss: function(css){
+ for (var prop in css){
+ if (this.actual.css(prop) !== css[prop]) return false
+ }
+ return true
+ },
+
+ toBeVisible: function() {
+ return this.actual.is(':visible')
+ },
+
+ toBeHidden: function() {
+ return this.actual.is(':hidden')
+ },
+
+ toBeSelected: function() {
+ return this.actual.is(':selected')
+ },
+
+ toBeChecked: function() {
+ return this.actual.is(':checked')
+ },
+
+ toBeEmpty: function() {
+ return this.actual.is(':empty')
+ },
+
+ toExist: function() {
+ return $(document).find(this.actual).length
+ },
+
+ toHaveLength: function(length) {
+ return this.actual.length === length
+ },
+
+ toHaveAttr: function(attributeName, expectedAttributeValue) {
+ return hasProperty(this.actual.attr(attributeName), expectedAttributeValue)
+ },
+
+ toHaveProp: function(propertyName, expectedPropertyValue) {
+ return hasProperty(this.actual.prop(propertyName), expectedPropertyValue)
+ },
+
+ toHaveId: function(id) {
+ return this.actual.attr('id') == id
+ },
+
+ toHaveHtml: function(html) {
+ return this.actual.html() == jasmine.JQuery.browserTagCaseIndependentHtml(html)
+ },
+
+ toContainHtml: function(html){
+ var actualHtml = this.actual.html()
+ var expectedHtml = jasmine.JQuery.browserTagCaseIndependentHtml(html)
+ return (actualHtml.indexOf(expectedHtml) >= 0)
+ },
+
+ toHaveText: function(text) {
+ var trimmedText = $.trim(this.actual.text())
+ if (text && $.isFunction(text.test)) {
+ return text.test(trimmedText)
+ } else {
+ return trimmedText == text
+ }
+ },
+
+ toContainText: function(text) {
+ var trimmedText = $.trim(this.actual.text())
+ if (text && $.isFunction(text.test)) {
+ return text.test(trimmedText)
+ } else {
+ return trimmedText.indexOf(text) != -1;
+ }
+ },
+
+ toHaveValue: function(value) {
+ return this.actual.val() === value
+ },
+
+ toHaveData: function(key, expectedValue) {
+ return hasProperty(this.actual.data(key), expectedValue)
+ },
+
+ toBe: function(selector) {
+ return this.actual.is(selector)
+ },
+
+ toContain: function(selector) {
+ return this.actual.find(selector).length
+ },
+
+ toBeMatchedBy: function(selector) {
+ return this.actual.filter(selector).length
+ },
+
+ toBeDisabled: function(selector){
+ return this.actual.is(':disabled')
+ },
+
+ toBeFocused: function(selector) {
+ return this.actual[0] === this.actual[0].ownerDocument.activeElement
+ },
+
+ toHandle: function(event) {
+
+ var events = $._data(this.actual.get(0), "events")
+
+ if(!events || !event || typeof event !== "string") {
+ return false
+ }
+
+ var namespaces = event.split(".")
+ var eventType = namespaces.shift()
+ var sortedNamespaces = namespaces.slice(0).sort()
+ var namespaceRegExp = new RegExp("(^|\\.)" + sortedNamespaces.join("\\.(?:.*\\.)?") + "(\\.|$)")
+
+ if(events[eventType] && namespaces.length) {
+ for(var i = 0; i < events[eventType].length; i++) {
+ var namespace = events[eventType][i].namespace
+ if(namespaceRegExp.test(namespace)) {
+ return true
+ }
+ }
+ } else {
+ return events[eventType] && events[eventType].length > 0
+ }
+ },
+
+ // tests the existence of a specific event binding + handler
+ toHandleWith: function(eventName, eventHandler) {
+ var normalizedEventName = eventName.split('.')[0];
+ var stack = $._data(this.actual.get(0), "events")[normalizedEventName]
+ for (var i = 0; i < stack.length; i++) {
+ if (stack[i].handler == eventHandler) return true
+ }
+ return false
+ }
+ }
+
+ var hasProperty = function(actualValue, expectedValue) {
+ if (expectedValue === undefined) return actualValue !== undefined
+ return actualValue == expectedValue
+ }
+
+ var bindMatcher = function(methodName) {
+ var builtInMatcher = jasmine.Matchers.prototype[methodName]
+
+ jasmine.JQuery.matchersClass[methodName] = function() {
+ if (this.actual
+ && (this.actual instanceof $
+ || jasmine.isDomNode(this.actual))) {
+ this.actual = $(this.actual)
+ var result = jQueryMatchers[methodName].apply(this, arguments)
+ var element
+ if (this.actual.get && (element = this.actual.get()[0]) && !$.isWindow(element) && element.tagName !== "HTML")
+ this.actual = jasmine.JQuery.elementToString(this.actual)
+ return result
+ }
+
+ if (builtInMatcher) {
+ return builtInMatcher.apply(this, arguments)
+ }
+
+ return false
+ }
+ }
+
+ for(var methodName in jQueryMatchers) {
+ bindMatcher(methodName)
+ }
+}()
+
+beforeEach(function() {
+ this.addMatchers(jasmine.JQuery.matchersClass)
+ this.addMatchers({
+ toHaveBeenTriggeredOn: function(selector) {
+ this.message = function() {
+ return [
+ "Expected event " + this.actual + " to have been triggered on " + selector,
+ "Expected event " + this.actual + " not to have been triggered on " + selector
+ ]
+ }
+ return jasmine.JQuery.events.wasTriggered(selector, this.actual)
+ }
+ })
+ this.addMatchers({
+ toHaveBeenTriggered: function(){
+ var eventName = this.actual.eventName,
+ selector = this.actual.selector
+ this.message = function() {
+ return [
+ "Expected event " + eventName + " to have been triggered on " + selector,
+ "Expected event " + eventName + " not to have been triggered on " + selector
+ ]
+ }
+ return jasmine.JQuery.events.wasTriggered(selector, eventName)
+ }
+ })
+ this.addMatchers({
+ toHaveBeenTriggeredOnAndWith: function() {
+ var selector = arguments[0],
+ expectedArgs = arguments[1],
+ wasTriggered = jasmine.JQuery.events.wasTriggered(selector, this.actual);
+ this.message = function() {
+ if (wasTriggered) {
+ var actualArgs = jasmine.JQuery.events.args(selector, this.actual, expectedArgs)[1];
+ return [
+ "Expected event " + this.actual + " to have been triggered with " + jasmine.pp(expectedArgs) + " but it was triggered with " + jasmine.pp(actualArgs),
+ "Expected event " + this.actual + " not to have been triggered with " + jasmine.pp(expectedArgs) + " but it was triggered with " + jasmine.pp(actualArgs)
+ ]
+ } else {
+ return [
+ "Expected event " + this.actual + " to have been triggered on " + selector,
+ "Expected event " + this.actual + " not to have been triggered on " + selector
+ ]
+ }
+ }
+ return wasTriggered && jasmine.JQuery.events.wasTriggeredWith(selector, this.actual, expectedArgs, this.env);
+ }
+ })
+ this.addMatchers({
+ toHaveBeenPreventedOn: function(selector) {
+ this.message = function() {
+ return [
+ "Expected event " + this.actual + " to have been prevented on " + selector,
+ "Expected event " + this.actual + " not to have been prevented on " + selector
+ ]
+ }
+ return jasmine.JQuery.events.wasPrevented(selector, this.actual)
+ }
+ })
+ this.addMatchers({
+ toHaveBeenPrevented: function() {
+ var eventName = this.actual.eventName,
+ selector = this.actual.selector
+ this.message = function() {
+ return [
+ "Expected event " + eventName + " to have been prevented on " + selector,
+ "Expected event " + eventName + " not to have been prevented on " + selector
+ ]
+ }
+ return jasmine.JQuery.events.wasPrevented(selector, eventName)
+ }
+ })
+ this.addMatchers({
+ toHaveBeenStoppedOn: function(selector) {
+ this.message = function() {
+ return [
+ "Expected event " + this.actual + " to have been stopped on " + selector,
+ "Expected event " + this.actual + " not to have been stopped on " + selector
+ ]
+ }
+ return jasmine.JQuery.events.wasStopped(selector, this.actual)
+ }
+ })
+ this.addMatchers({
+ toHaveBeenStopped: function() {
+ var eventName = this.actual.eventName,
+ selector = this.actual.selector
+ this.message = function() {
+ return [
+ "Expected event " + eventName + " to have been stopped on " + selector,
+ "Expected event " + eventName + " not to have been stopped on " + selector
+ ]
+ }
+ return jasmine.JQuery.events.wasStopped(selector, eventName)
+ }
+ })
+ jasmine.getEnv().addEqualityTester(function(a, b) {
+ if(a instanceof jQuery && b instanceof jQuery) {
+ if(a.size() != b.size()) {
+ return jasmine.undefined;
+ }
+ else if(a.is(b)) {
+ return true;
+ }
+ }
+ return jasmine.undefined;
+
+ })
+})
+
+afterEach(function() {
+ jasmine.getFixtures().cleanUp()
+ jasmine.getStyleFixtures().cleanUp()
+ jasmine.JQuery.events.cleanUp()
+})
diff --git a/js/test/lib/support/mock-ajax.js b/js/test/lib/support/mock-ajax.js
new file mode 100644
index 00000000..5c99627a
--- /dev/null
+++ b/js/test/lib/support/mock-ajax.js
@@ -0,0 +1,207 @@
+/*
+ Jasmine-Ajax : a set of helpers for testing AJAX requests under the Jasmine
+ BDD framework for JavaScript.
+
+ Supports both Prototype.js and jQuery.
+
+ http://github.com/pivotal/jasmine-ajax
+
+ Jasmine Home page: http://pivotal.github.com/jasmine
+
+ Copyright (c) 2008-2010 Pivotal Labs
+
+ 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.
+
+ */
+
+// Jasmine-Ajax interface
+var ajaxRequests = [];
+
+function mostRecentAjaxRequest() {
+ if (ajaxRequests.length > 0) {
+ return ajaxRequests[ajaxRequests.length - 1];
+ } else {
+ return null;
+ }
+}
+
+function clearAjaxRequests() {
+ ajaxRequests = [];
+}
+
+// Fake XHR for mocking Ajax Requests & Responses
+function FakeXMLHttpRequest() {
+ var extend = Object.extend || $.extend;
+ extend(this, {
+ requestHeaders: {},
+
+ open: function() {
+ this.method = arguments[0];
+ this.url = arguments[1];
+ this.readyState = 1;
+ },
+
+ setRequestHeader: function(header, value) {
+ this.requestHeaders[header] = value;
+ },
+
+ abort: function() {
+ this.readyState = 0;
+ },
+
+ readyState: 0,
+
+ onreadystatechange: function(isTimeout) {
+ },
+
+ status: null,
+
+ send: function(data) {
+ this.params = data;
+ this.readyState = 2;
+ },
+
+ getResponseHeader: function(name) {
+ return this.responseHeaders[name];
+ },
+
+ getAllResponseHeaders: function() {
+ var responseHeaders = [];
+ for (var i in this.responseHeaders) {
+ if (this.responseHeaders.hasOwnProperty(i)) {
+ responseHeaders.push(i + ': ' + this.responseHeaders[i]);
+ }
+ }
+ return responseHeaders.join('\r\n');
+ },
+
+ responseText: null,
+
+ response: function(response) {
+ this.status = response.status;
+ this.responseText = response.responseText || "";
+ this.readyState = 4;
+ this.responseHeaders = response.responseHeaders ||
+ {"Content-type": response.contentType || "application/json" };
+ // uncomment for jquery 1.3.x support
+ // jasmine.Clock.tick(20);
+
+ this.onreadystatechange();
+ },
+ responseTimeout: function() {
+ this.readyState = 4;
+ jasmine.Clock.tick(jQuery.ajaxSettings.timeout || 30000);
+ this.onreadystatechange('timeout');
+ }
+ });
+
+ return this;
+}
+
+
+jasmine.Ajax = {
+
+ isInstalled: function() {
+ return jasmine.Ajax.installed == true;
+ },
+
+ assertInstalled: function() {
+ if (!jasmine.Ajax.isInstalled()) {
+ throw new Error("Mock ajax is not installed, use jasmine.Ajax.useMock()")
+ }
+ },
+
+ useMock: function() {
+ if (!jasmine.Ajax.isInstalled()) {
+ var spec = jasmine.getEnv().currentSpec;
+ spec.after(jasmine.Ajax.uninstallMock);
+
+ jasmine.Ajax.installMock();
+ }
+ },
+
+ installMock: function() {
+ if (typeof jQuery != 'undefined') {
+ jasmine.Ajax.installJquery();
+ } else if (typeof Prototype != 'undefined') {
+ jasmine.Ajax.installPrototype();
+ } else {
+ throw new Error("jasmine.Ajax currently only supports jQuery and Prototype");
+ }
+ jasmine.Ajax.installed = true;
+ },
+
+ installJquery: function() {
+ jasmine.Ajax.mode = 'jQuery';
+ jasmine.Ajax.real = jQuery.ajaxSettings.xhr;
+ jQuery.ajaxSettings.xhr = jasmine.Ajax.jQueryMock;
+
+ },
+
+ installPrototype: function() {
+ jasmine.Ajax.mode = 'Prototype';
+ jasmine.Ajax.real = Ajax.getTransport;
+
+ Ajax.getTransport = jasmine.Ajax.prototypeMock;
+ },
+
+ uninstallMock: function() {
+ jasmine.Ajax.assertInstalled();
+ if (jasmine.Ajax.mode == 'jQuery') {
+ jQuery.ajaxSettings.xhr = jasmine.Ajax.real;
+ } else if (jasmine.Ajax.mode == 'Prototype') {
+ Ajax.getTransport = jasmine.Ajax.real;
+ }
+ jasmine.Ajax.reset();
+ },
+
+ reset: function() {
+ jasmine.Ajax.installed = false;
+ jasmine.Ajax.mode = null;
+ jasmine.Ajax.real = null;
+ },
+
+ jQueryMock: function() {
+ var newXhr = new FakeXMLHttpRequest();
+ ajaxRequests.push(newXhr);
+ return newXhr;
+ },
+
+ prototypeMock: function() {
+ return new FakeXMLHttpRequest();
+ },
+
+ installed: false,
+ mode: null
+}
+
+
+// Jasmine-Ajax Glue code for Prototype.js
+if (typeof Prototype != 'undefined' && Ajax && Ajax.Request) {
+ Ajax.Request.prototype.originalRequest = Ajax.Request.prototype.request;
+ Ajax.Request.prototype.request = function(url) {
+ this.originalRequest(url);
+ ajaxRequests.push(this);
+ };
+
+ Ajax.Request.prototype.response = function(responseOptions) {
+ return this.transport.response(responseOptions);
+ };
+}
diff --git a/js/test/spec/QuickStartWidgetSpec.js b/js/test/spec/QuickStartWidgetSpec.js
new file mode 100644
index 00000000..b5587776
--- /dev/null
+++ b/js/test/spec/QuickStartWidgetSpec.js
@@ -0,0 +1,109 @@
+describe("QuickStartWidget", function () {
+
+ describe("rendering", function () {
+
+ beforeEach(function () {
+ var project = new Spring.Project({
+ "id": "spring-data-jpa",
+ "name": "Spring Data JPA",
+ "repoUrl": "http://github.com/SpringSource/spring-data-jpa",
+ "siteUrl": "http://projects.spring.io/spring-data-jpa",
+ "projectReleases": [
+ {
+ "refDocUrl": "http://docs.spring.io/spring-data/jpa/docs/1.4.0.RC1/reference/html/",
+ "apiDocUrl": "http://docs.spring.io/spring-data/jpa/docs/1.4.0.RC1/api/",
+ "groupId": "org.springframework.data",
+ "artifactId": "spring-data-jpa",
+ "repository": {
+ "id": "spring-milestones",
+ "name": "Spring Milestones",
+ "url": "http://repo.spring.io/milestone",
+ "snapshotsEnabled": false
+ },
+ "version": "1.4.0.RC1",
+ "current": false,
+ "preRelease": true,
+ "snapshot": false,
+ "generalAvailability": false,
+ "versionDisplayName": "1.4.0.RC1"
+ },
+ {
+ "refDocUrl": "http://docs.spring.io/spring-data/jpa/docs/1.3.4.RELEASE/reference/html/",
+ "apiDocUrl": "http://docs.spring.io/spring-data/jpa/docs/1.3.4.RELEASE/api/",
+ "groupId": "org.springframework.data",
+ "artifactId": "spring-data-jpa",
+ "repository": null,
+ "version": "1.3.4.RELEASE",
+ "current": true,
+ "preRelease": false,
+ "snapshot": false,
+ "generalAvailability": true,
+ "versionDisplayName": "1.3.4"
+ }
+ ]
+ });
+
+ $('#jasmine_content').append("
");
+ $('#jasmine_content').append("
");
+ Spring.buildQuickStartWidget("#quick_select_widget", "#maven_widget", project);
+ });
+
+ it("lists out each release's version", function () {
+ expect($('#quick_select_widget')).toContainText("1.4.0.RC1");
+ expect($('#quick_select_widget')).toContainText("1.3.4");
+ });
+
+ describe("maven view", function() {
+ it("shows the current release dependency by default", function() {
+ expect($('#maven_widget')).toContainText("org.springframework.data");
+ expect($('#maven_widget')).toContainText("spring-data-jpa");
+ expect($('#maven_widget')).toContainText("1.3.4.RELEASE");
+ });
+
+ it("shows the correct dependency when users select a different release", function() {
+ $('#jasmine_content select').val(0).change();
+
+ expect($('#maven_widget')).toContainText("org.springframework.data");
+ expect($('#maven_widget')).toContainText("spring-data-jpa");
+ expect($('#maven_widget')).toContainText("1.4.0.RC1");
+ });
+
+ it("shows the repository information if user selects a release with a repository", function() {
+ $('#jasmine_content select').val(0).change();
+
+ expect($('#maven_widget')).toContainText("spring-milestones");
+ expect($('#maven_widget')).toContainText("Spring Milestones");
+ expect($('#maven_widget')).toContainText("http://repo.spring.io/milestone");
+ expect($('#maven_widget')).toContainText("false");
+ });
+
+ it("doesn't show the repository if the user selects a release without a repository", function (){
+ $('#jasmine_content select').val(1).change();
+
+ expect($('#maven_widget')).not.toContainText("repository");
+ expect($('#maven_widget')).not.toContainText("spring-milestones");
+ expect($('#maven_widget')).not.toContainText("Spring Milestones");
+ expect($('#maven_widget')).not.toContainText("http://repo.spring.io/milestone");
+ expect($('#maven_widget')).not.toContainText("false");
+ });
+ });
+
+ describe("gradle view", function() {
+ beforeEach(function() {
+ $("#quick_select_widget [data-snippet-type=gradle]").click();
+ });
+
+ it("shows the current release dependency by default", function() {
+ expect($('#maven_widget')).toContainText("dependencies");
+ expect($('#maven_widget')).toContainText("org.springframework.data:spring-data-jpa:1.3.4.RELEASE");
+ });
+
+ it("shows the repository if the data has one", function() {
+ $('#jasmine_content select').val(0).change();
+
+ expect($('#maven_widget')).toContainText("repositories");
+ expect($('#maven_widget')).toContainText("http://repo.spring.io/milestone");
+ });
+ });
+ });
+});
diff --git a/js/underscore.js b/js/underscore.js
new file mode 100644
index 00000000..7d4ee27c
--- /dev/null
+++ b/js/underscore.js
@@ -0,0 +1,1246 @@
+// Underscore.js 1.5.1
+// http://underscorejs.org
+// (c) 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
+// Underscore may be freely distributed under the MIT license.
+
+(function() {
+
+ // Baseline setup
+ // --------------
+
+ // Establish the root object, `window` in the browser, or `global` on the server.
+ var root = this;
+
+ // Save the previous value of the `_` variable.
+ var previousUnderscore = root._;
+
+ // Establish the object that gets returned to break out of a loop iteration.
+ var breaker = {};
+
+ // Save bytes in the minified (but not gzipped) version:
+ var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype;
+
+ // Create quick reference variables for speed access to core prototypes.
+ var
+ push = ArrayProto.push,
+ slice = ArrayProto.slice,
+ concat = ArrayProto.concat,
+ toString = ObjProto.toString,
+ hasOwnProperty = ObjProto.hasOwnProperty;
+
+ // All **ECMAScript 5** native function implementations that we hope to use
+ // are declared here.
+ var
+ nativeForEach = ArrayProto.forEach,
+ nativeMap = ArrayProto.map,
+ nativeReduce = ArrayProto.reduce,
+ nativeReduceRight = ArrayProto.reduceRight,
+ nativeFilter = ArrayProto.filter,
+ nativeEvery = ArrayProto.every,
+ nativeSome = ArrayProto.some,
+ nativeIndexOf = ArrayProto.indexOf,
+ nativeLastIndexOf = ArrayProto.lastIndexOf,
+ nativeIsArray = Array.isArray,
+ nativeKeys = Object.keys,
+ nativeBind = FuncProto.bind;
+
+ // Create a safe reference to the Underscore object for use below.
+ var _ = function(obj) {
+ if (obj instanceof _) return obj;
+ if (!(this instanceof _)) return new _(obj);
+ this._wrapped = obj;
+ };
+
+ // Export the Underscore object for **Node.js**, with
+ // backwards-compatibility for the old `require()` API. If we're in
+ // the browser, add `_` as a global object via a string identifier,
+ // for Closure Compiler "advanced" mode.
+ if (typeof exports !== 'undefined') {
+ if (typeof module !== 'undefined' && module.exports) {
+ exports = module.exports = _;
+ }
+ exports._ = _;
+ } else {
+ root._ = _;
+ }
+
+ // Current version.
+ _.VERSION = '1.5.1';
+
+ // Collection Functions
+ // --------------------
+
+ // The cornerstone, an `each` implementation, aka `forEach`.
+ // Handles objects with the built-in `forEach`, arrays, and raw objects.
+ // Delegates to **ECMAScript 5**'s native `forEach` if available.
+ var each = _.each = _.forEach = function(obj, iterator, context) {
+ if (obj == null) return;
+ if (nativeForEach && obj.forEach === nativeForEach) {
+ obj.forEach(iterator, context);
+ } else if (obj.length === +obj.length) {
+ for (var i = 0, l = obj.length; i < l; i++) {
+ if (iterator.call(context, obj[i], i, obj) === breaker) return;
+ }
+ } else {
+ for (var key in obj) {
+ if (_.has(obj, key)) {
+ if (iterator.call(context, obj[key], key, obj) === breaker) return;
+ }
+ }
+ }
+ };
+
+ // Return the results of applying the iterator to each element.
+ // Delegates to **ECMAScript 5**'s native `map` if available.
+ _.map = _.collect = function(obj, iterator, context) {
+ var results = [];
+ if (obj == null) return results;
+ if (nativeMap && obj.map === nativeMap) return obj.map(iterator, context);
+ each(obj, function(value, index, list) {
+ results.push(iterator.call(context, value, index, list));
+ });
+ return results;
+ };
+
+ var reduceError = 'Reduce of empty array with no initial value';
+
+ // **Reduce** builds up a single result from a list of values, aka `inject`,
+ // or `foldl`. Delegates to **ECMAScript 5**'s native `reduce` if available.
+ _.reduce = _.foldl = _.inject = function(obj, iterator, memo, context) {
+ var initial = arguments.length > 2;
+ if (obj == null) obj = [];
+ if (nativeReduce && obj.reduce === nativeReduce) {
+ if (context) iterator = _.bind(iterator, context);
+ return initial ? obj.reduce(iterator, memo) : obj.reduce(iterator);
+ }
+ each(obj, function(value, index, list) {
+ if (!initial) {
+ memo = value;
+ initial = true;
+ } else {
+ memo = iterator.call(context, memo, value, index, list);
+ }
+ });
+ if (!initial) throw new TypeError(reduceError);
+ return memo;
+ };
+
+ // The right-associative version of reduce, also known as `foldr`.
+ // Delegates to **ECMAScript 5**'s native `reduceRight` if available.
+ _.reduceRight = _.foldr = function(obj, iterator, memo, context) {
+ var initial = arguments.length > 2;
+ if (obj == null) obj = [];
+ if (nativeReduceRight && obj.reduceRight === nativeReduceRight) {
+ if (context) iterator = _.bind(iterator, context);
+ return initial ? obj.reduceRight(iterator, memo) : obj.reduceRight(iterator);
+ }
+ var length = obj.length;
+ if (length !== +length) {
+ var keys = _.keys(obj);
+ length = keys.length;
+ }
+ each(obj, function(value, index, list) {
+ index = keys ? keys[--length] : --length;
+ if (!initial) {
+ memo = obj[index];
+ initial = true;
+ } else {
+ memo = iterator.call(context, memo, obj[index], index, list);
+ }
+ });
+ if (!initial) throw new TypeError(reduceError);
+ return memo;
+ };
+
+ // Return the first value which passes a truth test. Aliased as `detect`.
+ _.find = _.detect = function(obj, iterator, context) {
+ var result;
+ any(obj, function(value, index, list) {
+ if (iterator.call(context, value, index, list)) {
+ result = value;
+ return true;
+ }
+ });
+ return result;
+ };
+
+ // Return all the elements that pass a truth test.
+ // Delegates to **ECMAScript 5**'s native `filter` if available.
+ // Aliased as `select`.
+ _.filter = _.select = function(obj, iterator, context) {
+ var results = [];
+ if (obj == null) return results;
+ if (nativeFilter && obj.filter === nativeFilter) return obj.filter(iterator, context);
+ each(obj, function(value, index, list) {
+ if (iterator.call(context, value, index, list)) results.push(value);
+ });
+ return results;
+ };
+
+ // Return all the elements for which a truth test fails.
+ _.reject = function(obj, iterator, context) {
+ return _.filter(obj, function(value, index, list) {
+ return !iterator.call(context, value, index, list);
+ }, context);
+ };
+
+ // Determine whether all of the elements match a truth test.
+ // Delegates to **ECMAScript 5**'s native `every` if available.
+ // Aliased as `all`.
+ _.every = _.all = function(obj, iterator, context) {
+ iterator || (iterator = _.identity);
+ var result = true;
+ if (obj == null) return result;
+ if (nativeEvery && obj.every === nativeEvery) return obj.every(iterator, context);
+ each(obj, function(value, index, list) {
+ if (!(result = result && iterator.call(context, value, index, list))) return breaker;
+ });
+ return !!result;
+ };
+
+ // Determine if at least one element in the object matches a truth test.
+ // Delegates to **ECMAScript 5**'s native `some` if available.
+ // Aliased as `any`.
+ var any = _.some = _.any = function(obj, iterator, context) {
+ iterator || (iterator = _.identity);
+ var result = false;
+ if (obj == null) return result;
+ if (nativeSome && obj.some === nativeSome) return obj.some(iterator, context);
+ each(obj, function(value, index, list) {
+ if (result || (result = iterator.call(context, value, index, list))) return breaker;
+ });
+ return !!result;
+ };
+
+ // Determine if the array or object contains a given value (using `===`).
+ // Aliased as `include`.
+ _.contains = _.include = function(obj, target) {
+ if (obj == null) return false;
+ if (nativeIndexOf && obj.indexOf === nativeIndexOf) return obj.indexOf(target) != -1;
+ return any(obj, function(value) {
+ return value === target;
+ });
+ };
+
+ // Invoke a method (with arguments) on every item in a collection.
+ _.invoke = function(obj, method) {
+ var args = slice.call(arguments, 2);
+ var isFunc = _.isFunction(method);
+ return _.map(obj, function(value) {
+ return (isFunc ? method : value[method]).apply(value, args);
+ });
+ };
+
+ // Convenience version of a common use case of `map`: fetching a property.
+ _.pluck = function(obj, key) {
+ return _.map(obj, function(value){ return value[key]; });
+ };
+
+ // Convenience version of a common use case of `filter`: selecting only objects
+ // containing specific `key:value` pairs.
+ _.where = function(obj, attrs, first) {
+ if (_.isEmpty(attrs)) return first ? void 0 : [];
+ return _[first ? 'find' : 'filter'](obj, function(value) {
+ for (var key in attrs) {
+ if (attrs[key] !== value[key]) return false;
+ }
+ return true;
+ });
+ };
+
+ // Convenience version of a common use case of `find`: getting the first object
+ // containing specific `key:value` pairs.
+ _.findWhere = function(obj, attrs) {
+ return _.where(obj, attrs, true);
+ };
+
+ // Return the maximum element or (element-based computation).
+ // Can't optimize arrays of integers longer than 65,535 elements.
+ // See [WebKit Bug 80797](https://bugs.webkit.org/show_bug.cgi?id=80797)
+ _.max = function(obj, iterator, context) {
+ if (!iterator && _.isArray(obj) && obj[0] === +obj[0] && obj.length < 65535) {
+ return Math.max.apply(Math, obj);
+ }
+ if (!iterator && _.isEmpty(obj)) return -Infinity;
+ var result = {computed : -Infinity, value: -Infinity};
+ each(obj, function(value, index, list) {
+ var computed = iterator ? iterator.call(context, value, index, list) : value;
+ computed > result.computed && (result = {value : value, computed : computed});
+ });
+ return result.value;
+ };
+
+ // Return the minimum element (or element-based computation).
+ _.min = function(obj, iterator, context) {
+ if (!iterator && _.isArray(obj) && obj[0] === +obj[0] && obj.length < 65535) {
+ return Math.min.apply(Math, obj);
+ }
+ if (!iterator && _.isEmpty(obj)) return Infinity;
+ var result = {computed : Infinity, value: Infinity};
+ each(obj, function(value, index, list) {
+ var computed = iterator ? iterator.call(context, value, index, list) : value;
+ computed < result.computed && (result = {value : value, computed : computed});
+ });
+ return result.value;
+ };
+
+ // Shuffle an array.
+ _.shuffle = function(obj) {
+ var rand;
+ var index = 0;
+ var shuffled = [];
+ each(obj, function(value) {
+ rand = _.random(index++);
+ shuffled[index - 1] = shuffled[rand];
+ shuffled[rand] = value;
+ });
+ return shuffled;
+ };
+
+ // An internal function to generate lookup iterators.
+ var lookupIterator = function(value) {
+ return _.isFunction(value) ? value : function(obj){ return obj[value]; };
+ };
+
+ // Sort the object's values by a criterion produced by an iterator.
+ _.sortBy = function(obj, value, context) {
+ var iterator = lookupIterator(value);
+ return _.pluck(_.map(obj, function(value, index, list) {
+ return {
+ value : value,
+ index : index,
+ criteria : iterator.call(context, value, index, list)
+ };
+ }).sort(function(left, right) {
+ var a = left.criteria;
+ var b = right.criteria;
+ if (a !== b) {
+ if (a > b || a === void 0) return 1;
+ if (a < b || b === void 0) return -1;
+ }
+ return left.index < right.index ? -1 : 1;
+ }), 'value');
+ };
+
+ // An internal function used for aggregate "group by" operations.
+ var group = function(obj, value, context, behavior) {
+ var result = {};
+ var iterator = lookupIterator(value == null ? _.identity : value);
+ each(obj, function(value, index) {
+ var key = iterator.call(context, value, index, obj);
+ behavior(result, key, value);
+ });
+ return result;
+ };
+
+ // Groups the object's values by a criterion. Pass either a string attribute
+ // to group by, or a function that returns the criterion.
+ _.groupBy = function(obj, value, context) {
+ return group(obj, value, context, function(result, key, value) {
+ (_.has(result, key) ? result[key] : (result[key] = [])).push(value);
+ });
+ };
+
+ // Counts instances of an object that group by a certain criterion. Pass
+ // either a string attribute to count by, or a function that returns the
+ // criterion.
+ _.countBy = function(obj, value, context) {
+ return group(obj, value, context, function(result, key) {
+ if (!_.has(result, key)) result[key] = 0;
+ result[key]++;
+ });
+ };
+
+ // Use a comparator function to figure out the smallest index at which
+ // an object should be inserted so as to maintain order. Uses binary search.
+ _.sortedIndex = function(array, obj, iterator, context) {
+ iterator = iterator == null ? _.identity : lookupIterator(iterator);
+ var value = iterator.call(context, obj);
+ var low = 0, high = array.length;
+ while (low < high) {
+ var mid = (low + high) >>> 1;
+ iterator.call(context, array[mid]) < value ? low = mid + 1 : high = mid;
+ }
+ return low;
+ };
+
+ // Safely create a real, live array from anything iterable.
+ _.toArray = function(obj) {
+ if (!obj) return [];
+ if (_.isArray(obj)) return slice.call(obj);
+ if (obj.length === +obj.length) return _.map(obj, _.identity);
+ return _.values(obj);
+ };
+
+ // Return the number of elements in an object.
+ _.size = function(obj) {
+ if (obj == null) return 0;
+ return (obj.length === +obj.length) ? obj.length : _.keys(obj).length;
+ };
+
+ // Array Functions
+ // ---------------
+
+ // Get the first element of an array. Passing **n** will return the first N
+ // values in the array. Aliased as `head` and `take`. The **guard** check
+ // allows it to work with `_.map`.
+ _.first = _.head = _.take = function(array, n, guard) {
+ if (array == null) return void 0;
+ return (n != null) && !guard ? slice.call(array, 0, n) : array[0];
+ };
+
+ // Returns everything but the last entry of the array. Especially useful on
+ // the arguments object. Passing **n** will return all the values in
+ // the array, excluding the last N. The **guard** check allows it to work with
+ // `_.map`.
+ _.initial = function(array, n, guard) {
+ return slice.call(array, 0, array.length - ((n == null) || guard ? 1 : n));
+ };
+
+ // Get the last element of an array. Passing **n** will return the last N
+ // values in the array. The **guard** check allows it to work with `_.map`.
+ _.last = function(array, n, guard) {
+ if (array == null) return void 0;
+ if ((n != null) && !guard) {
+ return slice.call(array, Math.max(array.length - n, 0));
+ } else {
+ return array[array.length - 1];
+ }
+ };
+
+ // Returns everything but the first entry of the array. Aliased as `tail` and `drop`.
+ // Especially useful on the arguments object. Passing an **n** will return
+ // the rest N values in the array. The **guard**
+ // check allows it to work with `_.map`.
+ _.rest = _.tail = _.drop = function(array, n, guard) {
+ return slice.call(array, (n == null) || guard ? 1 : n);
+ };
+
+ // Trim out all falsy values from an array.
+ _.compact = function(array) {
+ return _.filter(array, _.identity);
+ };
+
+ // Internal implementation of a recursive `flatten` function.
+ var flatten = function(input, shallow, output) {
+ if (shallow && _.every(input, _.isArray)) {
+ return concat.apply(output, input);
+ }
+ each(input, function(value) {
+ if (_.isArray(value) || _.isArguments(value)) {
+ shallow ? push.apply(output, value) : flatten(value, shallow, output);
+ } else {
+ output.push(value);
+ }
+ });
+ return output;
+ };
+
+ // Return a completely flattened version of an array.
+ _.flatten = function(array, shallow) {
+ return flatten(array, shallow, []);
+ };
+
+ // Return a version of the array that does not contain the specified value(s).
+ _.without = function(array) {
+ return _.difference(array, slice.call(arguments, 1));
+ };
+
+ // Produce a duplicate-free version of the array. If the array has already
+ // been sorted, you have the option of using a faster algorithm.
+ // Aliased as `unique`.
+ _.uniq = _.unique = function(array, isSorted, iterator, context) {
+ if (_.isFunction(isSorted)) {
+ context = iterator;
+ iterator = isSorted;
+ isSorted = false;
+ }
+ var initial = iterator ? _.map(array, iterator, context) : array;
+ var results = [];
+ var seen = [];
+ each(initial, function(value, index) {
+ if (isSorted ? (!index || seen[seen.length - 1] !== value) : !_.contains(seen, value)) {
+ seen.push(value);
+ results.push(array[index]);
+ }
+ });
+ return results;
+ };
+
+ // Produce an array that contains the union: each distinct element from all of
+ // the passed-in arrays.
+ _.union = function() {
+ return _.uniq(_.flatten(arguments, true));
+ };
+
+ // Produce an array that contains every item shared between all the
+ // passed-in arrays.
+ _.intersection = function(array) {
+ var rest = slice.call(arguments, 1);
+ return _.filter(_.uniq(array), function(item) {
+ return _.every(rest, function(other) {
+ return _.indexOf(other, item) >= 0;
+ });
+ });
+ };
+
+ // Take the difference between one array and a number of other arrays.
+ // Only the elements present in just the first array will remain.
+ _.difference = function(array) {
+ var rest = concat.apply(ArrayProto, slice.call(arguments, 1));
+ return _.filter(array, function(value){ return !_.contains(rest, value); });
+ };
+
+ // Zip together multiple lists into a single array -- elements that share
+ // an index go together.
+ _.zip = function() {
+ var length = _.max(_.pluck(arguments, "length").concat(0));
+ var results = new Array(length);
+ for (var i = 0; i < length; i++) {
+ results[i] = _.pluck(arguments, '' + i);
+ }
+ return results;
+ };
+
+ // Converts lists into objects. Pass either a single array of `[key, value]`
+ // pairs, or two parallel arrays of the same length -- one of keys, and one of
+ // the corresponding values.
+ _.object = function(list, values) {
+ if (list == null) return {};
+ var result = {};
+ for (var i = 0, l = list.length; i < l; i++) {
+ if (values) {
+ result[list[i]] = values[i];
+ } else {
+ result[list[i][0]] = list[i][1];
+ }
+ }
+ return result;
+ };
+
+ // If the browser doesn't supply us with indexOf (I'm looking at you, **MSIE**),
+ // we need this function. Return the position of the first occurrence of an
+ // item in an array, or -1 if the item is not included in the array.
+ // Delegates to **ECMAScript 5**'s native `indexOf` if available.
+ // If the array is large and already in sort order, pass `true`
+ // for **isSorted** to use binary search.
+ _.indexOf = function(array, item, isSorted) {
+ if (array == null) return -1;
+ var i = 0, l = array.length;
+ if (isSorted) {
+ if (typeof isSorted == 'number') {
+ i = (isSorted < 0 ? Math.max(0, l + isSorted) : isSorted);
+ } else {
+ i = _.sortedIndex(array, item);
+ return array[i] === item ? i : -1;
+ }
+ }
+ if (nativeIndexOf && array.indexOf === nativeIndexOf) return array.indexOf(item, isSorted);
+ for (; i < l; i++) if (array[i] === item) return i;
+ return -1;
+ };
+
+ // Delegates to **ECMAScript 5**'s native `lastIndexOf` if available.
+ _.lastIndexOf = function(array, item, from) {
+ if (array == null) return -1;
+ var hasIndex = from != null;
+ if (nativeLastIndexOf && array.lastIndexOf === nativeLastIndexOf) {
+ return hasIndex ? array.lastIndexOf(item, from) : array.lastIndexOf(item);
+ }
+ var i = (hasIndex ? from : array.length);
+ while (i--) if (array[i] === item) return i;
+ return -1;
+ };
+
+ // Generate an integer Array containing an arithmetic progression. A port of
+ // the native Python `range()` function. See
+ // [the Python documentation](http://docs.python.org/library/functions.html#range).
+ _.range = function(start, stop, step) {
+ if (arguments.length <= 1) {
+ stop = start || 0;
+ start = 0;
+ }
+ step = arguments[2] || 1;
+
+ var len = Math.max(Math.ceil((stop - start) / step), 0);
+ var idx = 0;
+ var range = new Array(len);
+
+ while(idx < len) {
+ range[idx++] = start;
+ start += step;
+ }
+
+ return range;
+ };
+
+ // Function (ahem) Functions
+ // ------------------
+
+ // Reusable constructor function for prototype setting.
+ var ctor = function(){};
+
+ // Create a function bound to a given object (assigning `this`, and arguments,
+ // optionally). Delegates to **ECMAScript 5**'s native `Function.bind` if
+ // available.
+ _.bind = function(func, context) {
+ var args, bound;
+ if (nativeBind && func.bind === nativeBind) return nativeBind.apply(func, slice.call(arguments, 1));
+ if (!_.isFunction(func)) throw new TypeError;
+ args = slice.call(arguments, 2);
+ return bound = function() {
+ if (!(this instanceof bound)) return func.apply(context, args.concat(slice.call(arguments)));
+ ctor.prototype = func.prototype;
+ var self = new ctor;
+ ctor.prototype = null;
+ var result = func.apply(self, args.concat(slice.call(arguments)));
+ if (Object(result) === result) return result;
+ return self;
+ };
+ };
+
+ // Partially apply a function by creating a version that has had some of its
+ // arguments pre-filled, without changing its dynamic `this` context.
+ _.partial = function(func) {
+ var args = slice.call(arguments, 1);
+ return function() {
+ return func.apply(this, args.concat(slice.call(arguments)));
+ };
+ };
+
+ // Bind all of an object's methods to that object. Useful for ensuring that
+ // all callbacks defined on an object belong to it.
+ _.bindAll = function(obj) {
+ var funcs = slice.call(arguments, 1);
+ if (funcs.length === 0) throw new Error("bindAll must be passed function names");
+ each(funcs, function(f) { obj[f] = _.bind(obj[f], obj); });
+ return obj;
+ };
+
+ // Memoize an expensive function by storing its results.
+ _.memoize = function(func, hasher) {
+ var memo = {};
+ hasher || (hasher = _.identity);
+ return function() {
+ var key = hasher.apply(this, arguments);
+ return _.has(memo, key) ? memo[key] : (memo[key] = func.apply(this, arguments));
+ };
+ };
+
+ // Delays a function for the given number of milliseconds, and then calls
+ // it with the arguments supplied.
+ _.delay = function(func, wait) {
+ var args = slice.call(arguments, 2);
+ return setTimeout(function(){ return func.apply(null, args); }, wait);
+ };
+
+ // Defers a function, scheduling it to run after the current call stack has
+ // cleared.
+ _.defer = function(func) {
+ return _.delay.apply(_, [func, 1].concat(slice.call(arguments, 1)));
+ };
+
+ // Returns a function, that, when invoked, will only be triggered at most once
+ // during a given window of time. Normally, the throttled function will run
+ // as much as it can, without ever going more than once per `wait` duration;
+ // but if you'd like to disable the execution on the leading edge, pass
+ // `{leading: false}`. To disable execution on the trailing edge, ditto.
+ _.throttle = function(func, wait, options) {
+ var context, args, result;
+ var timeout = null;
+ var previous = 0;
+ options || (options = {});
+ var later = function() {
+ previous = options.leading === false ? 0 : new Date;
+ timeout = null;
+ result = func.apply(context, args);
+ };
+ return function() {
+ var now = new Date;
+ if (!previous && options.leading === false) previous = now;
+ var remaining = wait - (now - previous);
+ context = this;
+ args = arguments;
+ if (remaining <= 0) {
+ clearTimeout(timeout);
+ timeout = null;
+ previous = now;
+ result = func.apply(context, args);
+ } else if (!timeout && options.trailing !== false) {
+ timeout = setTimeout(later, remaining);
+ }
+ return result;
+ };
+ };
+
+ // Returns a function, that, as long as it continues to be invoked, will not
+ // be triggered. The function will be called after it stops being called for
+ // N milliseconds. If `immediate` is passed, trigger the function on the
+ // leading edge, instead of the trailing.
+ _.debounce = function(func, wait, immediate) {
+ var result;
+ var timeout = null;
+ return function() {
+ var context = this, args = arguments;
+ var later = function() {
+ timeout = null;
+ if (!immediate) result = func.apply(context, args);
+ };
+ var callNow = immediate && !timeout;
+ clearTimeout(timeout);
+ timeout = setTimeout(later, wait);
+ if (callNow) result = func.apply(context, args);
+ return result;
+ };
+ };
+
+ // Returns a function that will be executed at most one time, no matter how
+ // often you call it. Useful for lazy initialization.
+ _.once = function(func) {
+ var ran = false, memo;
+ return function() {
+ if (ran) return memo;
+ ran = true;
+ memo = func.apply(this, arguments);
+ func = null;
+ return memo;
+ };
+ };
+
+ // Returns the first function passed as an argument to the second,
+ // allowing you to adjust arguments, run code before and after, and
+ // conditionally execute the original function.
+ _.wrap = function(func, wrapper) {
+ return function() {
+ var args = [func];
+ push.apply(args, arguments);
+ return wrapper.apply(this, args);
+ };
+ };
+
+ // Returns a function that is the composition of a list of functions, each
+ // consuming the return value of the function that follows.
+ _.compose = function() {
+ var funcs = arguments;
+ return function() {
+ var args = arguments;
+ for (var i = funcs.length - 1; i >= 0; i--) {
+ args = [funcs[i].apply(this, args)];
+ }
+ return args[0];
+ };
+ };
+
+ // Returns a function that will only be executed after being called N times.
+ _.after = function(times, func) {
+ return function() {
+ if (--times < 1) {
+ return func.apply(this, arguments);
+ }
+ };
+ };
+
+ // Object Functions
+ // ----------------
+
+ // Retrieve the names of an object's properties.
+ // Delegates to **ECMAScript 5**'s native `Object.keys`
+ _.keys = nativeKeys || function(obj) {
+ if (obj !== Object(obj)) throw new TypeError('Invalid object');
+ var keys = [];
+ for (var key in obj) if (_.has(obj, key)) keys.push(key);
+ return keys;
+ };
+
+ // Retrieve the values of an object's properties.
+ _.values = function(obj) {
+ var values = [];
+ for (var key in obj) if (_.has(obj, key)) values.push(obj[key]);
+ return values;
+ };
+
+ // Convert an object into a list of `[key, value]` pairs.
+ _.pairs = function(obj) {
+ var pairs = [];
+ for (var key in obj) if (_.has(obj, key)) pairs.push([key, obj[key]]);
+ return pairs;
+ };
+
+ // Invert the keys and values of an object. The values must be serializable.
+ _.invert = function(obj) {
+ var result = {};
+ for (var key in obj) if (_.has(obj, key)) result[obj[key]] = key;
+ return result;
+ };
+
+ // Return a sorted list of the function names available on the object.
+ // Aliased as `methods`
+ _.functions = _.methods = function(obj) {
+ var names = [];
+ for (var key in obj) {
+ if (_.isFunction(obj[key])) names.push(key);
+ }
+ return names.sort();
+ };
+
+ // Extend a given object with all the properties in passed-in object(s).
+ _.extend = function(obj) {
+ each(slice.call(arguments, 1), function(source) {
+ if (source) {
+ for (var prop in source) {
+ obj[prop] = source[prop];
+ }
+ }
+ });
+ return obj;
+ };
+
+ // Return a copy of the object only containing the whitelisted properties.
+ _.pick = function(obj) {
+ var copy = {};
+ var keys = concat.apply(ArrayProto, slice.call(arguments, 1));
+ each(keys, function(key) {
+ if (key in obj) copy[key] = obj[key];
+ });
+ return copy;
+ };
+
+ // Return a copy of the object without the blacklisted properties.
+ _.omit = function(obj) {
+ var copy = {};
+ var keys = concat.apply(ArrayProto, slice.call(arguments, 1));
+ for (var key in obj) {
+ if (!_.contains(keys, key)) copy[key] = obj[key];
+ }
+ return copy;
+ };
+
+ // Fill in a given object with default properties.
+ _.defaults = function(obj) {
+ each(slice.call(arguments, 1), function(source) {
+ if (source) {
+ for (var prop in source) {
+ if (obj[prop] === void 0) obj[prop] = source[prop];
+ }
+ }
+ });
+ return obj;
+ };
+
+ // Create a (shallow-cloned) duplicate of an object.
+ _.clone = function(obj) {
+ if (!_.isObject(obj)) return obj;
+ return _.isArray(obj) ? obj.slice() : _.extend({}, obj);
+ };
+
+ // Invokes interceptor with the obj, and then returns obj.
+ // The primary purpose of this method is to "tap into" a method chain, in
+ // order to perform operations on intermediate results within the chain.
+ _.tap = function(obj, interceptor) {
+ interceptor(obj);
+ return obj;
+ };
+
+ // Internal recursive comparison function for `isEqual`.
+ var eq = function(a, b, aStack, bStack) {
+ // Identical objects are equal. `0 === -0`, but they aren't identical.
+ // See the [Harmony `egal` proposal](http://wiki.ecmascript.org/doku.php?id=harmony:egal).
+ if (a === b) return a !== 0 || 1 / a == 1 / b;
+ // A strict comparison is necessary because `null == undefined`.
+ if (a == null || b == null) return a === b;
+ // Unwrap any wrapped objects.
+ if (a instanceof _) a = a._wrapped;
+ if (b instanceof _) b = b._wrapped;
+ // Compare `[[Class]]` names.
+ var className = toString.call(a);
+ if (className != toString.call(b)) return false;
+ switch (className) {
+ // Strings, numbers, dates, and booleans are compared by value.
+ case '[object String]':
+ // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is
+ // equivalent to `new String("5")`.
+ return a == String(b);
+ case '[object Number]':
+ // `NaN`s are equivalent, but non-reflexive. An `egal` comparison is performed for
+ // other numeric values.
+ return a != +a ? b != +b : (a == 0 ? 1 / a == 1 / b : a == +b);
+ case '[object Date]':
+ case '[object Boolean]':
+ // Coerce dates and booleans to numeric primitive values. Dates are compared by their
+ // millisecond representations. Note that invalid dates with millisecond representations
+ // of `NaN` are not equivalent.
+ return +a == +b;
+ // RegExps are compared by their source patterns and flags.
+ case '[object RegExp]':
+ return a.source == b.source &&
+ a.global == b.global &&
+ a.multiline == b.multiline &&
+ a.ignoreCase == b.ignoreCase;
+ }
+ if (typeof a != 'object' || typeof b != 'object') return false;
+ // Assume equality for cyclic structures. The algorithm for detecting cyclic
+ // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.
+ var length = aStack.length;
+ while (length--) {
+ // Linear search. Performance is inversely proportional to the number of
+ // unique nested structures.
+ if (aStack[length] == a) return bStack[length] == b;
+ }
+ // Objects with different constructors are not equivalent, but `Object`s
+ // from different frames are.
+ var aCtor = a.constructor, bCtor = b.constructor;
+ if (aCtor !== bCtor && !(_.isFunction(aCtor) && (aCtor instanceof aCtor) &&
+ _.isFunction(bCtor) && (bCtor instanceof bCtor))) {
+ return false;
+ }
+ // Add the first object to the stack of traversed objects.
+ aStack.push(a);
+ bStack.push(b);
+ var size = 0, result = true;
+ // Recursively compare objects and arrays.
+ if (className == '[object Array]') {
+ // Compare array lengths to determine if a deep comparison is necessary.
+ size = a.length;
+ result = size == b.length;
+ if (result) {
+ // Deep compare the contents, ignoring non-numeric properties.
+ while (size--) {
+ if (!(result = eq(a[size], b[size], aStack, bStack))) break;
+ }
+ }
+ } else {
+ // Deep compare objects.
+ for (var key in a) {
+ if (_.has(a, key)) {
+ // Count the expected number of properties.
+ size++;
+ // Deep compare each member.
+ if (!(result = _.has(b, key) && eq(a[key], b[key], aStack, bStack))) break;
+ }
+ }
+ // Ensure that both objects contain the same number of properties.
+ if (result) {
+ for (key in b) {
+ if (_.has(b, key) && !(size--)) break;
+ }
+ result = !size;
+ }
+ }
+ // Remove the first object from the stack of traversed objects.
+ aStack.pop();
+ bStack.pop();
+ return result;
+ };
+
+ // Perform a deep comparison to check if two objects are equal.
+ _.isEqual = function(a, b) {
+ return eq(a, b, [], []);
+ };
+
+ // Is a given array, string, or object empty?
+ // An "empty" object has no enumerable own-properties.
+ _.isEmpty = function(obj) {
+ if (obj == null) return true;
+ if (_.isArray(obj) || _.isString(obj)) return obj.length === 0;
+ for (var key in obj) if (_.has(obj, key)) return false;
+ return true;
+ };
+
+ // Is a given value a DOM element?
+ _.isElement = function(obj) {
+ return !!(obj && obj.nodeType === 1);
+ };
+
+ // Is a given value an array?
+ // Delegates to ECMA5's native Array.isArray
+ _.isArray = nativeIsArray || function(obj) {
+ return toString.call(obj) == '[object Array]';
+ };
+
+ // Is a given variable an object?
+ _.isObject = function(obj) {
+ return obj === Object(obj);
+ };
+
+ // Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp.
+ each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp'], function(name) {
+ _['is' + name] = function(obj) {
+ return toString.call(obj) == '[object ' + name + ']';
+ };
+ });
+
+ // Define a fallback version of the method in browsers (ahem, IE), where
+ // there isn't any inspectable "Arguments" type.
+ if (!_.isArguments(arguments)) {
+ _.isArguments = function(obj) {
+ return !!(obj && _.has(obj, 'callee'));
+ };
+ }
+
+ // Optimize `isFunction` if appropriate.
+ if (typeof (/./) !== 'function') {
+ _.isFunction = function(obj) {
+ return typeof obj === 'function';
+ };
+ }
+
+ // Is a given object a finite number?
+ _.isFinite = function(obj) {
+ return isFinite(obj) && !isNaN(parseFloat(obj));
+ };
+
+ // Is the given value `NaN`? (NaN is the only number which does not equal itself).
+ _.isNaN = function(obj) {
+ return _.isNumber(obj) && obj != +obj;
+ };
+
+ // Is a given value a boolean?
+ _.isBoolean = function(obj) {
+ return obj === true || obj === false || toString.call(obj) == '[object Boolean]';
+ };
+
+ // Is a given value equal to null?
+ _.isNull = function(obj) {
+ return obj === null;
+ };
+
+ // Is a given variable undefined?
+ _.isUndefined = function(obj) {
+ return obj === void 0;
+ };
+
+ // Shortcut function for checking if an object has a given property directly
+ // on itself (in other words, not on a prototype).
+ _.has = function(obj, key) {
+ return hasOwnProperty.call(obj, key);
+ };
+
+ // Utility Functions
+ // -----------------
+
+ // Run Underscore.js in *noConflict* mode, returning the `_` variable to its
+ // previous owner. Returns a reference to the Underscore object.
+ _.noConflict = function() {
+ root._ = previousUnderscore;
+ return this;
+ };
+
+ // Keep the identity function around for default iterators.
+ _.identity = function(value) {
+ return value;
+ };
+
+ // Run a function **n** times.
+ _.times = function(n, iterator, context) {
+ var accum = Array(Math.max(0, n));
+ for (var i = 0; i < n; i++) accum[i] = iterator.call(context, i);
+ return accum;
+ };
+
+ // Return a random integer between min and max (inclusive).
+ _.random = function(min, max) {
+ if (max == null) {
+ max = min;
+ min = 0;
+ }
+ return min + Math.floor(Math.random() * (max - min + 1));
+ };
+
+ // List of HTML entities for escaping.
+ var entityMap = {
+ escape: {
+ '&': '&',
+ '<': '<',
+ '>': '>',
+ '"': '"',
+ "'": ''',
+ '/': '/'
+ }
+ };
+ entityMap.unescape = _.invert(entityMap.escape);
+
+ // Regexes containing the keys and values listed immediately above.
+ var entityRegexes = {
+ escape: new RegExp('[' + _.keys(entityMap.escape).join('') + ']', 'g'),
+ unescape: new RegExp('(' + _.keys(entityMap.unescape).join('|') + ')', 'g')
+ };
+
+ // Functions for escaping and unescaping strings to/from HTML interpolation.
+ _.each(['escape', 'unescape'], function(method) {
+ _[method] = function(string) {
+ if (string == null) return '';
+ return ('' + string).replace(entityRegexes[method], function(match) {
+ return entityMap[method][match];
+ });
+ };
+ });
+
+ // If the value of the named `property` is a function then invoke it with the
+ // `object` as context; otherwise, return it.
+ _.result = function(object, property) {
+ if (object == null) return void 0;
+ var value = object[property];
+ return _.isFunction(value) ? value.call(object) : value;
+ };
+
+ // Add your own custom functions to the Underscore object.
+ _.mixin = function(obj) {
+ each(_.functions(obj), function(name){
+ var func = _[name] = obj[name];
+ _.prototype[name] = function() {
+ var args = [this._wrapped];
+ push.apply(args, arguments);
+ return result.call(this, func.apply(_, args));
+ };
+ });
+ };
+
+ // Generate a unique integer id (unique within the entire client session).
+ // Useful for temporary DOM ids.
+ var idCounter = 0;
+ _.uniqueId = function(prefix) {
+ var id = ++idCounter + '';
+ return prefix ? prefix + id : id;
+ };
+
+ // By default, Underscore uses ERB-style template delimiters, change the
+ // following template settings to use alternative delimiters.
+ _.templateSettings = {
+ evaluate : /<%([\s\S]+?)%>/g,
+ interpolate : /<%=([\s\S]+?)%>/g,
+ escape : /<%-([\s\S]+?)%>/g
+ };
+
+ // When customizing `templateSettings`, if you don't want to define an
+ // interpolation, evaluation or escaping regex, we need one that is
+ // guaranteed not to match.
+ var noMatch = /(.)^/;
+
+ // Certain characters need to be escaped so that they can be put into a
+ // string literal.
+ var escapes = {
+ "'": "'",
+ '\\': '\\',
+ '\r': 'r',
+ '\n': 'n',
+ '\t': 't',
+ '\u2028': 'u2028',
+ '\u2029': 'u2029'
+ };
+
+ var escaper = /\\|'|\r|\n|\t|\u2028|\u2029/g;
+
+ // JavaScript micro-templating, similar to John Resig's implementation.
+ // Underscore templating handles arbitrary delimiters, preserves whitespace,
+ // and correctly escapes quotes within interpolated code.
+ _.template = function(text, data, settings) {
+ var render;
+ settings = _.defaults({}, settings, _.templateSettings);
+
+ // Combine delimiters into one regular expression via alternation.
+ var matcher = new RegExp([
+ (settings.escape || noMatch).source,
+ (settings.interpolate || noMatch).source,
+ (settings.evaluate || noMatch).source
+ ].join('|') + '|$', 'g');
+
+ // Compile the template source, escaping string literals appropriately.
+ var index = 0;
+ var source = "__p+='";
+ text.replace(matcher, function(match, escape, interpolate, evaluate, offset) {
+ source += text.slice(index, offset)
+ .replace(escaper, function(match) { return '\\' + escapes[match]; });
+
+ if (escape) {
+ source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'";
+ }
+ if (interpolate) {
+ source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'";
+ }
+ if (evaluate) {
+ source += "';\n" + evaluate + "\n__p+='";
+ }
+ index = offset + match.length;
+ return match;
+ });
+ source += "';\n";
+
+ // If a variable is not specified, place data values in local scope.
+ if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n';
+
+ source = "var __t,__p='',__j=Array.prototype.join," +
+ "print=function(){__p+=__j.call(arguments,'');};\n" +
+ source + "return __p;\n";
+
+ try {
+ render = new Function(settings.variable || 'obj', '_', source);
+ } catch (e) {
+ e.source = source;
+ throw e;
+ }
+
+ if (data) return render(data, _);
+ var template = function(data) {
+ return render.call(this, data, _);
+ };
+
+ // Provide the compiled function source as a convenience for precompilation.
+ template.source = 'function(' + (settings.variable || 'obj') + '){\n' + source + '}';
+
+ return template;
+ };
+
+ // Add a "chain" function, which will delegate to the wrapper.
+ _.chain = function(obj) {
+ return _(obj).chain();
+ };
+
+ // OOP
+ // ---------------
+ // If Underscore is called as a function, it returns a wrapped object that
+ // can be used OO-style. This wrapper holds altered versions of all the
+ // underscore functions. Wrapped objects may be chained.
+
+ // Helper function to continue chaining intermediate results.
+ var result = function(obj) {
+ return this._chain ? _(obj).chain() : obj;
+ };
+
+ // Add all of the Underscore functions to the wrapper object.
+ _.mixin(_);
+
+ // Add all mutator Array functions to the wrapper.
+ each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) {
+ var method = ArrayProto[name];
+ _.prototype[name] = function() {
+ var obj = this._wrapped;
+ method.apply(obj, arguments);
+ if ((name == 'shift' || name == 'splice') && obj.length === 0) delete obj[0];
+ return result.call(this, obj);
+ };
+ });
+
+ // Add all accessor Array functions to the wrapper.
+ each(['concat', 'join', 'slice'], function(name) {
+ var method = ArrayProto[name];
+ _.prototype[name] = function() {
+ return result.call(this, method.apply(this._wrapped, arguments));
+ };
+ });
+
+ _.extend(_.prototype, {
+
+ // Start chaining a wrapped Underscore object.
+ chain: function() {
+ this._chain = true;
+ return this;
+ },
+
+ // Extracts the result from a wrapped and chained object.
+ value: function() {
+ return this._wrapped;
+ }
+
+ });
+
+}).call(this);
diff --git a/mvnw b/mvnw
deleted file mode 100755
index ee316a27..00000000
--- a/mvnw
+++ /dev/null
@@ -1,245 +0,0 @@
-#!/bin/sh
-# ----------------------------------------------------------------------------
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-# ----------------------------------------------------------------------------
-
-# ----------------------------------------------------------------------------
-# Maven2 Start Up Batch script
-#
-# Required ENV vars:
-# ------------------
-# JAVA_HOME - location of a JDK home dir
-#
-# Optional ENV vars
-# -----------------
-# M2_HOME - location of maven2's installed home dir
-# MAVEN_OPTS - parameters passed to the Java VM when running Maven
-# e.g. to debug Maven itself, use
-# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
-# MAVEN_SKIP_RC - flag to disable loading of mavenrc files
-# ----------------------------------------------------------------------------
-
-if [ -z "$MAVEN_SKIP_RC" ] ; then
-
- if [ -f /etc/mavenrc ] ; then
- . /etc/mavenrc
- fi
-
- if [ -f "$HOME/.mavenrc" ] ; then
- . "$HOME/.mavenrc"
- fi
-
-fi
-
-# OS specific support. $var _must_ be set to either true or false.
-cygwin=false;
-darwin=false;
-mingw=false
-case "`uname`" in
- CYGWIN*) cygwin=true ;;
- MINGW*) mingw=true;;
- Darwin*) darwin=true
- #
- # Look for the Apple JDKs first to preserve the existing behaviour, and then look
- # for the new JDKs provided by Oracle.
- #
- if [ -z "$JAVA_HOME" ] && [ -L /System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK ] ; then
- #
- # Apple JDKs
- #
- export JAVA_HOME=/System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Home
- fi
-
- if [ -z "$JAVA_HOME" ] && [ -L /System/Library/Java/JavaVirtualMachines/CurrentJDK ] ; then
- #
- # Apple JDKs
- #
- export JAVA_HOME=/System/Library/Java/JavaVirtualMachines/CurrentJDK/Contents/Home
- fi
-
- if [ -z "$JAVA_HOME" ] && [ -L "/Library/Java/JavaVirtualMachines/CurrentJDK" ] ; then
- #
- # Oracle JDKs
- #
- export JAVA_HOME=/Library/Java/JavaVirtualMachines/CurrentJDK/Contents/Home
- fi
-
- if [ -z "$JAVA_HOME" ] && [ -x "/usr/libexec/java_home" ]; then
- #
- # Apple JDKs
- #
- export JAVA_HOME=`/usr/libexec/java_home`
- fi
- ;;
-esac
-
-if [ -z "$JAVA_HOME" ] ; then
- if [ -r /etc/gentoo-release ] ; then
- JAVA_HOME=`java-config --jre-home`
- fi
-fi
-
-if [ -z "$M2_HOME" ] ; then
- ## resolve links - $0 may be a link to maven's home
- PRG="$0"
-
- # need this for relative symlinks
- while [ -h "$PRG" ] ; do
- ls=`ls -ld "$PRG"`
- link=`expr "$ls" : '.*-> \(.*\)$'`
- if expr "$link" : '/.*' > /dev/null; then
- PRG="$link"
- else
- PRG="`dirname "$PRG"`/$link"
- fi
- done
-
- saveddir=`pwd`
-
- M2_HOME=`dirname "$PRG"`/..
-
- # make it fully qualified
- M2_HOME=`cd "$M2_HOME" && pwd`
-
- cd "$saveddir"
- # echo Using m2 at $M2_HOME
-fi
-
-# For Cygwin, ensure paths are in UNIX format before anything is touched
-if $cygwin ; then
- [ -n "$M2_HOME" ] &&
- M2_HOME=`cygpath --unix "$M2_HOME"`
- [ -n "$JAVA_HOME" ] &&
- JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
- [ -n "$CLASSPATH" ] &&
- CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
-fi
-
-# For Migwn, ensure paths are in UNIX format before anything is touched
-if $mingw ; then
- [ -n "$M2_HOME" ] &&
- M2_HOME="`(cd "$M2_HOME"; pwd)`"
- [ -n "$JAVA_HOME" ] &&
- JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
- # TODO classpath?
-fi
-
-if [ -z "$JAVA_HOME" ]; then
- javaExecutable="`which javac`"
- if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
- # readlink(1) is not available as standard on Solaris 10.
- readLink=`which readlink`
- if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
- if $darwin ; then
- javaHome="`dirname \"$javaExecutable\"`"
- javaExecutable="`cd \"$javaHome\" && pwd -P`/javac"
- else
- javaExecutable="`readlink -f \"$javaExecutable\"`"
- fi
- javaHome="`dirname \"$javaExecutable\"`"
- javaHome=`expr "$javaHome" : '\(.*\)/bin'`
- JAVA_HOME="$javaHome"
- export JAVA_HOME
- fi
- fi
-fi
-
-if [ -z "$JAVACMD" ] ; then
- if [ -n "$JAVA_HOME" ] ; then
- if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
- # IBM's JDK on AIX uses strange locations for the executables
- JAVACMD="$JAVA_HOME/jre/sh/java"
- else
- JAVACMD="$JAVA_HOME/bin/java"
- fi
- else
- JAVACMD="`which java`"
- fi
-fi
-
-if [ ! -x "$JAVACMD" ] ; then
- echo "Error: JAVA_HOME is not defined correctly." >&2
- echo " We cannot execute $JAVACMD" >&2
- exit 1
-fi
-
-if [ -z "$JAVA_HOME" ] ; then
- echo "Warning: JAVA_HOME environment variable is not set."
-fi
-
-CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
-
-# For Cygwin, switch paths to Windows format before running java
-if $cygwin; then
- [ -n "$M2_HOME" ] &&
- M2_HOME=`cygpath --path --windows "$M2_HOME"`
- [ -n "$JAVA_HOME" ] &&
- JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
- [ -n "$CLASSPATH" ] &&
- CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
-fi
-
-# traverses directory structure from process work directory to filesystem root
-# first directory with .mvn subdirectory is considered project base directory
-find_maven_basedir() {
- local basedir=$(pwd)
- local wdir=$(pwd)
- while [ "$wdir" != '/' ] ; do
- if [ -d "$wdir"/.mvn ] ; then
- basedir=$wdir
- break
- fi
- wdir=$(cd "$wdir/.."; pwd)
- done
- echo "${basedir}"
-}
-
-# concatenates all lines of a file
-concat_lines() {
- if [ -f "$1" ]; then
- echo "$(tr -s '\n' ' ' < "$1")"
- fi
-}
-
-export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-$(find_maven_basedir)}
-MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
-
-# Provide a "standardized" way to retrieve the CLI args that will
-# work with both Windows and non-Windows executions.
-MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@"
-export MAVEN_CMD_LINE_ARGS
-
-WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
-
-echo "Running version check"
-VERSION=$( sed '\!
//' -e 's!.*$!!' )
-echo "The found version is [${VERSION}]"
-
-if echo $VERSION | egrep -q 'M|RC'; then
- echo Activating \"milestone\" profile for version=\"$VERSION\"
- echo $MAVEN_ARGS | grep -q milestone || MAVEN_ARGS="$MAVEN_ARGS -Pmilestone"
-else
- echo Deactivating \"milestone\" profile for version=\"$VERSION\"
- echo $MAVEN_ARGS | grep -q milestone && MAVEN_ARGS=$(echo $MAVEN_ARGS | sed -e 's/-Pmilestone//')
-fi
-
-exec "$JAVACMD" \
- $MAVEN_OPTS \
- -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
- "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
- ${WRAPPER_LAUNCHER} ${MAVEN_ARGS} "$@"
diff --git a/mvnw.cmd b/mvnw.cmd
deleted file mode 100644
index 2b934e89..00000000
--- a/mvnw.cmd
+++ /dev/null
@@ -1,145 +0,0 @@
-@REM ----------------------------------------------------------------------------
-@REM Licensed to the Apache Software Foundation (ASF) under one
-@REM or more contributor license agreements. See the NOTICE file
-@REM distributed with this work for additional information
-@REM regarding copyright ownership. The ASF licenses this file
-@REM to you under the Apache License, Version 2.0 (the
-@REM "License"); you may not use this file except in compliance
-@REM with the License. You may obtain a copy of the License at
-@REM
-@REM http://www.apache.org/licenses/LICENSE-2.0
-@REM
-@REM Unless required by applicable law or agreed to in writing,
-@REM software distributed under the License is distributed on an
-@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-@REM KIND, either express or implied. See the License for the
-@REM specific language governing permissions and limitations
-@REM under the License.
-@REM ----------------------------------------------------------------------------
-
-@REM ----------------------------------------------------------------------------
-@REM Maven2 Start Up Batch script
-@REM
-@REM Required ENV vars:
-@REM JAVA_HOME - location of a JDK home dir
-@REM
-@REM Optional ENV vars
-@REM M2_HOME - location of maven2's installed home dir
-@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
-@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending
-@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
-@REM e.g. to debug Maven itself, use
-@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
-@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
-@REM ----------------------------------------------------------------------------
-
-@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
-@echo off
-@REM enable echoing my setting MAVEN_BATCH_ECHO to 'on'
-@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
-
-@REM set %HOME% to equivalent of $HOME
-if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
-
-@REM Execute a user defined script before this one
-if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
-@REM check for pre script, once with legacy .bat ending and once with .cmd ending
-if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat"
-if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd"
-:skipRcPre
-
-@setlocal
-
-set ERROR_CODE=0
-
-@REM To isolate internal variables from possible post scripts, we use another setlocal
-@setlocal
-
-@REM ==== START VALIDATION ====
-if not "%JAVA_HOME%" == "" goto OkJHome
-
-echo.
-echo Error: JAVA_HOME not found in your environment. >&2
-echo Please set the JAVA_HOME variable in your environment to match the >&2
-echo location of your Java installation. >&2
-echo.
-goto error
-
-:OkJHome
-if exist "%JAVA_HOME%\bin\java.exe" goto init
-
-echo.
-echo Error: JAVA_HOME is set to an invalid directory. >&2
-echo JAVA_HOME = "%JAVA_HOME%" >&2
-echo Please set the JAVA_HOME variable in your environment to match the >&2
-echo location of your Java installation. >&2
-echo.
-goto error
-
-@REM ==== END VALIDATION ====
-
-:init
-
-set MAVEN_CMD_LINE_ARGS=%*
-
-@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
-@REM Fallback to current working directory if not found.
-
-set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
-IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
-
-set EXEC_DIR=%CD%
-set WDIR=%EXEC_DIR%
-:findBaseDir
-IF EXIST "%WDIR%"\.mvn goto baseDirFound
-cd ..
-IF "%WDIR%"=="%CD%" goto baseDirNotFound
-set WDIR=%CD%
-goto findBaseDir
-
-:baseDirFound
-set MAVEN_PROJECTBASEDIR=%WDIR%
-cd "%EXEC_DIR%"
-goto endDetectBaseDir
-
-:baseDirNotFound
-set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
-cd "%EXEC_DIR%"
-
-:endDetectBaseDir
-
-IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
-
-@setlocal EnableExtensions EnableDelayedExpansion
-for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
-@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
-
-:endReadAdditionalConfig
-
-SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
-
-set WRAPPER_JAR="".\.mvn\wrapper\maven-wrapper.jar""
-set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
-
-%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CMD_LINE_ARGS%
-if ERRORLEVEL 1 goto error
-goto end
-
-:error
-set ERROR_CODE=1
-
-:end
-@endlocal & set ERROR_CODE=%ERROR_CODE%
-
-if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost
-@REM check for post script, once with legacy .bat ending and once with .cmd ending
-if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat"
-if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd"
-:skipRcPost
-
-@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
-if "%MAVEN_BATCH_PAUSE%" == "on" pause
-
-if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE%
-
-exit /B %ERROR_CODE%
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
deleted file mode 100644
index 71e29156..00000000
--- a/pom.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-
-
- 4.0.0
-
- org.springframework.cloud.internal
- spring-cloud-release-tools-parent
- 1.0.0.M1
- pom
-
-
- org.springframework.cloud
- spring-cloud-build
- 1.2.2.RELEASE
-
-
-
-
-
- docs
- spring-cloud-release-tools-core
- spring-cloud-release-tools-spring
-
-
-
diff --git a/project-icon.md b/project-icon.md
new file mode 100644
index 00000000..56c63683
--- /dev/null
+++ b/project-icon.md
@@ -0,0 +1 @@
+{{include.link | markdownify }}
diff --git a/spring-cloud-release-tools-core/pom.xml b/spring-cloud-release-tools-core/pom.xml
deleted file mode 100644
index 1ae9ef17..00000000
--- a/spring-cloud-release-tools-core/pom.xml
+++ /dev/null
@@ -1,113 +0,0 @@
-
-
- 4.0.0
-
- org.springframework.cloud.internal
- spring-cloud-release-tools-core
- 1.0.0.M1
- jar
-
-
- org.springframework.cloud
- spring-cloud-build
- 1.2.2.RELEASE
-
-
-
-
-
- UTF-8
- 1.8
-
-
-
-
- org.springframework.boot
- spring-boot-starter
-
-
- org.eclipse.jgit
- org.eclipse.jgit
- 4.6.0.201612231935-r
-
-
- org.apache.maven
- maven-model
-
-
- 2.2.1
-
-
- org.codehaus.mojo
- versions-maven-plugin
- 2.3
-
-
- org.slf4j
- slf4j-jdk14
-
-
- org.slf4j
- jcl-over-slf4j
-
-
- org.slf4j
- slf4j-nop
-
-
-
-
- org.springframework.boot
- spring-boot-starter-test
- test
-
-
-
-
-
- sonar
-
-
-
- org.jacoco
- jacoco-maven-plugin
-
-
- pre-unit-test
-
- prepare-agent
-
-
- surefireArgLine
- ${project.build.directory}/jacoco.exec
-
-
-
- post-unit-test
- test
-
- report
-
-
-
- ${project.build.directory}/jacoco.exec
-
-
-
-
-
- org.apache.maven.plugins
- maven-surefire-plugin
-
-
- ${surefireArgLine}
-
-
-
-
-
-
-
-
diff --git a/spring-cloud-release-tools-core/src/main/java/org/springframework/cloud/release/internal/Releaser.java b/spring-cloud-release-tools-core/src/main/java/org/springframework/cloud/release/internal/Releaser.java
deleted file mode 100644
index d50905ad..00000000
--- a/spring-cloud-release-tools-core/src/main/java/org/springframework/cloud/release/internal/Releaser.java
+++ /dev/null
@@ -1,47 +0,0 @@
-package org.springframework.cloud.release.internal;
-
-import java.io.File;
-import java.io.IOException;
-import java.lang.invoke.MethodHandles;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.cloud.release.internal.build.ProjectBuilder;
-import org.springframework.cloud.release.internal.pom.ProjectUpdater;
-import org.springframework.util.StringUtils;
-
-/**
- * @author Marcin Grzejszczak
- */
-public class Releaser {
- private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
-
- private final ReleaserProperties properties;
- private final ProjectUpdater projectUpdater;
- private final ProjectBuilder projectBuilder;
-
- public Releaser(ReleaserProperties properties,
- ProjectUpdater projectUpdater, ProjectBuilder projectBuilder) {
- this.properties = properties;
- this.projectUpdater = projectUpdater;
- this.projectBuilder = projectBuilder;
- }
-
- public void release() {
- try {
- String workingDir = StringUtils.hasText(this.properties.getWorkingDir()) ?
- this.properties.getWorkingDir() : System.getProperty("user.dir");
- log.info("\n\n\n=== UPDATING POMS ===\n\nWill run the application for root folder [{}]", workingDir);
- this.projectUpdater.updateProject(new File(workingDir));
- log.info("\n\nProject was successfully updated");
- log.info("\n\n\n=== BUILD PROJECT ===\n\nPress ENTER to build the project\n\n");
- System.in.read();
- this.projectBuilder.build();
- log.info("\nProject was successfully built");
- log.info("\n\n\n=== COMMITTING AND PUSHING TAGS ===\n\nPress ENTER to commit, tag and push the tag\n\n");
- System.in.read();
- } catch (IOException e) {
- throw new IllegalStateException(e);
- }
- }
-}
diff --git a/spring-cloud-release-tools-core/src/main/java/org/springframework/cloud/release/internal/ReleaserProperties.java b/spring-cloud-release-tools-core/src/main/java/org/springframework/cloud/release/internal/ReleaserProperties.java
deleted file mode 100644
index 6243efcf..00000000
--- a/spring-cloud-release-tools-core/src/main/java/org/springframework/cloud/release/internal/ReleaserProperties.java
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- * Copyright 2013-2017 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.springframework.cloud.release.internal;
-
-import java.util.List;
-
-import org.springframework.boot.context.properties.ConfigurationProperties;
-
-import edu.emory.mathcs.backport.java.util.Arrays;
-
-/**
- * @author Marcin Grzejszczak
- */
-@ConfigurationProperties("releaser")
-public class ReleaserProperties {
-
- /**
- * By default Releaser assumes running the program from the current working directory.
- * If you want to change this behaviour - just change this value.
- */
- private String workingDir;
-
- private Pom pom = new Pom();
-
- private Build build = new Build();
-
- public static class Pom {
- /**
- * URL to Spring Cloud Release Git repository
- */
- private String springCloudReleaseGitUrl = "https://github.com/spring-cloud/spring-cloud-release";
-
- /**
- * Where should the Spring Cloud Release repo get cloned to. If {@code null} defaults to a temporary directory
- */
- private String cloneDestinationDir;
-
- /**
- * Which branch of Spring Cloud Release should be checked out. Defaults to {@code master}
- */
- private String branch = "master";
-
- /**
- * List of regular expressions of ignored poms. Defaults to test projects and samples.
- */
- @SuppressWarnings("unchecked")
- private List ignoredPomRegex = Arrays.asList(new String[] {
- "^.*spring-cloud-contract-maven-plugin/src/test/projects/.*$",
- "^.*samples/standalone.*$"
- });
-
- public String getSpringCloudReleaseGitUrl() {
- return this.springCloudReleaseGitUrl;
- }
-
- public void setSpringCloudReleaseGitUrl(String springCloudReleaseGitUrl) {
- this.springCloudReleaseGitUrl = springCloudReleaseGitUrl;
- }
-
- public String getCloneDestinationDir() {
- return this.cloneDestinationDir;
- }
-
- public void setCloneDestinationDir(String cloneDestinationDir) {
- this.cloneDestinationDir = cloneDestinationDir;
- }
-
- public String getBranch() {
- return this.branch;
- }
-
- public void setBranch(String branch) {
- this.branch = branch;
- }
-
- public List getIgnoredPomRegex() {
- return this.ignoredPomRegex;
- }
-
- public void setIgnoredPomRegex(List ignoredPomRegex) {
- this.ignoredPomRegex = ignoredPomRegex;
- }
- }
-
- public static class Build {
-
- /**
- * Command to be executed to build the project
- */
- private String command = "./mvnw clean install -Pdocs";
-
- /**
- * Max wait time in minutes for the build to finish
- */
- private long waitTimeInMinutes = 20;
-
- public String getCommand() {
- return this.command;
- }
-
- public void setCommand(String command) {
- this.command = command;
- }
-
- public long getWaitTimeInMinutes() {
- return this.waitTimeInMinutes;
- }
-
- public void setWaitTimeInMinutes(long waitTimeInMinutes) {
- this.waitTimeInMinutes = waitTimeInMinutes;
- }
- }
-
- public String getWorkingDir() {
- return this.workingDir;
- }
-
- public void setWorkingDir(String workingDir) {
- this.workingDir = workingDir;
- }
-
- public Pom getPom() {
- return this.pom;
- }
-
- public void setPom(Pom pom) {
- this.pom = pom;
- }
-
- public Build getBuild() {
- return this.build;
- }
-
- public void setBuild(Build build) {
- this.build = build;
- }
-}
diff --git a/spring-cloud-release-tools-core/src/main/java/org/springframework/cloud/release/internal/pom/GitProjectRepo.java b/spring-cloud-release-tools-core/src/main/java/org/springframework/cloud/release/internal/pom/GitProjectRepo.java
deleted file mode 100644
index f0205a79..00000000
--- a/spring-cloud-release-tools-core/src/main/java/org/springframework/cloud/release/internal/pom/GitProjectRepo.java
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * Copyright 2013-2017 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.springframework.cloud.release.internal.pom;
-
-import java.io.File;
-import java.io.IOException;
-import java.lang.invoke.MethodHandles;
-import java.net.URI;
-import java.util.List;
-
-import org.eclipse.jgit.api.CheckoutCommand;
-import org.eclipse.jgit.api.CloneCommand;
-import org.eclipse.jgit.api.CreateBranchCommand;
-import org.eclipse.jgit.api.Git;
-import org.eclipse.jgit.api.ListBranchCommand;
-import org.eclipse.jgit.api.errors.GitAPIException;
-import org.eclipse.jgit.lib.Ref;
-import org.eclipse.jgit.util.FileUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Abstraction over a Git repo. Can clonea repo from a given location
- * and check its branch.
- *
- * @author Marcin Grzejszczak
- */
-class GitProjectRepo {
-
- private static final Logger log = LoggerFactory
- .getLogger(MethodHandles.lookup().lookupClass());
-
- private final GitProjectRepo.JGitFactory gitFactory;
-
- private final File basedir;
-
- GitProjectRepo(File basedir) {
- this.basedir = basedir;
- this.gitFactory = new GitProjectRepo.JGitFactory();
- }
-
- GitProjectRepo(File basedir, GitProjectRepo.JGitFactory factory) {
- this.basedir = basedir;
- this.gitFactory = factory;
- }
-
- /**
- * Clones the project
- * @param projectUri - URI of the project
- * @return file where the project was cloned
- */
- File cloneProject(URI projectUri) {
- try {
- log.info("Cloning repo from [{}] to [{}]", projectUri, this.basedir);
- Git git = cloneToBasedir(projectUri, this.basedir);
- if (git != null) {
- git.close();
- }
- File clonedRepo = git.getRepository().getWorkTree();
- log.info("Cloned repo to [{}]", clonedRepo);
- return clonedRepo;
- }
- catch (Exception e) {
- throw new IllegalStateException("Exception occurred while cloning repo", e);
- }
- }
-
- /**
- * Checks out a branch for a project
- * @param project - a Git project
- * @param branch - branch to check out
- */
- void checkout(File project, String branch) {
- try {
- log.info("Checking out branch [{}] for repo [{}] to [{}]", this.basedir, branch);
- checkoutBranch(project, branch);
- log.info("Successfully checked out the branch [{}]", branch);
- }
- catch (Exception e) {
- throw new IllegalStateException(e);
- }
- }
-
- private Git cloneToBasedir(URI projectUrl, File destinationFolder)
- throws GitAPIException {
- CloneCommand command = this.gitFactory.getCloneCommandByCloneRepository()
- .setURI(projectUrl.toString() + ".git").setDirectory(destinationFolder);
- try {
- return command.call();
- }
- catch (GitAPIException e) {
- deleteBaseDirIfExists();
- throw e;
- }
- }
-
- private Ref checkoutBranch(File projectDir, String branch)
- throws GitAPIException {
- Git git = this.gitFactory.open(projectDir);
- CheckoutCommand command = git.checkout().setName(branch);
- try {
- if (shouldTrack(git, branch)) {
- trackBranch(command, branch);
- }
- return command.call();
- }
- catch (GitAPIException e) {
- deleteBaseDirIfExists();
- throw e;
- } finally {
- git.close();
- }
- }
-
- private boolean shouldTrack(Git git, String label) throws GitAPIException {
- return isBranch(git, label) && !isLocalBranch(git, label);
- }
-
- private void trackBranch(CheckoutCommand checkout, String label) {
- checkout.setCreateBranch(true).setName(label)
- .setUpstreamMode(CreateBranchCommand.SetupUpstreamMode.TRACK)
- .setStartPoint("origin/" + label);
- }
-
- private boolean isBranch(Git git, String label) throws GitAPIException {
- return containsBranch(git, label, ListBranchCommand.ListMode.ALL);
- }
-
- private boolean isLocalBranch(Git git, String label) throws GitAPIException {
- return containsBranch(git, label, null);
- }
-
- private boolean containsBranch(Git git, String label, ListBranchCommand.ListMode listMode)
- throws GitAPIException {
- ListBranchCommand command = git.branchList();
- if (listMode != null) {
- command.setListMode(listMode);
- }
- List[ branches = command.call();
- for (Ref ref : branches) {
- if (ref.getName().endsWith("/" + label)) {
- return true;
- }
- }
- return false;
- }
-
- private void deleteBaseDirIfExists() {
- if (this.basedir.exists()) {
- try {
- FileUtils.delete(this.basedir, FileUtils.RECURSIVE);
- }
- catch (IOException e) {
- throw new IllegalStateException("Failed to initialize base directory", e);
- }
- }
- }
-
- /**
- * Wraps the static method calls to {@link org.eclipse.jgit.api.Git} and
- * {@link org.eclipse.jgit.api.CloneCommand} allowing for easier unit testing.
- */
- static class JGitFactory {
- CloneCommand getCloneCommandByCloneRepository() {
- return Git.cloneRepository();
- }
-
- Git open(File file) {
- try {
- return Git.open(file);
- }
- catch (IOException e) {
- throw new IllegalStateException(e);
- }
- }
- }
-}
\ No newline at end of file
diff --git a/spring-cloud-release-tools-core/src/main/java/org/springframework/cloud/release/internal/pom/PomReader.java b/spring-cloud-release-tools-core/src/main/java/org/springframework/cloud/release/internal/pom/PomReader.java
deleted file mode 100644
index 4ad0e7a0..00000000
--- a/spring-cloud-release-tools-core/src/main/java/org/springframework/cloud/release/internal/pom/PomReader.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright 2013-2017 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.springframework.cloud.release.internal.pom;
-
-import java.io.File;
-import java.io.FileReader;
-import java.io.IOException;
-import java.io.Reader;
-
-import org.apache.maven.model.Model;
-import org.apache.maven.model.io.xpp3.MavenXpp3Reader;
-import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
-
-/**
- * @author Marcin Grzejszczak
- */
-class PomReader {
-
- /**
- * Returns a parsed POM
- */
- Model readPom(File pom) {
- try(Reader reader = new FileReader(pom)) {
- MavenXpp3Reader xpp3Reader = new MavenXpp3Reader();
- return xpp3Reader.read(reader);
- }
- catch (XmlPullParserException | IOException e) {
- throw new IllegalStateException("Failed to read file", e);
- }
- }
-}
diff --git a/spring-cloud-release-tools-core/src/main/java/org/springframework/cloud/release/internal/pom/PomUpdater.java b/spring-cloud-release-tools-core/src/main/java/org/springframework/cloud/release/internal/pom/PomUpdater.java
deleted file mode 100644
index ac603e95..00000000
--- a/spring-cloud-release-tools-core/src/main/java/org/springframework/cloud/release/internal/pom/PomUpdater.java
+++ /dev/null
@@ -1,412 +0,0 @@
-/*
- * Copyright 2013-2017 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.springframework.cloud.release.internal.pom;
-
-import java.io.BufferedWriter;
-import java.io.File;
-import java.io.FileWriter;
-import java.lang.invoke.MethodHandles;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Properties;
-import javax.xml.stream.XMLInputFactory;
-import javax.xml.stream.XMLStreamException;
-
-import org.apache.maven.model.Model;
-import org.apache.maven.plugin.logging.Log;
-import org.codehaus.mojo.versions.api.PomHelper;
-import org.codehaus.mojo.versions.change.AbstractVersionChanger;
-import org.codehaus.mojo.versions.change.VersionChange;
-import org.codehaus.mojo.versions.change.VersionChanger;
-import org.codehaus.mojo.versions.change.VersionChangerFactory;
-import org.codehaus.mojo.versions.rewriting.ModifiedPomXMLEventReader;
-import org.codehaus.stax2.XMLInputFactory2;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.util.StringUtils;
-
-/**
- * @author Marcin Grzejszczak
- */
-class PomUpdater {
-
- private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
-
- private final PomReader pomReader = new PomReader();
- private final PomWriter pomWriter = new PomWriter();
-
- /**
- * Basing on the contents of the root pom and the versions will decide whether
- * the project should be updated or not.
- *
- * @param rootFolder - root folder of the project
- * @param versions - list of dependencies to be updated
- * @return {@code true} if the project is on the list of projects to be updated
- */
- boolean shouldProjectBeUpdated(File rootFolder, Versions versions) {
- File rootPom = rootPom(rootFolder);
- Model model = this.pomReader.readPom(rootPom);
- String artifactId = artifactId(model);
- if (!versions.shouldBeUpdated(artifactId)) {
- log.info("Skipping project [{}] since it's not on the list of projects to update", model.getArtifactId());
- return false;
- }
- log.info("Project [{}] will have its dependencies updated", model.getArtifactId());
- return true;
- }
-
- private File rootPom(File rootFolder) {
- if (rootFolder.getName().endsWith(".xml")) {
- return rootFolder;
- }
- return new File(rootFolder, "pom.xml");
- }
-
- private String artifactId(Model model) {
- boolean parent = model.getArtifactId().endsWith("-parent");
- if (!parent) {
- return model.getArtifactId();
- }
- return model.getArtifactId().substring(0, model.getArtifactId().indexOf("-parent"));
- }
-
- ModelWrapper readModel(File pom) {
- return new ModelWrapper(this.pomReader.readPom(pom));
- }
-
- /**q
- * Updates the root / child module model
- *
- * @param rootPom - root project model
- * @param pom - file with the pom
- * @param versions - versions to update
- * @return updated model
- */
- ModelWrapper updateModel(ModelWrapper rootPom, File pom, Versions versions) {
- Model model = this.pomReader.readPom(pom);
- List] sourceChanges = new ArrayList<>();
- sourceChanges = updateParentIfPossible(rootPom, versions, model, sourceChanges);
- sourceChanges = updateVersionIfPossible(rootPom, versions, model, sourceChanges);
- return new ModelWrapper(model, sourceChanges, versions);
- }
-
- /**
- * Overwrites the pom.xml with data from {@link ModelWrapper} only if there were
- * any changes in the model.
- *
- * @return - the pom file
- */
- File overwritePomIfDirty(ModelWrapper updatedPomModel, Versions versions, File pom) {
- if (updatedPomModel.isDirty()) {
- log.debug("There were changes in the pom so file will be overridden");
- this.pomWriter.write(updatedPomModel, versions, pom);
- log.info("Successfully stored [{}]", pom);
- }
- return pom;
- }
-
- private List updateParentIfPossible(ModelWrapper wrapper, Versions versions,
- Model model, List sourceChanges) {
- String rootProjectName = wrapper.projectName();
- List changes = new ArrayList<>(sourceChanges);
- if (model.getParent() == null || StringUtils.isEmpty(model.getParent().getVersion())) {
- log.debug("Can't set the value for parent... Will return {}", sourceChanges);
- return changes;
- }
- String parentGroupId = model.getParent().getGroupId();
- String parentArtifactId = model.getParent().getArtifactId();
- log.debug("Searching for a version of parent [{}:{}]", parentGroupId, parentArtifactId);
- String oldVersion = model.getParent().getVersion();
- String version = versions.versionForProject(parentArtifactId);
- log.debug("Found version is [{}]", version);
- if (StringUtils.isEmpty(version)) {
- if (StringUtils.hasText(model.getParent().getRelativePath())) {
- version = versions.versionForProject(rootProjectName);
- } else {
- log.warn("There is no info on the [{}:{}] version", parentGroupId, parentArtifactId);
- return changes;
- }
- }
- if (oldVersion.equals(version)) {
- log.debug("Won't update the version of parent [{}:{}] since you're already using the proper one", parentGroupId, parentArtifactId);
- return changes;
- }
- log.info("Setting version of parent [{}] to [{}] for module [{}]", parentArtifactId,
- version, model.getArtifactId());
- changes.add(new VersionChange(parentGroupId, parentArtifactId, oldVersion, version));
- return changes;
- }
-
- private List updateVersionIfPossible(ModelWrapper wrapper, Versions versions,
- Model model, List sourceChanges) {
- String rootProjectName = wrapper.projectName();
- List changes = new ArrayList<>(sourceChanges);
- String groupId = groupId(model);
- String artifactId = model.getArtifactId();
- log.debug("Searching for a version [{}:{}]", groupId, artifactId);
- String oldVersion = model.getVersion();
- String version = versions.versionForProject(rootProjectName);
- log.debug("Found version is [{}]", version);
- if (StringUtils.isEmpty(version) || StringUtils.isEmpty(model.getVersion())) {
- log.debug("There was no version set for project [{}], skipping version setting for module [{}]", rootProjectName, model.getArtifactId());
- return changes;
- }
- if (oldVersion.equals(version)) {
- log.debug("Won't update the version of module [{}]:[{}] since you're already using the proper one", groupId, artifactId);
- return changes;
- }
- log.info("Setting [{}] version to [{}]", artifactId, version);
- changes.add(new VersionChange(groupId, artifactId, oldVersion, version));
- return changes;
- }
-
- private boolean relativePathIsSet(Model model) {
- return model.getParent() != null && StringUtils.hasText(model.getParent().getRelativePath());
- }
-
- private String parentName(Model model) {
- return model.getParent() != null ? model.getParent().getArtifactId() : "";
- }
-
- private String groupId(Model model) {
- if (StringUtils.hasText(model.getGroupId())) {
- return model.getGroupId();
- }
- if (model.getParent() != null) {
- return model.getParent().getGroupId();
- }
- return "";
- }
-}
-
-class ModelWrapper {
- final Model model;
- final Versions versions;
- final List sourceChanges = new ArrayList<>();
-
- ModelWrapper(Model model, List sourceChanges, Versions versions) {
- this.model = model;
- this.versions = versions;
- this.sourceChanges.addAll(sourceChanges);
- }
-
- ModelWrapper(Model model) {
- this.model = model;
- this.versions = Versions.EMPTY_VERSION;
- }
-
- String projectName() {
- return this.model.getArtifactId();
- }
-
- boolean isDirty() {
- return !this.sourceChanges.isEmpty() || this.versions.shouldSetProperty(this.model.getProperties());
- }
-}
-
-class PomWriter {
-
- private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
-
- void write(ModelWrapper wrapper, Versions versions, File pom) {
- try {
- VersionChangerFactory versionChangerFactory = new VersionChangerFactory();
- StringBuilder input = PomHelper.readXmlFile(pom);
- ModifiedPomXMLEventReader parsedPom = newModifiedPomXER(input);
- versionChangerFactory.setPom(parsedPom);
- LoggerToMavenLog loggerToMavenLog = new LoggerToMavenLog(PomWriter.log);
- versionChangerFactory.setLog(loggerToMavenLog);
- versionChangerFactory.setModel(wrapper.model);
- log.info("Applying version / parent / plugin / project changes to the pom [{}]", pom);
- VersionChanger changer = versionChangerFactory.newVersionChanger( true,
- true, true, true);
- for (VersionChange versionChange : wrapper.sourceChanges) {
- changer.apply(versionChange);
- }
- log.debug("Applying properties changes to the pom [{}]", pom);
- new PropertyVersionChanger(wrapper, versions, parsedPom, loggerToMavenLog)
- .apply(null);
- try (BufferedWriter bw = new BufferedWriter(new FileWriter(pom))) {
- bw.write(input.toString());
- }
- log.debug("Flushed changes to the pom file [{}]", pom);
- } catch (Exception e) {
- log.error("Exception occurred while trying to apply changes to the POM", e);
- }
- }
-
- /**
- * Creates a {@link org.codehaus.mojo.versions.rewriting.ModifiedPomXMLEventReader} from a StringBuilder.
- *
- * @param input The XML to read and modify.
- * @return The {@link org.codehaus.mojo.versions.rewriting.ModifiedPomXMLEventReader}.
- */
- private ModifiedPomXMLEventReader newModifiedPomXER(StringBuilder input) {
- ModifiedPomXMLEventReader newPom = null;
- try {
- XMLInputFactory inputFactory = XMLInputFactory2.newInstance();
- inputFactory.setProperty(XMLInputFactory2.P_PRESERVE_LOCATION, Boolean.TRUE);
- newPom = new ModifiedPomXMLEventReader(input, inputFactory);
- }
- catch (XMLStreamException e) {
- log.error("Exception occurred while trying to parse pom", e);
- }
- return newPom;
- }
-}
-
-class PropertyVersionChanger extends AbstractVersionChanger {
-
- private final Versions versions;
- private final PropertyStorer propertyStorer;
-
- PropertyVersionChanger(ModelWrapper wrapper, Versions versions, ModifiedPomXMLEventReader pom, Log log) {
- super(wrapper.model, pom, log);
- this.versions = versions;
- this.propertyStorer = new PropertyStorer(log, pom);
- }
-
- PropertyVersionChanger(ModelWrapper wrapper, Versions versions, ModifiedPomXMLEventReader pom, Log log, PropertyStorer propertyStorer) {
- super(wrapper.model, pom, log);
- this.versions = versions;
- this.propertyStorer = propertyStorer;
- }
-
- @Override public void apply(final VersionChange versionChange) throws XMLStreamException {
- this.versions.projects
- .stream()
- .filter(project -> {
- Properties properties = getModel().getProperties();
- String projectVersionKey = propertyName(project);
- if (!properties.containsKey(projectVersionKey)) {
- return false;
- }
- String version = properties.getProperty(projectVersionKey);
- return !version.equals(project.version);
- })
- .forEach(this.propertyStorer::setPropertyVersionIfApplicable);
- }
-
- private String propertyName(Project project) {
- return project.name + ".version";
- }
-}
-
-class PropertyStorer {
-
- private final Log log;
- private final ModifiedPomXMLEventReader pom;
-
- PropertyStorer(Log log, ModifiedPomXMLEventReader pom) {
- this.log = log;
- this.pom = pom;
- }
-
- void setPropertyVersionIfApplicable(Project project) {
- String propertyName = propertyName(project);
- if (setPropertyVersion(propertyName, project.version)) {
- log.info(" Updating property " + propertyName);
- log.info(" to version " + project.version);
- }
- }
-
- private String propertyName(Project project) {
- return project.name + ".version";
- }
-
- private boolean setPropertyVersion(String propertyName, String version) {
- try {
- return PomHelper.setPropertyVersion(this.pom, null, propertyName, version);
- }
- catch (XMLStreamException e) {
- this.log.error("Exception occurred while trying to set property version", e);
- return false;
- }
- }
-}
-
-class LoggerToMavenLog implements Log {
-
- private final Logger logger;
-
- LoggerToMavenLog(Logger logger) {
- this.logger = logger;
- }
-
- @Override public boolean isDebugEnabled() {
- return this.logger.isDebugEnabled();
- }
-
- @Override public void debug(CharSequence content) {
- this.logger.debug(content.toString());
- }
-
- @Override public void debug(CharSequence content, Throwable error) {
- this.logger.debug(content.toString(), error);
- }
-
- @Override public void debug(Throwable error) {
- this.debug("Exception occurred", error);
- }
-
- @Override public boolean isInfoEnabled() {
- return this.logger.isInfoEnabled();
- }
-
- @Override public void info(CharSequence content) {
- this.logger.info(content.toString());
- }
-
- @Override public void info(CharSequence content, Throwable error) {
- this.logger.info(content.toString(), error);
- }
-
- @Override public void info(Throwable error) {
- this.info("Exception occurred", error);
- }
-
- @Override public boolean isWarnEnabled() {
- return this.logger.isWarnEnabled();
- }
-
- @Override public void warn(CharSequence content) {
- this.logger.warn(content.toString());
- }
-
- @Override public void warn(CharSequence content, Throwable error) {
- this.logger.warn(content.toString(), error);
- }
-
- @Override public void warn(Throwable error) {
- this.warn("Exception occurred", error);
- }
-
- @Override public boolean isErrorEnabled() {
- return this.logger.isErrorEnabled();
- }
-
- @Override public void error(CharSequence content) {
- this.logger.error(content.toString());
- }
-
- @Override public void error(CharSequence content, Throwable error) {
- this.logger.error(content.toString(), error);
- }
-
- @Override public void error(Throwable error) {
- this.error("Exception occurred", error);
- }
-}
\ No newline at end of file
diff --git a/spring-cloud-release-tools-core/src/main/java/org/springframework/cloud/release/internal/pom/ProjectUpdater.java b/spring-cloud-release-tools-core/src/main/java/org/springframework/cloud/release/internal/pom/ProjectUpdater.java
deleted file mode 100644
index 312feb62..00000000
--- a/spring-cloud-release-tools-core/src/main/java/org/springframework/cloud/release/internal/pom/ProjectUpdater.java
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Copyright 2013-2017 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.springframework.cloud.release.internal.pom;
-
-import java.io.File;
-import java.io.IOException;
-import java.lang.invoke.MethodHandles;
-import java.net.URI;
-import java.nio.file.FileVisitResult;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.SimpleFileVisitor;
-import java.nio.file.attribute.BasicFileAttributes;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.cloud.release.internal.ReleaserProperties;
-
-/**
- * @author Marcin Grzejszczak
- */
-public class ProjectUpdater {
-
- private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
-
- private final File destinationDir;
- private final ReleaserProperties properties;
- private final GitProjectRepo gitProjectRepo;
- private final PomUpdater pomUpdater = new PomUpdater();
-
- public ProjectUpdater(ReleaserProperties properties) {
- try {
- this.destinationDir = properties.getPom().getCloneDestinationDir() != null ?
- new File(properties.getPom().getCloneDestinationDir()) :
- Files.createTempDirectory("releaser").toFile();
- this.properties = properties;
- this.gitProjectRepo = new GitProjectRepo(this.destinationDir);
- }
- catch (IOException e) {
- throw new IllegalStateException("Failed to create a temporary folder", e);
- }
- }
-
- /**
- * For the given root folder (typically the working directory) performs the whole
- * flow of updating {@code pom.xml} with values from Spring Cloud Release project.
- *
- * @param projectRoot - root folder with project to update
- */
- public void updateProject(File projectRoot) {
- File clonedScRelease = this.gitProjectRepo.cloneProject(
- URI.create(this.properties.getPom().getSpringCloudReleaseGitUrl()));
- this.gitProjectRepo.checkout(clonedScRelease, this.properties.getPom().getBranch());
- SCReleasePomParser sCReleasePomParser = new SCReleasePomParser(clonedScRelease);
- Versions versions = sCReleasePomParser.allVersions();
- log.info("Retrieved the following versions\n{}", versions);
- if (!this.pomUpdater.shouldProjectBeUpdated(projectRoot, versions)) {
- log.info("Skipping project updating");
- return;
- }
- File rootPom = new File(projectRoot, "pom.xml");
- ModelWrapper rootPomModel = this.pomUpdater.readModel(rootPom);
- processAllPoms(projectRoot, new PomWalker(rootPomModel, versions, this.pomUpdater,
- properties));
- }
-
- private void processAllPoms(File projectRoot, PomWalker pomWalker) {
- try {
- Files.walkFileTree(projectRoot.toPath(), pomWalker);
- }
- catch (IOException e) {
- throw new IllegalStateException(e);
- }
- }
-
- private class PomWalker extends SimpleFileVisitor {
-
- private static final String POM_XML = "pom.xml";
-
- private final ModelWrapper rootPom;
- private final Versions versions;
- private final PomUpdater pomUpdater;
- private final ReleaserProperties properties;
-
- private PomWalker(ModelWrapper rootPom, Versions versions, PomUpdater pomUpdater,
- ReleaserProperties properties) {
- this.rootPom = rootPom;
- this.versions = versions;
- this.pomUpdater = pomUpdater;
- this.properties = properties;
- }
-
- @Override
- public FileVisitResult visitFile(Path path, BasicFileAttributes attr) {
- File file = path.toFile();
- if (POM_XML.equals(file.getName())) {
- if (pathIgnored(file)) {
- log.debug("Ignoring file [{}] since it's on a list of patterns to ignore", file);
- return FileVisitResult.CONTINUE;
- }
- ModelWrapper model = this.pomUpdater.updateModel(this.rootPom, file, this.versions);
- this.pomUpdater.overwritePomIfDirty(model, this.versions, file);
- }
- return FileVisitResult.CONTINUE;
- }
-
- private boolean pathIgnored(File file) {
- String path = file.getPath();
- return this.properties.getPom().getIgnoredPomRegex().stream().anyMatch(path::matches);
- }
- }
-
-}
diff --git a/spring-cloud-release-tools-core/src/main/java/org/springframework/cloud/release/internal/pom/SCReleasePomParser.java b/spring-cloud-release-tools-core/src/main/java/org/springframework/cloud/release/internal/pom/SCReleasePomParser.java
deleted file mode 100644
index 77d134a8..00000000
--- a/spring-cloud-release-tools-core/src/main/java/org/springframework/cloud/release/internal/pom/SCReleasePomParser.java
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * Copyright 2013-2017 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.springframework.cloud.release.internal.pom;
-
-import java.io.File;
-import java.lang.invoke.MethodHandles;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-import java.util.function.Function;
-import java.util.function.Predicate;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-import java.util.stream.Collectors;
-
-import org.apache.maven.model.Model;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Parses the poms for a given project and populates versions from Spring Cloud Release
- *
- * @author Marcin Grzejszczak
- */
-class SCReleasePomParser {
-
- private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
-
- private static final String STARTER_POM = "spring-cloud-starter-parent/pom.xml";
- private static final String DEPENDENCIES_POM = "spring-cloud-dependencies/pom.xml";
- private static final Pattern SC_VERSION_PATTERN = Pattern.compile("^(spring-cloud-.*)\\.version$");
-
- private final File springCloudReleaseDir;
- private final String bootPom;
- private final String dependenciesPom;
- private final PomReader pomReader = new PomReader();
-
- SCReleasePomParser(File springCloudReleaseDir) {
- this(springCloudReleaseDir, STARTER_POM, DEPENDENCIES_POM);
- }
-
- SCReleasePomParser(File springCloudReleaseDir, String bootPom, String dependenciesPom) {
- this.springCloudReleaseDir = springCloudReleaseDir;
- this.bootPom = bootPom;
- this.dependenciesPom = dependenciesPom;
- }
-
- Versions allVersions() {
- Versions boot = bootVersion();
- Versions cloud = springCloudVersions();
- return new Versions(boot.bootVersion, cloud.scBuildVersion, allProjects(boot, cloud));
- }
-
- private Set allProjects(Versions boot, Versions cloud) {
- Set allProjects = new HashSet<>();
- allProjects.addAll(boot.projects);
- allProjects.addAll(cloud.projects);
- return allProjects;
- }
-
- Versions bootVersion() {
- Model model = pom(this.bootPom);
- String bootArtifactId = model.getParent().getArtifactId();
- log.debug("Boot artifact id is equal to [{}]", bootArtifactId);
- if (!SpringCloudConstants.BOOT_STARTER_ARTIFACT_ID.equals(bootArtifactId)) {
- throw new IllegalStateException("The pom doesn't have a [" + SpringCloudConstants.BOOT_STARTER_ARTIFACT_ID + "] artifact id");
- }
- String bootVersion = model.getParent().getVersion();
- log.debug("Boot version is equal to [{}]", bootVersion);
- return new Versions(bootVersion);
- }
-
- private Model pom(String pom) {
- if (pom == null) {
- throw new IllegalStateException("Pom is not present");
- }
- File pomFile = new File(this.springCloudReleaseDir, pom);
- if (!pomFile.exists()) {
- throw new IllegalStateException("Pom is not present");
- }
- return this.pomReader.readPom(pomFile);
- }
-
- Versions springCloudVersions() {
- Model model = pom(this.dependenciesPom);
- String buildArtifact = model.getParent().getArtifactId();
- log.debug("[{}] artifact id is equal to [{}]", SpringCloudConstants.CLOUD_DEPENDENCIES_ARTIFACT_ID, buildArtifact);
- if (!SpringCloudConstants.CLOUD_DEPENDENCIES_ARTIFACT_ID.equals(buildArtifact)) {
- throw new IllegalStateException("The pom doesn't have a [" + SpringCloudConstants.CLOUD_DEPENDENCIES_ARTIFACT_ID + "] artifact id");
- }
- String buildVersion = model.getParent().getVersion();
- log.debug("Spring Cloud Build version is equal to [{}]", buildVersion);
- Set projects = model.getProperties().entrySet()
- .stream()
- .filter(propertyMatchesSCPattern())
- .map(toProject())
- .collect(Collectors.toSet());
- return new Versions(buildVersion, projects);
- }
-
- private Predicate> propertyMatchesSCPattern() {
- return entry -> SC_VERSION_PATTERN.matcher(entry.getKey().toString()).matches();
- }
-
- private Function, Project> toProject() {
- return entry -> {
- Matcher matcher = SC_VERSION_PATTERN.matcher(entry.getKey().toString());
- // you have to first match to get info about the group
- matcher.matches();
- String name = matcher.group(1);
- return new Project(name, entry.getValue().toString());
- };
- }
-}
-
diff --git a/spring-cloud-release-tools-core/src/main/java/org/springframework/cloud/release/internal/pom/SpringCloudConstants.java b/spring-cloud-release-tools-core/src/main/java/org/springframework/cloud/release/internal/pom/SpringCloudConstants.java
deleted file mode 100644
index c3a56a65..00000000
--- a/spring-cloud-release-tools-core/src/main/java/org/springframework/cloud/release/internal/pom/SpringCloudConstants.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright 2013-2017 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.springframework.cloud.release.internal.pom;
-
-/**
- * @author Marcin Grzejszczak
- */
-final class SpringCloudConstants {
- static final String BOOT_STARTER_ARTIFACT_ID = "spring-boot-starter-parent";
- static final String CLOUD_DEPENDENCIES_ARTIFACT_ID = "spring-cloud-dependencies-parent";
- static final String BUILD_ARTIFACT_ID = "spring-cloud-build";
-
- private SpringCloudConstants() {
- throw new IllegalStateException("Don't instantiate a utility class");
- }
-
-}
diff --git a/spring-cloud-release-tools-core/src/main/java/org/springframework/cloud/release/internal/pom/Versions.java b/spring-cloud-release-tools-core/src/main/java/org/springframework/cloud/release/internal/pom/Versions.java
deleted file mode 100644
index d459813a..00000000
--- a/spring-cloud-release-tools-core/src/main/java/org/springframework/cloud/release/internal/pom/Versions.java
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Copyright 2013-2017 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.springframework.cloud.release.internal.pom;
-
-import java.util.HashSet;
-import java.util.Properties;
-import java.util.Set;
-import java.util.stream.Collectors;
-
-import static org.springframework.cloud.release.internal.pom.SpringCloudConstants.BOOT_STARTER_ARTIFACT_ID;
-import static org.springframework.cloud.release.internal.pom.SpringCloudConstants.BUILD_ARTIFACT_ID;
-import static org.springframework.cloud.release.internal.pom.SpringCloudConstants.CLOUD_DEPENDENCIES_ARTIFACT_ID;
-
-/**
- * Represents versions taken out from Spring Cloud Release pom
- *
- * @author Marcin Grzejszczak
- */
-class Versions {
-
- private static final String SPRING_BOOT_PROJECT_NAME = "spring-boot";
- static final Versions EMPTY_VERSION = new Versions("");
-
- String bootVersion;
- String scBuildVersion;
- Set projects = new HashSet<>();
-
- Versions(String bootVersion) {
- this.bootVersion = bootVersion;
- this.projects.add(new Project(SPRING_BOOT_PROJECT_NAME, bootVersion));
- this.projects.add(new Project(BOOT_STARTER_ARTIFACT_ID, bootVersion));
- }
-
- Versions(String scBuildVersion, Set projects) {
- this.scBuildVersion = scBuildVersion;
- this.projects.add(new Project(BUILD_ARTIFACT_ID, scBuildVersion));
- this.projects.add(new Project(CLOUD_DEPENDENCIES_ARTIFACT_ID, scBuildVersion));
- this.projects.addAll(projects);
- }
-
- Versions(String bootVersion, String scBuildVersion, Set projects) {
- this.bootVersion = bootVersion;
- this.scBuildVersion = scBuildVersion;
- this.projects.add(new Project(BUILD_ARTIFACT_ID, scBuildVersion));
- this.projects.add(new Project(CLOUD_DEPENDENCIES_ARTIFACT_ID, scBuildVersion));
- this.projects.addAll(projects);
- }
-
- String versionForProject(String projectName) {
- return this.projects.stream()
- .filter(project -> nameMatches(projectName, project))
- .findFirst()
- .orElse(Project.EMPTY_PROJECT)
- .version;
- }
-
- boolean shouldBeUpdated(String projectName) {
- return this.projects.stream()
- .anyMatch(project -> nameMatches(projectName, project));
- }
-
- boolean shouldSetProperty(Properties properties) {
- return this.projects.stream()
- .anyMatch(project -> properties.containsKey(project.name + ".version"));
- }
-
- private boolean nameMatches(String projectName, Project project) {
- if (project.name.equals(projectName)) {
- return true;
- }
- boolean containsParent = projectName.endsWith("-parent");
- if (!containsParent) {
- return false;
- }
- String withoutParent = projectName.substring(0, projectName.indexOf("-parent"));
- return project.name.equals(withoutParent);
- }
-
- @Override public String toString() {
- return "Spring Boot Version=[" + this.bootVersion + ']' + "\nSpring Cloud Build Version=["
- + this.scBuildVersion + ']' + "\nProjects=\n\t" + this.projects.stream().map(Object::toString).collect(
- Collectors.joining("\n\t"));
- }
-}
-
-/**
- * @author Marcin Grzejszczak
- */
-class Project {
-
- static Project EMPTY_PROJECT = new Project("", "");
-
- final String name;
- final String version;
-
- Project(String name, String version) {
- this.name = name;
- this.version = version;
- }
-
- @Override public boolean equals(Object o) {
- if (this == o)
- return true;
- if (o == null || getClass() != o.getClass())
- return false;
- Project project = (Project) o;
- if (this.name != null ? !this.name.equals(project.name) : project.name != null)
- return false;
- return this.version != null ?
- this.version.equals(project.version) :
- project.version == null;
- }
-
- @Override public int hashCode() {
- int result = this.name != null ? this.name.hashCode() : 0;
- result = 31 * result + (this.version != null ? this.version.hashCode() : 0);
- return result;
- }
-
- @Override public String toString() {
- return "name=[" + this.name + "], version=[" + this.version + ']';
- }
-}
\ No newline at end of file
diff --git a/spring-cloud-release-tools-core/src/test/java/org/springframework/cloud/release/AcceptanceTests.java b/spring-cloud-release-tools-core/src/test/java/org/springframework/cloud/release/AcceptanceTests.java
deleted file mode 100644
index aad4bee6..00000000
--- a/spring-cloud-release-tools-core/src/test/java/org/springframework/cloud/release/AcceptanceTests.java
+++ /dev/null
@@ -1,95 +0,0 @@
-package org.springframework.cloud.release;
-
-import java.io.File;
-import java.io.IOException;
-import java.net.URISyntaxException;
-import java.nio.file.Files;
-
-import org.apache.maven.model.Model;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TemporaryFolder;
-import org.springframework.cloud.release.internal.pom.ProjectUpdater;
-import org.springframework.cloud.release.internal.ReleaserProperties;
-import org.springframework.cloud.release.internal.pom.TestPomReader;
-import org.springframework.cloud.release.internal.pom.TestUtils;
-import org.springframework.util.FileSystemUtils;
-
-import static org.assertj.core.api.BDDAssertions.then;
-
-/**
- * @author Marcin Grzejszczak
- */
-public class AcceptanceTests {
-
- @Rule public TemporaryFolder tmp = new TemporaryFolder();
- TestPomReader testPomReader = new TestPomReader();
- File temporaryFolder;
-
- @Before
- public void setup() throws Exception {
- this.temporaryFolder = this.tmp.newFolder();
- TestUtils.prepareLocalRepo();
- FileSystemUtils.copyRecursively(file("/projects/"), this.temporaryFolder);
- }
-
- @Test
- public void should_update_all_versions_for_a_release_train() throws Exception {
- ReleaserProperties releaserProperties = releaserProperties();
- ProjectUpdater projectUpdater = new ProjectUpdater(releaserProperties);
-
- projectUpdater.updateProject(new File(this.temporaryFolder, "/spring-cloud-sleuth"));
-
- then(this.temporaryFolder).exists();
- Model rootPom = this.testPomReader.readPom(tmpFile("/spring-cloud-sleuth/pom.xml"));
- Model depsPom = this.testPomReader.readPom(tmpFile("/spring-cloud-sleuth/spring-cloud-sleuth-dependencies/pom.xml"));
- Model corePom = this.testPomReader.readPom(tmpFile("/spring-cloud-sleuth/spring-cloud-sleuth-core/pom.xml"));
- Model zipkinStreamPom = this.testPomReader.readPom(tmpFile("/spring-cloud-sleuth/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-zipkin-stream/pom.xml"));
- then(rootPom.getVersion()).isEqualTo("1.2.0.BUILD-SNAPSHOT");
- then(rootPom.getProperties())
- .containsEntry("spring-cloud-build.version","1.3.1.BUILD-SNAPSHOT")
- .containsEntry("spring-cloud-commons.version","1.2.0.BUILD-SNAPSHOT")
- .containsEntry("spring-cloud-stream.version","Chelsea.BUILD-SNAPSHOT")
- .containsEntry("spring-cloud-netflix.version","1.3.0.BUILD-SNAPSHOT");
- then(depsPom.getVersion()).isEqualTo("1.2.0.BUILD-SNAPSHOT");
- then(depsPom.getParent().getVersion()).isEqualTo("1.3.1.BUILD-SNAPSHOT");
- then(corePom.getParent().getVersion()).isEqualTo("1.2.0.BUILD-SNAPSHOT");
- then(zipkinStreamPom.getParent().getVersion()).isEqualTo("1.2.0.BUILD-SNAPSHOT");
- }
-
- @Test
- public void should_not_update_a_project_that_is_not_on_the_list() throws Exception {
- ReleaserProperties releaserProperties = releaserProperties();
- ProjectUpdater projectUpdater = new ProjectUpdater(releaserProperties);
- File beforeProcessing = pom("/projects/project/");
-
- projectUpdater.updateProject(tmpFile("/project/"));
-
- then(this.temporaryFolder).exists();
- File afterProcessing = tmpFile("/project/pom.xml");
- then(asString(beforeProcessing)).isEqualTo(asString(afterProcessing));
- }
-
- private ReleaserProperties releaserProperties() throws URISyntaxException {
- ReleaserProperties releaserProperties = new ReleaserProperties();
- releaserProperties.getPom().setSpringCloudReleaseGitUrl(file("/projects/spring-cloud-release/").toURI().getPath());
- return releaserProperties;
- }
-
- private File tmpFile(String relativePath) {
- return new File(this.temporaryFolder, relativePath);
- }
-
- private File file(String relativePath) throws URISyntaxException {
- return new File(AcceptanceTests.class.getResource(relativePath).toURI());
- }
-
- private File pom(String relativePath) throws URISyntaxException {
- return new File(new File(AcceptanceTests.class.getResource(relativePath).toURI()), "pom.xml");
- }
-
- private String asString(File file) throws IOException {
- return new String(Files.readAllBytes(file.toPath()));
- }
-}
diff --git a/spring-cloud-release-tools-core/src/test/java/org/springframework/cloud/release/internal/pom/GitProjectRepoTests.java b/spring-cloud-release-tools-core/src/test/java/org/springframework/cloud/release/internal/pom/GitProjectRepoTests.java
deleted file mode 100644
index 5cdd1c41..00000000
--- a/spring-cloud-release-tools-core/src/test/java/org/springframework/cloud/release/internal/pom/GitProjectRepoTests.java
+++ /dev/null
@@ -1,102 +0,0 @@
-package org.springframework.cloud.release.internal.pom;
-
-import java.io.File;
-import java.io.IOException;
-import java.net.URISyntaxException;
-import java.nio.file.Files;
-
-import org.eclipse.jgit.api.CloneCommand;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TemporaryFolder;
-
-import static org.assertj.core.api.Assertions.fail;
-import static org.assertj.core.api.BDDAssertions.then;
-import static org.assertj.core.api.BDDAssertions.thenThrownBy;
-
-/**
- * @author Marcin Grzejszczak
- */
-public class GitProjectRepoTests {
-
- @Rule public TemporaryFolder tmp = new TemporaryFolder();
- File springCloudReleaseProject;
- File tmpFolder;
- GitProjectRepo gitProjectRepo;
-
- @Before
- public void setup() throws IOException, URISyntaxException {
- this.tmpFolder = this.tmp.newFolder();
- this.springCloudReleaseProject = new File(GitProjectRepoTests.class.getResource("/projects/spring-cloud-release").toURI());
- TestUtils.prepareLocalRepo();
- this.gitProjectRepo = new GitProjectRepo(this.tmpFolder);
- }
-
- @Test
- public void should_clone_the_project_from_a_given_location() throws IOException {
- this.gitProjectRepo.cloneProject(this.springCloudReleaseProject.toURI());
-
- then(new File(this.tmpFolder, ".git")).exists();
- }
-
- @Test
- public void should_throw_exception_when_there_is_no_repo() throws IOException, URISyntaxException {
- thenThrownBy(() -> this.gitProjectRepo
- .cloneProject(GitProjectRepoTests.class.getResource("/projects/").toURI()))
- .isInstanceOf(IllegalStateException.class)
- .hasMessageContaining("Exception occurred while cloning repo");
- }
-
- @Test
- public void should_throw_an_exception_when_failed_to_initialize_the_repo() throws IOException {
- thenThrownBy(() -> new GitProjectRepo(this.tmpFolder, new ExceptionThrowingJGitFactory()).cloneProject(this.springCloudReleaseProject.toURI()))
- .isInstanceOf(IllegalStateException.class)
- .hasMessageContaining("Exception occurred while cloning repo")
- .hasCauseInstanceOf(CustomException.class);
- }
-
- @Test
- public void should_check_out_a_branch_on_cloned_repo() throws IOException {
- File project = this.gitProjectRepo.cloneProject(this.springCloudReleaseProject.toURI());
- this.gitProjectRepo.checkout(project, "vCamden.SR3");
-
- File pom = new File(this.tmpFolder, "pom.xml");
- then(pom).exists();
- then(Files.lines(pom.toPath()).anyMatch(s -> s.contains("Camden.SR3 "))).isTrue();
- }
-
- @Test
- public void should_check_out_a_branch_on_cloned_repo2() throws IOException {
- File project = this.gitProjectRepo.cloneProject(this.springCloudReleaseProject.toURI());
- this.gitProjectRepo.checkout(project, "Camden.x");
-
- File pom = new File(this.tmpFolder, "pom.xml");
- then(pom).exists();
- then(Files.lines(pom.toPath()).anyMatch(s -> s.contains("Camden.BUILD-SNAPSHOT "))).isTrue();
- }
-
- @Test
- public void should_throw_an_exception_when_checking_out_nonexisting_branch() throws IOException {
- File project = this.gitProjectRepo.cloneProject(this.springCloudReleaseProject.toURI());
- try {
- this.gitProjectRepo.checkout(project, "nonExistingBranch");
- fail("should throw an exception");
- } catch (IllegalStateException e) {
- then(e).hasMessageContaining("Ref nonExistingBranch can not be resolved");
- }
- }
-
-}
-
-class ExceptionThrowingJGitFactory extends GitProjectRepo.JGitFactory {
- @Override CloneCommand getCloneCommandByCloneRepository() {
- throw new CustomException("foo");
- }
-}
-
-class CustomException extends RuntimeException {
- public CustomException(String message) {
- super(message);
- }
-}
\ No newline at end of file
diff --git a/spring-cloud-release-tools-core/src/test/java/org/springframework/cloud/release/internal/pom/LoggerToMavenLogTests.java b/spring-cloud-release-tools-core/src/test/java/org/springframework/cloud/release/internal/pom/LoggerToMavenLogTests.java
deleted file mode 100644
index 4f1f9f35..00000000
--- a/spring-cloud-release-tools-core/src/test/java/org/springframework/cloud/release/internal/pom/LoggerToMavenLogTests.java
+++ /dev/null
@@ -1,119 +0,0 @@
-package org.springframework.cloud.release.internal.pom;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.InjectMocks;
-import org.mockito.Mock;
-import org.mockito.runners.MockitoJUnitRunner;
-import org.slf4j.Logger;
-import org.springframework.cloud.release.internal.pom.LoggerToMavenLog;
-
-import static org.mockito.BDDMockito.then;
-
-/**
- * @author Marcin Grzejszczak
- */
-@RunWith(MockitoJUnitRunner.class)
-public class LoggerToMavenLogTests {
-
- @Mock Logger logger;
- @InjectMocks LoggerToMavenLog loggerToMavenLog;
- RuntimeException exception = new RuntimeException();
-
- @Test public void isDebugEnabled() throws Exception {
- this.loggerToMavenLog.isDebugEnabled();
-
- then(this.logger).should().isDebugEnabled();
- }
-
- @Test public void debug() throws Exception {
- this.loggerToMavenLog.debug("foo");
-
- then(this.logger).should().debug("foo");
- }
-
- @Test public void debug1() throws Exception {
- this.loggerToMavenLog.debug("foo", this.exception);
-
- then(this.logger).should().debug("foo", this.exception);
- }
-
- @Test public void debug2() throws Exception {
- this.loggerToMavenLog.debug(exception);
-
- then(this.logger).should().debug("Exception occurred", this.exception);
- }
-
- @Test public void isInfoEnabled() throws Exception {
- this.loggerToMavenLog.isInfoEnabled();
-
- then(this.logger).should().isInfoEnabled();
- }
-
- @Test public void info() throws Exception {
- this.loggerToMavenLog.info("foo");
-
- then(this.logger).should().info("foo");
- }
-
- @Test public void info1() throws Exception {
- this.loggerToMavenLog.info("foo", this.exception);
-
- then(this.logger).should().info("foo", this.exception);
- }
-
- @Test public void info2() throws Exception {
- this.loggerToMavenLog.info(exception);
-
- then(this.logger).should().info("Exception occurred", this.exception);
- }
-
- @Test public void isWarnEnabled() throws Exception {
- this.loggerToMavenLog.isWarnEnabled();
-
- then(this.logger).should().isWarnEnabled();
- }
-
- @Test public void warn() throws Exception {
- this.loggerToMavenLog.warn("foo");
-
- then(this.logger).should().warn("foo");
- }
-
- @Test public void warn1() throws Exception {
- this.loggerToMavenLog.warn("foo", this.exception);
-
- then(this.logger).should().warn("foo", this.exception);
- }
-
- @Test public void warn2() throws Exception {
- this.loggerToMavenLog.warn(exception);
-
- then(this.logger).should().warn("Exception occurred", this.exception);
- }
-
- @Test public void isErrorEnabled() throws Exception {
- this.loggerToMavenLog.isErrorEnabled();
-
- then(this.logger).should().isErrorEnabled();
- }
-
- @Test public void error() throws Exception {
- this.loggerToMavenLog.error("foo");
-
- then(this.logger).should().error("foo");
- }
-
- @Test public void error1() throws Exception {
- this.loggerToMavenLog.error("foo", this.exception);
-
- then(this.logger).should().error("foo", this.exception);
- }
-
- @Test public void error2() throws Exception {
- this.loggerToMavenLog.error(exception);
-
- then(this.logger).should().error("Exception occurred", this.exception);
- }
-
-}
\ No newline at end of file
diff --git a/spring-cloud-release-tools-core/src/test/java/org/springframework/cloud/release/internal/pom/PomReaderTests.java b/spring-cloud-release-tools-core/src/test/java/org/springframework/cloud/release/internal/pom/PomReaderTests.java
deleted file mode 100644
index 59c5e1c1..00000000
--- a/spring-cloud-release-tools-core/src/test/java/org/springframework/cloud/release/internal/pom/PomReaderTests.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright 2013-2017 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.springframework.cloud.release.internal.pom;
-
-import static org.assertj.core.api.BDDAssertions.then;
-import static org.assertj.core.api.BDDAssertions.thenThrownBy;
-
-import java.io.File;
-import java.io.IOException;
-import java.net.URI;
-import java.net.URISyntaxException;
-
-import org.apache.maven.model.Model;
-import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
-import org.junit.Before;
-import org.junit.Test;
-
-/**
- * @author Marcin Grzejszczak
- */
-public class PomReaderTests {
-
- PomReader pomReader = new PomReader();
- File springCloudReleaseProject;
- File licenseFile;
-
- @Before
- public void setup() throws URISyntaxException {
- URI scRelease = GitProjectRepoTests.class.getResource("/projects/spring-cloud-release").toURI();
- this.springCloudReleaseProject = new File(scRelease.getPath(), "pom.xml");
- this.licenseFile = new File(scRelease.getPath(), "LICENSE.txt");
- }
-
- @Test
- public void should_parse_a_valid_pom() {
- Model pom = this.pomReader.readPom(this.springCloudReleaseProject);
-
- then(pom).isNotNull();
- then(pom.getArtifactId()).isEqualTo("spring-cloud-starter-build");
- }
-
- @Test
- public void should_throw_exception_when_file_is_missing() {
- thenThrownBy(() -> this.pomReader.readPom(new File("foo/bar")))
- .hasMessage("Failed to read file")
- .hasCauseInstanceOf(IOException.class);
- }
-
- @Test
- public void should_throw_exception_when_file_is_invalid() {
- thenThrownBy(() -> this.pomReader.readPom(this.licenseFile))
- .hasMessage("Failed to read file")
- .hasCauseInstanceOf(XmlPullParserException.class);
- }
-}
\ No newline at end of file
diff --git a/spring-cloud-release-tools-core/src/test/java/org/springframework/cloud/release/internal/pom/PomUpdaterTests.java b/spring-cloud-release-tools-core/src/test/java/org/springframework/cloud/release/internal/pom/PomUpdaterTests.java
deleted file mode 100644
index 8209eff5..00000000
--- a/spring-cloud-release-tools-core/src/test/java/org/springframework/cloud/release/internal/pom/PomUpdaterTests.java
+++ /dev/null
@@ -1,299 +0,0 @@
-/*
- * Copyright 2013-2017 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.springframework.cloud.release.internal.pom;
-
-import java.io.File;
-import java.io.IOException;
-import java.net.URISyntaxException;
-import java.nio.file.Files;
-import java.util.HashSet;
-import java.util.Set;
-
-import org.apache.maven.model.Model;
-import org.assertj.core.api.BDDAssertions;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TemporaryFolder;
-import org.springframework.boot.test.rule.OutputCapture;
-import org.springframework.util.FileSystemUtils;
-
-/**
- * @author Marcin Grzejszczak
- */
-public class PomUpdaterTests {
-
- Versions versions = new Versions("0.0.1", "0.0.2", projects());
- PomUpdater pomUpdater = new PomUpdater();
- PomReader pomReader = new PomReader();
- @Rule public OutputCapture capture = new OutputCapture();
- @Rule public TemporaryFolder tmp = new TemporaryFolder();
- File temporaryFolder;
-
- @Before
- public void setup() throws Exception {
- this.temporaryFolder = this.tmp.newFolder();
- FileSystemUtils.copyRecursively(file("/projects/"), this.temporaryFolder);
- }
-
- @Test
- public void should_not_update_pom_when_project_is_not_on_the_versions_list() throws Exception {
- File springCloudReleasePom = file("/projects/spring-cloud-release");
-
- BDDAssertions
- .then(this.pomUpdater.shouldProjectBeUpdated(springCloudReleasePom, this.versions)).isFalse();
- }
-
- @Test
- public void should_not_update_pom_when_project_with_parent_suffix_is_not_on_the_versions_list() throws Exception {
- File springCloud = pom("/projects/project", "pom_with_parent_suffix.xml");
-
- BDDAssertions.then(this.pomUpdater.shouldProjectBeUpdated(springCloud, this.versions)).isFalse();
- }
-
- @Test
- public void should_update_pom_for_project_with_suffix_when_project_is_on_the_versions_list() throws Exception {
- File springCloud = pom("/projects/project", "pom_matching_with_parent_suffix.xml");
-
- BDDAssertions.then(this.pomUpdater.shouldProjectBeUpdated(springCloud, this.versions)).isTrue();
- }
-
- @Test
- public void should_update_pom_when_project_is_not_on_the_versions_list() throws Exception {
- File springCloudSleuthPom = file("/projects/spring-cloud-sleuth");
-
- BDDAssertions
- .then(this.pomUpdater.shouldProjectBeUpdated(springCloudSleuthPom, this.versions)).isTrue();
- }
-
- @Test
- public void should_not_update_the_pom_if_no_changes_were_made() throws Exception {
- File originalPom = pom("/projects/project");
- File pomInTemp = tmpFile("/project/pom.xml");
- ModelWrapper rootPom = model("foo");
- ModelWrapper model = this.pomUpdater.updateModel(rootPom, pomInTemp, this.versions);
-
- File storedPom = this.pomUpdater.overwritePomIfDirty(model, this.versions, pomInTemp);
-
- BDDAssertions.then(asString(storedPom)).isEqualTo(asString(originalPom));
- }
-
- @Test
- public void should_update_the_pom_if_only_artifact_id_is_matched_in_the_root_pom() throws Exception {
- File originalPom = pom("/projects/project", "pom_matching_artifact.xml");
- File pomInTemp = tmpFile("/project/pom_matching_artifact.xml");
- ModelWrapper rootPom = model("spring-cloud-sleuth");
- ModelWrapper model = this.pomUpdater.updateModel(rootPom, pomInTemp, this.versions);
-
- File storedPom = this.pomUpdater.overwritePomIfDirty(model, this.versions, pomInTemp);
-
- BDDAssertions.then(asString(storedPom)).isNotEqualTo(asString(originalPom));
- Model overriddenPomModel = this.pomReader.readPom(storedPom);
- BDDAssertions.then(overriddenPomModel.getVersion()).isEqualTo("0.0.3.BUILD-SNAPSHOT");
- }
-
- @Test
- public void should_update_the_pom_if_parent_is_matched_via_sc_build() throws Exception {
- File originalPom = pom("/projects/project", "pom_matching_parent_v2.xml");
- File pomInTemp = tmpFile("/project/pom_matching_parent_v2.xml");
- ModelWrapper rootPom = model("spring-cloud-sleuth");
- ModelWrapper model = this.pomUpdater.updateModel(rootPom, pomInTemp, this.versions);
-
- File storedPom = this.pomUpdater.overwritePomIfDirty(model, this.versions, pomInTemp);
-
- BDDAssertions.then(asString(originalPom)).isNotEqualTo(asString(storedPom));
- Model overriddenPomModel = this.pomReader.readPom(storedPom);
- BDDAssertions.then(overriddenPomModel.getVersion()).isEqualTo("0.0.3.BUILD-SNAPSHOT");
- BDDAssertions.then(overriddenPomModel.getParent().getVersion()).isEqualTo("0.0.2");
- }
-
- @Test
- public void should_update_the_pom_if_parent_is_matched_via_sc_dependencies_parent() throws Exception {
- File originalPom = pom("/projects/project", "pom_matching_parent.xml");
- File pomInTemp = tmpFile("/project/pom_matching_parent.xml");
- ModelWrapper rootPom = model("spring-cloud-sleuth");
- ModelWrapper model = this.pomUpdater.updateModel(rootPom, pomInTemp, this.versions);
-
- File storedPom = this.pomUpdater.overwritePomIfDirty(model, this.versions, pomInTemp);
-
- BDDAssertions.then(asString(storedPom)).isNotEqualTo(asString(originalPom));
- Model overriddenPomModel = this.pomReader.readPom(storedPom);
- BDDAssertions.then(overriddenPomModel.getVersion()).isEqualTo("0.0.3.BUILD-SNAPSHOT");
- BDDAssertions.then(overriddenPomModel.getParent().getVersion()).isEqualTo("0.0.2");
- }
-
- @Test
- public void should_not_update_child_pom_when_project_is_not_on_the_versions_list() throws Exception {
- File springCloudReleasePom = file("/projects/spring-cloud-release");
-
- BDDAssertions
- .then(this.pomUpdater.shouldProjectBeUpdated(springCloudReleasePom, this.versions)).isFalse();
- }
-
- @Test
- public void should_update_child_pom_when_project_is_not_on_the_versions_list() throws Exception {
- File springCloudSleuthPom = file("/projects/spring-cloud-sleuth");
-
- BDDAssertions
- .then(this.pomUpdater.shouldProjectBeUpdated(springCloudSleuthPom, this.versions)).isTrue();
- }
-
- @Test
- public void should_update_the_child_pom_if_parent_is_matched_via_sc_build() throws Exception {
- File originalPom = pom("/projects/project/children", "pom_matching_parent_v2.xml");
- File pomInTemp = tmpFile("/project/children/pom_matching_parent_v2.xml");
- ModelWrapper rootPom = model("spring-cloud-sleuth");
- ModelWrapper model = this.pomUpdater.updateModel(rootPom, pomInTemp, this.versions);
-
- File storedPom = this.pomUpdater.overwritePomIfDirty(model, this.versions, pomInTemp);
-
- BDDAssertions.then(asString(storedPom)).isNotEqualTo(asString(originalPom));
- Model overriddenPomModel = this.pomReader.readPom(storedPom);
- BDDAssertions.then(overriddenPomModel.getVersion()).isEqualTo("0.0.3.BUILD-SNAPSHOT");
- BDDAssertions.then(overriddenPomModel.getParent().getVersion()).isEqualTo("0.0.3.BUILD-SNAPSHOT");
- // the rest is the same
- BDDAssertions.then(overriddenPomModel.getProperties())
- .containsEntry("spring-cloud-foo.version", "1.3.1.BUILD-SNAPSHOT")
- .containsEntry("foo.version", "1.2.0.BUILD-SNAPSHOT");
- }
-
- @Test
- public void should_update_the_child_pom_if_parent_is_matched_via_sc_dependencies_parent() throws Exception {
- File originalPom = pom("/projects/project/children", "pom_matching_parent.xml");
- File pomInTemp = tmpFile("/project/children/pom_matching_parent.xml");
- ModelWrapper rootPom = model("spring-cloud-sleuth");
- ModelWrapper model = this.pomUpdater.updateModel(rootPom, pomInTemp, this.versions);
-
- File storedPom = this.pomUpdater.overwritePomIfDirty(model, this.versions, pomInTemp);
-
- BDDAssertions.then(asString(storedPom)).isNotEqualTo(asString(originalPom));
- Model overriddenPomModel = this.pomReader.readPom(storedPom);
- BDDAssertions.then(overriddenPomModel.getVersion()).isEqualTo("0.0.3.BUILD-SNAPSHOT");
- BDDAssertions.then(overriddenPomModel.getParent().getVersion()).isEqualTo("0.0.3.BUILD-SNAPSHOT");
- // the rest is the same
- BDDAssertions.then(overriddenPomModel.getProperties())
- .containsEntry("spring-cloud-foo.version", "1.3.1.BUILD-SNAPSHOT")
- .containsEntry("foo.version", "1.2.0.BUILD-SNAPSHOT");
- }
-
- @Test
- public void should_update_the_child_pom_if_properties_are_matched() throws Exception {
- File originalPom = pom("/projects/project/children", "pom_matching_properties.xml");
- File pomInTemp = tmpFile("/project/children/pom_matching_properties.xml");
- ModelWrapper rootPom = model("spring-cloud-sleuth");
- ModelWrapper model = this.pomUpdater.updateModel(rootPom, pomInTemp, this.versions);
-
- File storedPom = this.pomUpdater.overwritePomIfDirty(model, this.versions, pomInTemp);
-
- BDDAssertions.then(asString(storedPom)).isNotEqualTo(asString(originalPom));
- Model overriddenPomModel = this.pomReader.readPom(storedPom);
- BDDAssertions.then(overriddenPomModel.getVersion()).isEqualTo("0.0.3.BUILD-SNAPSHOT");
- BDDAssertions.then(overriddenPomModel.getParent().getVersion()).isEqualTo("0.0.3.BUILD-SNAPSHOT");
- BDDAssertions.then(overriddenPomModel.getProperties())
- .containsEntry("spring-cloud-sleuth.version", "0.0.3.BUILD-SNAPSHOT")
- .containsEntry("spring-cloud-vault.version", "0.0.4.BUILD-SNAPSHOT");
- }
-
- @Test
- public void should_override_a_pom_when_there_was_a_change_in_the_model() throws Exception {
- File beforeProcessing = pom("/projects/project/children", "pom_matching_properties.xml");
- File afterProcessing = tmpFile("/project/children/pom_matching_properties.xml");
- ModelWrapper model = this.pomUpdater.updateModel(model("spring-cloud-sleuth"), afterProcessing, this.versions);
-
- File processedPom = this.pomUpdater.overwritePomIfDirty(model, Versions.EMPTY_VERSION, afterProcessing);
-
- String processedPomText = asString(processedPom);
- String beforeProcessingText = asString(beforeProcessing);
- BDDAssertions.then(processedPomText).isNotEqualTo(beforeProcessingText);
- }
-
- @Test
- public void should_not_override_a_pom_when_there_was_no_change_in_the_model() throws Exception {
- File beforeProcessing = pom("/projects/project/");
- File afterProcessing = tmpFile("/project/pom.xml");
- ModelWrapper model = this.pomUpdater.updateModel(model("foo"), afterProcessing, this.versions);
-
- File processedPom = this.pomUpdater.overwritePomIfDirty(model, Versions.EMPTY_VERSION, afterProcessing);
-
- BDDAssertions.then(asString(processedPom)).isEqualTo(asString(beforeProcessing));
- }
-
- @Test
- public void should_update_the_model_when_root_project_has_parent_suffix() throws Exception {
- File originalPom = pom("/projects/spring-cloud-contract");
- File pomInTemp = tmpFile("/spring-cloud-contract/pom.xml");
- ModelWrapper rootPom = model("spring-cloud-contract-parent");
- ModelWrapper model = this.pomUpdater.updateModel(rootPom, pomInTemp, this.versions);
-
- File storedPom = this.pomUpdater.overwritePomIfDirty(model, this.versions, pomInTemp);
-
- BDDAssertions.then(asString(storedPom)).isNotEqualTo(asString(originalPom));
- Model overriddenPomModel = this.pomReader.readPom(storedPom);
- BDDAssertions.then(overriddenPomModel.getVersion()).isEqualTo("0.0.2.BUILD-SNAPSHOT");
- BDDAssertions.then(overriddenPomModel.getParent().getVersion()).isEqualTo("0.0.2");
- }
-
- @Test
- public void should_not_update_the_model_when_project_uses_same_version_for_artifact() throws Exception {
- File originalPom = pom("/projects/project/", "pom_matching_artifact_same_version.xml");
- File pomInTemp = tmpFile("/project/pom_matching_artifact_same_version.xml");
- ModelWrapper rootPom = model("spring-cloud-sleuth");
- ModelWrapper model = this.pomUpdater.updateModel(rootPom, pomInTemp, this.versions);
-
- File storedPom = this.pomUpdater.overwritePomIfDirty(model, this.versions, pomInTemp);
-
- BDDAssertions.then(asString(storedPom)).isEqualTo(asString(originalPom));
- BDDAssertions.then(this.capture.toString())
- .contains("Won't update the version of parent")
- .contains("Won't update the version of module");
- }
-
- Set projects() {
- Set projects = new HashSet<>();
- projects.add(new Project("spring-cloud-contract", "0.0.2.BUILD-SNAPSHOT"));
- projects.add(new Project("spring-cloud-sleuth", "0.0.3.BUILD-SNAPSHOT"));
- projects.add(new Project("spring-cloud-vault", "0.0.4.BUILD-SNAPSHOT"));
- return projects;
- }
-
- private ModelWrapper model(String projectName) {
- Model parent = new Model();
- parent.setArtifactId(projectName);
- return new ModelWrapper(parent);
- }
-
- private File tmpFile(String relativePath) {
- return new File(this.temporaryFolder, relativePath);
- }
-
- private File file(String relativePath) throws URISyntaxException {
- return new File(GitProjectRepoTests.class.getResource(relativePath).toURI());
- }
-
- private File pom(String relativePath) throws URISyntaxException {
- return pom(relativePath, "pom.xml");
- }
-
- private File pom(String relativePath, String pomName) throws URISyntaxException {
- return new File(new File(GitProjectRepoTests.class.getResource(relativePath).toURI()), pomName);
- }
-
- private String asString(File file) throws IOException {
- return new String(Files.readAllBytes(file.toPath()));
- }
-
-}
\ No newline at end of file
diff --git a/spring-cloud-release-tools-core/src/test/java/org/springframework/cloud/release/internal/pom/PropertyVersionChangerTests.java b/spring-cloud-release-tools-core/src/test/java/org/springframework/cloud/release/internal/pom/PropertyVersionChangerTests.java
deleted file mode 100644
index 7680600e..00000000
--- a/spring-cloud-release-tools-core/src/test/java/org/springframework/cloud/release/internal/pom/PropertyVersionChangerTests.java
+++ /dev/null
@@ -1,110 +0,0 @@
-package org.springframework.cloud.release.internal.pom;
-
-import java.util.HashSet;
-import java.util.Properties;
-import java.util.Set;
-
-import org.apache.maven.model.Model;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.runners.MockitoJUnitRunner;
-import org.springframework.cloud.release.internal.pom.ModelWrapper;
-import org.springframework.cloud.release.internal.pom.Project;
-import org.springframework.cloud.release.internal.pom.PropertyStorer;
-import org.springframework.cloud.release.internal.pom.PropertyVersionChanger;
-import org.springframework.cloud.release.internal.pom.Versions;
-
-import edu.emory.mathcs.backport.java.util.Arrays;
-
-import static org.mockito.BDDMockito.then;
-import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.never;
-
-/**
- * @author Marcin Grzejszczak
- */
-@RunWith(MockitoJUnitRunner.class)
-public class PropertyVersionChangerTests {
-
- @Mock PropertyStorer propertyStorer;
-
- @Test
- public void should_set_version_when_project_matches_property_name() throws Exception {
- PropertyVersionChanger changer = new PropertyVersionChanger(model(), versions(), null, null, this.propertyStorer);
-
- changer.apply(null);
-
- then(this.propertyStorer).should().setPropertyVersionIfApplicable(project("spring-cloud-sleuth", "1.2.0.BUILD-SNAPSHOT"));
- }
-
- @Test
- public void should_not_set_version_when_project_doesnt_match_property_name() throws Exception {
- PropertyVersionChanger changer = new PropertyVersionChanger(nonMatchingModel(), versions(), null, null, this.propertyStorer);
-
- changer.apply(null);
-
- then(this.propertyStorer).should(never()).setPropertyVersionIfApplicable(any(Project.class));
- }
-
- @Test
- public void should_not_set_version_when_project_matches_property_name_and_versions_are_the_same() throws Exception {
- PropertyVersionChanger changer = new PropertyVersionChanger(modelWithSameValues(), versions(), null, null, this.propertyStorer);
-
- changer.apply(null);
-
- then(this.propertyStorer).should(never()).setPropertyVersionIfApplicable(any(Project.class));
- }
-
- Versions versions() {
- return new Versions("", "", allProjects());
- }
-
- @SuppressWarnings("unchecked")
- private Set allProjects() {
- return new HashSet<>(Arrays.asList(new Project[] {
- project("spring-cloud-aws", "1.2.0.BUILD-SNAPSHOT"),
- project("spring-cloud-sleuth", "1.2.0.BUILD-SNAPSHOT")
- }));
- }
-
- Project project(String name, String value) {
- return new Project(name, value);
- }
-
- ModelWrapper model() {
- Model model = new Model();
- model.setProperties(properties());
- return new ModelWrapper(model);
- }
-
- Properties properties() {
- Properties properties = new Properties();
- properties.setProperty("spring-cloud-sleuth.version", "1.0.0.RELEASE");
- return properties;
- }
-
- ModelWrapper modelWithSameValues() {
- Model model = new Model();
- model.setProperties(propertiesWithSameValues());
- return new ModelWrapper(model);
- }
-
- Properties propertiesWithSameValues() {
- Properties properties = new Properties();
- properties.setProperty("spring-cloud-sleuth.version", "1.2.0.BUILD-SNAPSHOT");
- return properties;
- }
-
- ModelWrapper nonMatchingModel() {
- Model model = new Model();
- model.setProperties(nonMatchingProperties());
- return new ModelWrapper(model);
- }
-
- Properties nonMatchingProperties() {
- Properties properties = new Properties();
- properties.setProperty("spring-cloud-non-matching.version", "1.0.0.RELEASE");
- return properties;
- }
-}
\ No newline at end of file
diff --git a/spring-cloud-release-tools-core/src/test/java/org/springframework/cloud/release/internal/pom/SCReleasePomParserTests.java b/spring-cloud-release-tools-core/src/test/java/org/springframework/cloud/release/internal/pom/SCReleasePomParserTests.java
deleted file mode 100644
index 64db70ef..00000000
--- a/spring-cloud-release-tools-core/src/test/java/org/springframework/cloud/release/internal/pom/SCReleasePomParserTests.java
+++ /dev/null
@@ -1,129 +0,0 @@
-package org.springframework.cloud.release.internal.pom;
-
-import java.io.File;
-import java.io.IOException;
-import java.net.URISyntaxException;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import static org.assertj.core.api.BDDAssertions.then;
-import static org.assertj.core.api.BDDAssertions.thenThrownBy;
-
-/**
- * @author Marcin Grzejszczak
- */
-public class SCReleasePomParserTests {
-
- File springCloudReleaseProject;
-
- @Before
- public void setup() throws IOException, URISyntaxException {
- this.springCloudReleaseProject = new File(GitProjectRepoTests.class.getResource("/projects/spring-cloud-release").toURI());
- }
-
- @Test
- public void should_throw_exception_when_boot_pom_is_missing() {
- SCReleasePomParser parser = new SCReleasePomParser(new File("."));
-
- thenThrownBy(parser::bootVersion)
- .isInstanceOf(IllegalStateException.class)
- .hasMessageContaining("Pom is not present");
- }
-
- @Test
- public void should_throw_exception_when_null_is_passed_to_boot() {
- SCReleasePomParser parser = new SCReleasePomParser(this.springCloudReleaseProject, null, null);
-
- thenThrownBy(parser::bootVersion)
- .isInstanceOf(IllegalStateException.class)
- .hasMessageContaining("Pom is not present");
- }
-
- @Test
- public void should_throw_exception_when_boot_version_is_missing_in_pom() {
- SCReleasePomParser parser = new SCReleasePomParser(this.springCloudReleaseProject, "pom.xml", null);
-
- thenThrownBy(parser::bootVersion)
- .isInstanceOf(IllegalStateException.class)
- .hasMessageContaining("The pom doesn't have a [spring-boot-starter-parent] artifact id");
- }
-
- @Test
- public void should_populate_boot_version() {
- SCReleasePomParser parser = new SCReleasePomParser(this.springCloudReleaseProject);
-
- String bootVersion = parser.bootVersion().bootVersion;
-
- then(bootVersion).isEqualTo("1.5.1.BUILD-SNAPSHOT");
- }
-
- @Test
- public void should_throw_exception_when_cloud_pom_is_missing() {
- SCReleasePomParser parser = new SCReleasePomParser(new File("."));
-
- thenThrownBy(parser::springCloudVersions)
- .isInstanceOf(IllegalStateException.class)
- .hasMessageContaining("Pom is not present");
- }
-
- @Test
- public void should_throw_exception_when_null_is_passed_to_cloud() {
- SCReleasePomParser parser = new SCReleasePomParser(this.springCloudReleaseProject, null, null);
-
- thenThrownBy(parser::springCloudVersions)
- .isInstanceOf(IllegalStateException.class)
- .hasMessageContaining("Pom is not present");
- }
-
- @Test
- public void should_throw_exception_when_cloud_version_is_missing_in_pom() {
- SCReleasePomParser parser = new SCReleasePomParser(this.springCloudReleaseProject, null, "pom.xml");
-
- thenThrownBy(parser::springCloudVersions)
- .isInstanceOf(IllegalStateException.class)
- .hasMessageContaining("The pom doesn't have a [spring-cloud-dependencies-parent] artifact id");
- }
-
- @Test
- public void should_populate_cloud_version() {
- SCReleasePomParser parser = new SCReleasePomParser(this.springCloudReleaseProject);
-
- Versions cloudVersions = parser.springCloudVersions();
-
- then(cloudVersions.scBuildVersion).isEqualTo("1.3.1.BUILD-SNAPSHOT");
- then(cloudVersions.projects).contains(allProjects());
- }
-
- @Test
- public void should_populate_boot_and_cloud_version() {
- SCReleasePomParser parser = new SCReleasePomParser(this.springCloudReleaseProject);
-
- Versions cloudVersions = parser.allVersions();
-
- then(cloudVersions.bootVersion).isEqualTo("1.5.1.BUILD-SNAPSHOT");
- then(cloudVersions.scBuildVersion).isEqualTo("1.3.1.BUILD-SNAPSHOT");
- then(cloudVersions.projects).contains(allProjects());
- }
-
- private Project[] allProjects() {
- return new Project[] { project("spring-cloud-aws", "1.2.0.BUILD-SNAPSHOT"),
- project("spring-cloud-bus", "1.3.0.BUILD-SNAPSHOT"),
- project("spring-cloud-contract", "1.1.0.BUILD-SNAPSHOT"),
- project("spring-cloud-cloudfoundry", "1.1.0.BUILD-SNAPSHOT"),
- project("spring-cloud-commons", "1.2.0.BUILD-SNAPSHOT"),
- project("spring-cloud-config", "1.3.0.BUILD-SNAPSHOT"),
- project("spring-cloud-netflix", "1.3.0.BUILD-SNAPSHOT"),
- project("spring-cloud-security", "1.2.0.BUILD-SNAPSHOT"),
- project("spring-cloud-consul", "1.2.0.BUILD-SNAPSHOT"),
- project("spring-cloud-sleuth", "1.2.0.BUILD-SNAPSHOT"),
- project("spring-cloud-stream", "Chelsea.BUILD-SNAPSHOT"),
- project("spring-cloud-task", "1.1.2.BUILD-SNAPSHOT"),
- project("spring-cloud-vault", "1.0.0.BUILD-SNAPSHOT"),
- project("spring-cloud-zookeeper", "1.1.0.BUILD-SNAPSHOT") };
- }
-
- Project project(String name, String value) {
- return new Project(name, value);
- }
-}
\ No newline at end of file
diff --git a/spring-cloud-release-tools-core/src/test/java/org/springframework/cloud/release/internal/pom/TestPomReader.java b/spring-cloud-release-tools-core/src/test/java/org/springframework/cloud/release/internal/pom/TestPomReader.java
deleted file mode 100644
index 87d9f96b..00000000
--- a/spring-cloud-release-tools-core/src/test/java/org/springframework/cloud/release/internal/pom/TestPomReader.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package org.springframework.cloud.release.internal.pom;
-
-import java.io.File;
-
-import org.apache.maven.model.Model;
-import org.springframework.cloud.release.internal.pom.PomReader;
-
-/**
- * @author Marcin Grzejszczak
- */
-public class TestPomReader {
-
- PomReader pomReader = new PomReader();
-
- public Model readPom(File pom) {
- return this.pomReader.readPom(pom);
- }
-}
diff --git a/spring-cloud-release-tools-core/src/test/java/org/springframework/cloud/release/internal/pom/TestUtils.java b/spring-cloud-release-tools-core/src/test/java/org/springframework/cloud/release/internal/pom/TestUtils.java
deleted file mode 100644
index c77075a2..00000000
--- a/spring-cloud-release-tools-core/src/test/java/org/springframework/cloud/release/internal/pom/TestUtils.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package org.springframework.cloud.release.internal.pom;
-
-import java.io.File;
-import java.io.IOException;
-
-import org.eclipse.jgit.util.FileUtils;
-
-public class TestUtils {
-
- public static void prepareLocalRepo() throws IOException {
- prepareLocalRepo("target/test-classes/projects/", "spring-cloud-release");
- }
-
- private static void prepareLocalRepo(String buildDir, String repoPath) throws IOException {
- File dotGit = new File(buildDir + repoPath + "/.git");
- File git = new File(buildDir + repoPath + "/git");
- if (git.exists()) {
- if (dotGit.exists()) {
- FileUtils.delete(dotGit, FileUtils.RECURSIVE);
- }
- }
- git.renameTo(dotGit);
- }
-
-}
\ No newline at end of file
diff --git a/spring-cloud-release-tools-core/src/test/java/org/springframework/cloud/release/internal/pom/VersionChangeAssertions.java b/spring-cloud-release-tools-core/src/test/java/org/springframework/cloud/release/internal/pom/VersionChangeAssertions.java
deleted file mode 100644
index 22e628df..00000000
--- a/spring-cloud-release-tools-core/src/test/java/org/springframework/cloud/release/internal/pom/VersionChangeAssertions.java
+++ /dev/null
@@ -1,58 +0,0 @@
-package org.springframework.cloud.release.internal.pom;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.assertj.core.api.AbstractAssert;
-import org.assertj.core.api.BDDAssertions;
-import org.codehaus.mojo.versions.change.VersionChange;
-
-/**
- * @author Marcin Grzejszczak
- */
-class VersionChangeAssertions extends BDDAssertions {
-
- public static VersionChangeAssert then(ListOfChanges actual) {
- return assertThat(actual);
- }
-
- public static VersionChangeAssert assertThat(ListOfChanges actual) {
- return new VersionChangeAssert(actual);
- }
-
-}
-
-class ListOfChanges {
-
- final List changes;
-
- ListOfChanges(ModelWrapper model) {
- this.changes = new ArrayList<>(model.sourceChanges);
- }
-}
-
-class VersionChangeAssert extends
- AbstractAssert {
-
- public VersionChangeAssert(ListOfChanges actual) {
- super(actual, VersionChangeAssert.class);
- }
-
- VersionChangeAssert newParentVersionIsEqualTo(String groupId, String artifactId, String newVersion) {
- boolean matches = false;
- for (VersionChange change : actual.changes) {
- if (newVersion.equals(change.getNewVersion())
- && groupId.equals(change.getGroupId())
- && artifactId.equals(change.getArtifactId())) {
- matches = true;
- break;
- }
- }
- if (matches) {
- return this;
- }
- failWithMessage("There is no change with that parent coordinates");
- return this;
- }
-}
-
diff --git a/spring-cloud-release-tools-core/src/test/java/org/springframework/cloud/release/internal/pom/VersionsTests.java b/spring-cloud-release-tools-core/src/test/java/org/springframework/cloud/release/internal/pom/VersionsTests.java
deleted file mode 100644
index 52c8cde0..00000000
--- a/spring-cloud-release-tools-core/src/test/java/org/springframework/cloud/release/internal/pom/VersionsTests.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright 2013-2017 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.springframework.cloud.release.internal.pom;
-
-import java.util.HashSet;
-import java.util.Properties;
-import java.util.Set;
-
-import org.junit.Test;
-import org.springframework.cloud.release.internal.pom.Project;
-import org.springframework.cloud.release.internal.pom.Versions;
-
-import static org.assertj.core.api.BDDAssertions.then;
-
-/**
- * @author Marcin Grzejszczak
- */
-public class VersionsTests {
-
- Versions versions = new Versions("", projects());
-
- @Test
- public void should_add_boot_to_versions_when_version_is_created() {
- then(new Versions("1.2.3.RELEASE").projects)
- .contains(
- new Project("spring-boot", "1.2.3.RELEASE"),
- new Project("spring-boot-starter-parent", "1.2.3.RELEASE")
- );
- }
-
- @Test
- public void should_return_true_when_project_is_on_the_list() {
- then(this.versions.shouldBeUpdated("foo")).isTrue();
- }
-
- @Test
- public void should_return_true_when_project_has_a_parent_suffix_and_project_is_on_the_list() {
- then(this.versions.shouldBeUpdated("foo-parent")).isTrue();
- }
-
- @Test
- public void should_return_false_when_project_is_not_on_the_list() {
- then(this.versions.shouldBeUpdated("missing")).isFalse();
- }
-
- @Test
- public void should_return_version_for_present_project() {
- then(this.versions.versionForProject("foo")).isEqualTo("bar");
- }
-
- @Test
- public void should_return_empty_string_for_missing_project() {
- then(this.versions.versionForProject("missing")).isEmpty();
- }
-
- @Test
- public void should_return_true_if_properties_contains_project_key() {
- then(this.versions.shouldSetProperty(validProps())).isTrue();
- }
-
- @Test
- public void should_return_false_if_properties_does_not_contain_project_key() {
- then(this.versions.shouldSetProperty(missingProps())).isFalse();
- }
-
- Set projects() {
- Set projects = new HashSet<>();
- projects.add(new Project("foo", "bar"));
- return projects;
- }
-
- Properties validProps() {
- Properties properties = new Properties();
- properties.setProperty("foo.version", "1.0.0");
- return properties;
- }
-
- Properties missingProps() {
- Properties properties = new Properties();
- properties.setProperty("missing.version", "1.0.0");
- return properties;
- }
-}
\ No newline at end of file
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/builder/resolved/file.txt b/spring-cloud-release-tools-core/src/test/resources/projects/builder/resolved/file.txt
deleted file mode 100644
index e69de29b..00000000
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/builder/unresolved/file.html b/spring-cloud-release-tools-core/src/test/resources/projects/builder/unresolved/file.html
deleted file mode 100644
index cddd0885..00000000
--- a/spring-cloud-release-tools-core/src/test/resources/projects/builder/unresolved/file.html
+++ /dev/null
@@ -1 +0,0 @@
-Unresolved
\ No newline at end of file
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/project/children/pom.xml b/spring-cloud-release-tools-core/src/test/resources/projects/project/children/pom.xml
deleted file mode 100644
index 039b9bf6..00000000
--- a/spring-cloud-release-tools-core/src/test/resources/projects/project/children/pom.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-
-
-
-
- 4.0.0
-
- foo
- 1.2.0.BUILD-SNAPSHOT
- pom
- foo
- foo
-
-
- parentGroup
- parentArtifactId
- 1.3.1.BUILD-SNAPSHOT
- ..
-
-
-
- 1.3.1.BUILD-SNAPSHOT
- 1.2.0.BUILD-SNAPSHOT
-
-
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/project/children/pom_matching_artifact.xml b/spring-cloud-release-tools-core/src/test/resources/projects/project/children/pom_matching_artifact.xml
deleted file mode 100644
index 0d53f5e5..00000000
--- a/spring-cloud-release-tools-core/src/test/resources/projects/project/children/pom_matching_artifact.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-
-
-
-
- 4.0.0
-
- spring-cloud-sleuth-child
- 1.2.0.BUILD-SNAPSHOT
- pom
- foo
- foo
-
-
- parentGroup
- parentArtifactId
- 1.3.1.BUILD-SNAPSHOT
- ..
-
-
-
- 1.3.1.BUILD-SNAPSHOT
- 1.2.0.BUILD-SNAPSHOT
-
-
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/project/children/pom_matching_parent.xml b/spring-cloud-release-tools-core/src/test/resources/projects/project/children/pom_matching_parent.xml
deleted file mode 100644
index f64bd647..00000000
--- a/spring-cloud-release-tools-core/src/test/resources/projects/project/children/pom_matching_parent.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-
-
-
-
- 4.0.0
-
- spring-cloud-sleuth-child
- 1.2.0.BUILD-SNAPSHOT
- pom
- foo
- foo
-
-
- org.springframework.cloud
- spring-cloud-sleuth
- 1.3.1.BUILD-SNAPSHOT
- ..
-
-
-
- 1.3.1.BUILD-SNAPSHOT
- 1.2.0.BUILD-SNAPSHOT
-
-
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/project/children/pom_matching_parent_v2.xml b/spring-cloud-release-tools-core/src/test/resources/projects/project/children/pom_matching_parent_v2.xml
deleted file mode 100644
index f64bd647..00000000
--- a/spring-cloud-release-tools-core/src/test/resources/projects/project/children/pom_matching_parent_v2.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-
-
-
-
- 4.0.0
-
- spring-cloud-sleuth-child
- 1.2.0.BUILD-SNAPSHOT
- pom
- foo
- foo
-
-
- org.springframework.cloud
- spring-cloud-sleuth
- 1.3.1.BUILD-SNAPSHOT
- ..
-
-
-
- 1.3.1.BUILD-SNAPSHOT
- 1.2.0.BUILD-SNAPSHOT
-
-
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/project/children/pom_matching_properties.xml b/spring-cloud-release-tools-core/src/test/resources/projects/project/children/pom_matching_properties.xml
deleted file mode 100644
index c2be71c2..00000000
--- a/spring-cloud-release-tools-core/src/test/resources/projects/project/children/pom_matching_properties.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-
-
-
-
- 4.0.0
-
- spring-cloud-sleuth-child
- 1.2.0.BUILD-SNAPSHOT
- pom
- foo
- foo
-
-
- org.springframework.cloud
- spring-cloud-sleuth
- 1.3.1.BUILD-SNAPSHOT
- ..
-
-
-
- 1.3.1.BUILD-SNAPSHOT
- 1.2.0.BUILD-SNAPSHOT
-
-
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/project/pom.xml b/spring-cloud-release-tools-core/src/test/resources/projects/project/pom.xml
deleted file mode 100644
index 504000ba..00000000
--- a/spring-cloud-release-tools-core/src/test/resources/projects/project/pom.xml
+++ /dev/null
@@ -1,41 +0,0 @@
-
-
-
-
- 4.0.0
-
- foo
- 1.2.0.BUILD-SNAPSHOT
- pom
- foo
- foo
-
-
- parentGroup
- parentArtifactId
- 1.3.1.BUILD-SNAPSHOT
-
-
-
-
-
- 1.3.1.BUILD-SNAPSHOT
- 1.2.0.BUILD-SNAPSHOT
-
-
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/project/pom_matching_artifact.xml b/spring-cloud-release-tools-core/src/test/resources/projects/project/pom_matching_artifact.xml
deleted file mode 100644
index d504aec8..00000000
--- a/spring-cloud-release-tools-core/src/test/resources/projects/project/pom_matching_artifact.xml
+++ /dev/null
@@ -1,41 +0,0 @@
-
-
-
-
- 4.0.0
-
- spring-cloud-sleuth
- 1.2.0.BUILD-SNAPSHOT
- pom
- foo
- foo
-
-
- parentGroup
- parentArtifactId
- 1.3.1.BUILD-SNAPSHOT
-
-
-
-
-
- 1.3.1.BUILD-SNAPSHOT
- 1.2.0.BUILD-SNAPSHOT
-
-
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/project/pom_matching_artifact_same_version.xml b/spring-cloud-release-tools-core/src/test/resources/projects/project/pom_matching_artifact_same_version.xml
deleted file mode 100644
index 7e097d58..00000000
--- a/spring-cloud-release-tools-core/src/test/resources/projects/project/pom_matching_artifact_same_version.xml
+++ /dev/null
@@ -1,39 +0,0 @@
-
-
-
-
- 4.0.0
-
- spring-cloud-sleuth
- 0.0.3.BUILD-SNAPSHOT
- pom
- foo
- foo
-
-
- org.springframework
- spring-cloud-sleuth
- 0.0.3.BUILD-SNAPSHOT
-
-
-
- 1.3.1.BUILD-SNAPSHOT
- 1.2.0.BUILD-SNAPSHOT
-
-
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/project/pom_matching_parent.xml b/spring-cloud-release-tools-core/src/test/resources/projects/project/pom_matching_parent.xml
deleted file mode 100644
index 324497f5..00000000
--- a/spring-cloud-release-tools-core/src/test/resources/projects/project/pom_matching_parent.xml
+++ /dev/null
@@ -1,41 +0,0 @@
-
-
-
-
- 4.0.0
-
- spring-cloud-sleuth
- 1.2.0.BUILD-SNAPSHOT
- pom
- foo
- foo
-
-
- org.springframework.cloud
- spring-cloud-build
- 1.3.1.BUILD-SNAPSHOT
-
-
-
-
-
- 1.3.1.BUILD-SNAPSHOT
- 1.2.0.BUILD-SNAPSHOT
-
-
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/project/pom_matching_parent_v2.xml b/spring-cloud-release-tools-core/src/test/resources/projects/project/pom_matching_parent_v2.xml
deleted file mode 100644
index 324497f5..00000000
--- a/spring-cloud-release-tools-core/src/test/resources/projects/project/pom_matching_parent_v2.xml
+++ /dev/null
@@ -1,41 +0,0 @@
-
-
-
-
- 4.0.0
-
- spring-cloud-sleuth
- 1.2.0.BUILD-SNAPSHOT
- pom
- foo
- foo
-
-
- org.springframework.cloud
- spring-cloud-build
- 1.3.1.BUILD-SNAPSHOT
-
-
-
-
-
- 1.3.1.BUILD-SNAPSHOT
- 1.2.0.BUILD-SNAPSHOT
-
-
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/project/pom_matching_properties.xml b/spring-cloud-release-tools-core/src/test/resources/projects/project/pom_matching_properties.xml
deleted file mode 100644
index a59e3487..00000000
--- a/spring-cloud-release-tools-core/src/test/resources/projects/project/pom_matching_properties.xml
+++ /dev/null
@@ -1,41 +0,0 @@
-
-
-
-
- 4.0.0
-
- spring-cloud-sleuth
- 1.2.0.BUILD-SNAPSHOT
- pom
- foo
- foo
-
-
- org.springframework.cloud
- spring-cloud-build
- 1.3.1.BUILD-SNAPSHOT
-
-
-
-
-
- 1.3.1.BUILD-SNAPSHOT
- 1.2.0.BUILD-SNAPSHOT
-
-
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/project/pom_matching_with_parent_suffix.xml b/spring-cloud-release-tools-core/src/test/resources/projects/project/pom_matching_with_parent_suffix.xml
deleted file mode 100644
index d6f6628f..00000000
--- a/spring-cloud-release-tools-core/src/test/resources/projects/project/pom_matching_with_parent_suffix.xml
+++ /dev/null
@@ -1,41 +0,0 @@
-
-
-
-
- 4.0.0
-
- spring-cloud-sleuth-parent
- 1.2.0.BUILD-SNAPSHOT
- pom
- foo
- foo
-
-
- parentGroup
- parentArtifactId
- 1.3.1.BUILD-SNAPSHOT
-
-
-
-
-
- 1.3.1.BUILD-SNAPSHOT
- 1.2.0.BUILD-SNAPSHOT
-
-
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/project/pom_with_parent_suffix.xml b/spring-cloud-release-tools-core/src/test/resources/projects/project/pom_with_parent_suffix.xml
deleted file mode 100644
index 8a4f9248..00000000
--- a/spring-cloud-release-tools-core/src/test/resources/projects/project/pom_with_parent_suffix.xml
+++ /dev/null
@@ -1,41 +0,0 @@
-
-
-
-
- 4.0.0
-
- foo-parent
- 1.2.0.BUILD-SNAPSHOT
- pom
- foo
- foo
-
-
- parentGroup
- parentArtifactId
- 1.3.1.BUILD-SNAPSHOT
-
-
-
-
-
- 1.3.1.BUILD-SNAPSHOT
- 1.2.0.BUILD-SNAPSHOT
-
-
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-contract/pom.xml b/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-contract/pom.xml
deleted file mode 100644
index 30717fad..00000000
--- a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-contract/pom.xml
+++ /dev/null
@@ -1,440 +0,0 @@
-
-
- 4.0.0
-
-
- org.springframework.cloud
- spring-cloud-build
- 1.3.1.BUILD-SNAPSHOT
-
-
-
- spring-cloud-contract-parent
- pom
- 1.1.0.BUILD-SNAPSHOT
-
- Spring Cloud Contract
- Spring Cloud Contract
-
- https://github.com/spring-cloud/spring-cloud-contract
-
- 2016
-
-
- 5.12.1
- 2.17.0
- 1.5.2.BUILD-SNAPSHOT
- 2.17
- 1.3.1.BUILD-SNAPSHOT
- 1.1.0.BUILD-SNAPSHOT
- Chelsea.BUILD-SNAPSHOT
- 1.3.0.BUILD-SNAPSHOT
- 1.2.0.BUILD-SNAPSHOT
- 1.2.0.BUILD-SNAPSHOT
-
-
-
- spring-cloud-contract-dependencies
- docs
- spring-cloud-contract-wiremock
- spring-cloud-contract-verifier
- spring-cloud-contract-spec
- spring-cloud-contract-stub-runner
- spring-cloud-contract-starters
- spring-cloud-contract-tools
- tests
- samples
-
-
-
-
-
- org.springframework.cloud
- spring-cloud-commons-dependencies
- ${spring-cloud-commons.version}
- pom
- import
-
-
- org.apache.camel
- camel-spring
- ${camel.version}
-
-
- org.apache.camel
- camel-spring-boot-starter
- ${camel.version}
-
-
- org.apache.camel
- camel-jackson
- ${camel.version}
-
-
- org.apache.camel
- camel-jms
- ${camel.version}
-
-
- org.apache.activemq
- activemq-camel
- ${activemq.version}
-
-
- org.apache.activemq
- activemq-pool
- ${activemq.version}
-
-
- net.sf.jopt-simple
- jopt-simple
- 4.9
-
-
- cglib
- cglib
- 3.2.4
-
-
- org.spockframework
- spock-spring
- 1.0-groovy-2.4
-
-
- org.spockframework
- spock-core
- 1.0-groovy-2.4
-
-
- info.solidsoft.spock
- spock-global-unroll
- 0.5.0
-
-
- org.springframework.amqp
- spring-rabbit
- 1.6.2.RELEASE
-
-
- org.mockito
- mockito-core
- 1.10.19
-
-
- io.specto
- hoverfly-junit
- 0.1.8
-
-
- org.apache.commons
- commons-lang3
- 3.4
-
-
- au.com.dius
- pact-jvm-model
- 2.4.18
-
-
- com.github.jknack
- handlebars
- 4.0.6
-
-
- org.springframework.cloud
- spring-cloud-contract-dependencies
- ${project.version}
- pom
- import
-
-
- org.springframework.boot
- spring-boot-dependencies
- ${spring-boot.version}
- pom
- import
-
-
- org.springframework.cloud
- spring-cloud-netflix-dependencies
- ${spring-cloud-netflix.version}
- pom
- import
-
-
- org.springframework.cloud
- spring-cloud-stream-dependencies
- ${spring-cloud-stream.version}
- pom
- import
-
-
- org.springframework.cloud
- spring-cloud-zookeeper-dependencies
- ${spring-cloud-zookeeper.version}
- pom
- import
-
-
- org.springframework.cloud
- spring-cloud-consul-dependencies
- ${spring-cloud-consul.version}
- pom
- import
-
-
-
-
-
- [3.2.1,)
-
-
-
- Spring
- https://spring.io/
-
-
-
-
- mariuszs
- Mariusz Smykula
- mariuszs@gmail.com
-
-
- marcingrzejszczak
- Marcin Grzejszczak
- mgrzejszczak@pivotal.io
-
-
- dsyer
- David Syer
- dsyer@pivotal.io
-
-
-
-
- scm:git:https://github.com/spring-cloud/spring-cloud-contract.git
- scm:git:git@github.com:spring-cloud/spring-cloud-contract.git
- https://github.com/spring-cloud/spring-cloud-contract
- HEAD
-
-
-
- GitHub
- https://github.com/spring-cloud/spring-cloud-contract/issues
-
-
-
- CircleCi
- https://circleci.com/gh/spring-cloud/spring-cloud-contract
-
-
-
-
-
-
- org.apache.maven.plugins
- maven-surefire-plugin
-
-
- **/*Spec.*
- **/*Tests.*
- **/*Test.*
-
- plain
-
-
-
- org.codehaus.plexus
- plexus-component-metadata
- 1.6
-
-
- maven-plugin-plugin
- ${maven.plugin.plugin.version}
-
-
- io.takari.maven.plugins
- takari-lifecycle-plugin
- 1.12.0
-
-
- org.eluder.coveralls
- coveralls-maven-plugin
- 4.1.0
-
-
- org.codehaus.gmavenplus
- gmavenplus-plugin
- 1.5
-
-
-
-
-
- org.apache.maven.plugins
- maven-clean-plugin
- 3.0.0
-
-
-
- target
-
-
-
-
-
- org.apache.maven.plugins
- maven-checkstyle-plugin
- ${checkstyle.version}
-
-
- org.springframework.cloud
- spring-cloud-build-tools
- ${spring-cloud-build.version}
-
-
-
-
- validate
- validate
-
- checkstyle.xml
- LICENSE.txt
- true
- true
- ${project.build.directory}/**
-
-
- check
-
-
-
-
-
-
-
-
-
-
- org.apache.maven.plugins
- maven-checkstyle-plugin
- ${checkstyle.version}
-
- checkstyle.xml
- LICENSE.txt
- ${project.build.directory}/**
-
-
-
-
-
-
-
- spring
-
-
- spring-snapshots
- Spring Snapshots
- https://repo.spring.io/libs-snapshot-local
-
- true
-
-
- false
-
-
-
- spring-milestones
- Spring Milestones
- https://repo.spring.io/libs-milestone-local
-
- false
-
-
-
- spring-releases
- Spring Releases
- https://repo.spring.io/release
-
- false
-
-
-
-
-
- spring-snapshots
- Spring Snapshots
- https://repo.spring.io/libs-snapshot-local
-
- true
-
-
- false
-
-
-
- spring-milestones
- Spring Milestones
- https://repo.spring.io/libs-milestone-local
-
- false
-
-
-
- spring-releases
- Spring Releases
- https://repo.spring.io/libs-release-local
-
- false
-
-
-
-
-
- sonar
-
-
-
- org.jacoco
- jacoco-maven-plugin
-
-
- pre-unit-test
-
- prepare-agent
-
-
- surefireArgLine
- ${project.build.directory}/jacoco.exec
-
-
-
- post-unit-test
- test
-
- report
-
-
-
- ${project.build.directory}/jacoco.exec
-
-
-
-
-
- org.apache.maven.plugins
- maven-surefire-plugin
-
-
- ${surefireArgLine}
-
-
-
-
-
-
-
-
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-contract/spring-cloud-contract-dependencies/pom.xml b/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-contract/spring-cloud-contract-dependencies/pom.xml
deleted file mode 100644
index 2ea7e734..00000000
--- a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-contract/spring-cloud-contract-dependencies/pom.xml
+++ /dev/null
@@ -1,233 +0,0 @@
-
-
- 4.0.0
-
- spring-cloud-dependencies-parent
- org.springframework.cloud
- 1.3.1.BUILD-SNAPSHOT
-
-
- spring-cloud-contract-dependencies
- 1.1.0.BUILD-SNAPSHOT
- pom
- spring-cloud-contract-dependencies
- Spring Cloud Contract Dependencies
-
- 2.5.1
- 0.4.8
- 1.0.2.v20150114
-
-
-
-
- org.springframework.cloud
- spring-cloud-contract-wiremock
- ${project.version}
-
-
- org.springframework.cloud
- spring-cloud-contract-spec
- ${project.version}
-
-
- org.springframework.cloud
- spring-cloud-contract-verifier
- ${project.version}
-
-
- org.springframework.cloud
- spring-cloud-contract-converters
- ${project.version}
-
-
- org.springframework.cloud
- spring-cloud-contract-spec-pact
- ${project.version}
-
-
- org.springframework.cloud
- spring-cloud-contract-stub-runner
- ${project.version}
-
-
- org.springframework.cloud
- spring-cloud-starter-contract-verifier
- ${project.version}
-
-
- org.springframework.cloud
- spring-cloud-starter-contract-stub-runner
- ${project.version}
-
-
- org.springframework.cloud
- spring-cloud-starter-contract-stub-runner-jetty
- ${project.version}
-
-
- org.springframework.cloud
- spring-cloud-contract-maven-plugin
- ${project.version}
-
-
- org.springframework.cloud
- spring-cloud-contract-gradle-plugin
- ${project.version}
-
-
- com.github.tomakehurst
- wiremock
- ${wiremock.version}
-
-
- org.mortbay.jetty
- jetty
-
-
- org.apache.httpcomponents
- httpclient
-
-
- com.jayway.jsonpath
- json-path
-
-
- net.sf.jopt-simple
- jopt-simple
-
-
- jetty-server
- org.eclipse.jetty
-
-
- jetty-servlet
- org.eclipse.jetty
-
-
- jetty-servlets
- org.eclipse.jetty
-
-
- jetty-webapp
- org.eclipse.jetty
-
-
-
-
- com.toomuchcoding.jsonassert
- jsonassert
- ${jsonassert.version}
-
-
- com.jayway.restassured
- spring-mock-mvc
- 2.9.0
-
-
- spring-web
- org.springframework
-
-
- spring-webmvc
- org.springframework
-
-
- spring-test
- org.springframework
-
-
-
-
- org.eclipse.aether
- aether-api
- ${aether.version}
-
-
- org.eclipse.aether
- aether-impl
- ${aether.version}
-
-
- org.eclipse.aether
- aether-transport-file
- ${aether.version}
-
-
- org.eclipse.aether
- aether-transport-http
- ${aether.version}
-
-
- org.eclipse.aether
- aether-connector-basic
- ${aether.version}
-
-
- org.apache.maven
- maven-aether-provider
- 3.2.1
-
-
- org.apache.maven
- maven-settings-builder
- 3.2.1
-
-
-
-
-
- spring
-
-
- spring-snapshots
- Spring Snapshots
- https://repo.spring.io/libs-snapshot-local
-
- true
-
-
- false
-
-
-
- spring-milestones
- Spring Milestones
- https://repo.spring.io/libs-milestone-local
-
- false
-
-
-
- spring-releases
- Spring Releases
- https://repo.spring.io/release
-
- false
-
-
-
-
-
- spring-snapshots
- Spring Snapshots
- https://repo.spring.io/libs-snapshot-local
-
- true
-
-
- false
-
-
-
- spring-milestones
- Spring Milestones
- https://repo.spring.io/libs-milestone-local
-
- false
-
-
-
-
-
-
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-contract/spring-cloud-contract-tools/pom.xml b/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-contract/spring-cloud-contract-tools/pom.xml
deleted file mode 100644
index 67ce9f8f..00000000
--- a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-contract/spring-cloud-contract-tools/pom.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-
-
- 4.0.0
-
-
- org.springframework.cloud
- spring-cloud-contract-parent
-
- ..
-
-
- spring-cloud-contract-tools
- pom
-
- Spring Cloud Contract Tools
- Spring Cloud Contract Tools
-
-
- spring-cloud-contract-converters
- spring-cloud-contract-spec-pact
- spring-cloud-contract-maven-plugin
- spring-cloud-contract-gradle-plugin
-
-
-
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-contract/spring-cloud-contract-tools/spring-cloud-contract-converters/pom.xml b/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-contract/spring-cloud-contract-tools/spring-cloud-contract-converters/pom.xml
deleted file mode 100644
index 7873089a..00000000
--- a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-contract/spring-cloud-contract-tools/spring-cloud-contract-converters/pom.xml
+++ /dev/null
@@ -1,78 +0,0 @@
-
-
- 4.0.0
-
- org.springframework.cloud
- spring-cloud-contract-tools
-
- ..
-
- spring-cloud-contract-converters
- jar
- Spring Cloud Contract Converters
- Spring Cloud Contract Converters
- 1.8
-
-
- org.springframework
- spring-context
-
-
- org.springframework.cloud
- spring-cloud-contract-spec
-
-
- org.springframework.cloud
- spring-cloud-contract-verifier
-
-
- org.springframework.boot
- spring-boot-starter-logging
-
-
- org.codehaus.groovy
- groovy
-
-
- org.codehaus.groovy
- groovy-nio
-
-
- com.github.tomakehurst
- wiremock
-
-
- org.spockframework
- spock-core
- test
-
-
- org.springframework.boot
- spring-boot-starter-test
- test
-
-
- info.solidsoft.spock
- spock-global-unroll
- test
-
-
-
-
-
- org.codehaus.gmavenplus
- gmavenplus-plugin
-
-
-
- addSources
- compile
- testCompile
-
-
-
-
-
-
-
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/.gitignore b/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/.gitignore
deleted file mode 100644
index 1667f838..00000000
--- a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/.gitignore
+++ /dev/null
@@ -1,17 +0,0 @@
-*~
-#*
-*#
-.#*
-.classpath
-.project
-.settings
-.springBeans
-.gradle
-build
-bin
-target/
-.idea
-*.iml
-*.ipr
-*.iws
-.factorypath
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/.settings.xml b/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/.settings.xml
deleted file mode 100644
index 6c355129..00000000
--- a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/.settings.xml
+++ /dev/null
@@ -1,66 +0,0 @@
-
-
-
-
- repo.spring.io
- ${env.CI_DEPLOY_USERNAME}
- ${env.CI_DEPLOY_PASSWORD}
-
-
-
-
-
- spring
- true
-
-
- spring-snapshots
- Spring Snapshots
- http://repo.spring.io/libs-snapshot-local
-
- true
-
-
-
- spring-milestones
- Spring Milestones
- http://repo.spring.io/libs-milestone-local
-
- false
-
-
-
- spring-releases
- Spring Releases
- http://repo.spring.io/release
-
- false
-
-
-
-
-
- spring-snapshots
- Spring Snapshots
- http://repo.spring.io/libs-snapshot-local
-
- true
-
-
-
- spring-milestones
- Spring Milestones
- http://repo.spring.io/libs-milestone-local
-
- false
-
-
-
-
-
-
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/.travis.yml b/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/.travis.yml
deleted file mode 100644
index 87c1ea4b..00000000
--- a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/.travis.yml
+++ /dev/null
@@ -1,9 +0,0 @@
-sudo: false
-cache:
- directories:
- - $HOME/.m2
-language: java
-before_install:
- - gem install asciidoctor
-script:
-- ./mvnw clean install -P docs -q -U -Dmaven.test.redirectTestOutputToFile=true
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/LICENSE.txt b/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/LICENSE.txt
deleted file mode 100644
index d6456956..00000000
--- a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/LICENSE.txt
+++ /dev/null
@@ -1,202 +0,0 @@
-
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
-
- APPENDIX: How to apply the Apache License to your work.
-
- To apply the Apache License to your work, attach the following
- boilerplate notice, with the fields enclosed by brackets "[]"
- replaced with your own identifying information. (Don't include
- the brackets!) The text should be enclosed in the appropriate
- comment syntax for the file format. We also recommend that a
- file or class name and description of purpose be included on the
- same "printed page" as the copyright notice for easier
- identification within third-party archives.
-
- Copyright [yyyy] [name of copyright owner]
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/README.adoc b/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/README.adoc
deleted file mode 100644
index 19ece70a..00000000
--- a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/README.adoc
+++ /dev/null
@@ -1,85 +0,0 @@
-// Do not edit this file (e.g. go instead to src/main/asciidoc)
-
-Spring Cloud Release Train is a curated set of dependencies across a
-range of Spring Cloud projects. You consume it by using the
-spring-cloud-dependencies POM to manage dependencies in Maven or
-Gradle. The release trains have names, not versions, to avoid
-confusion with the sub-projects. The names are an alphabetic sequence
-(so you can sort them chronologically) with names of London Tube
-stations ("Angel" is the first release, "Brixton" is the second).
-
-== Contributing
-
-Spring Cloud is released under the non-restrictive Apache 2.0 license,
-and follows a very standard Github development process, using Github
-tracker for issues and merging pull requests into master. If you want
-to contribute even something trivial please do not hesitate, but
-follow the guidelines below.
-
-=== Sign the Contributor License Agreement
-Before we accept a non-trivial patch or pull request we will need you to sign the
-https://cla.pivotal.io/sign/spring[Contributor License Agreement].
-Signing the contributor's agreement does not grant anyone commit rights to the main
-repository, but it does mean that we can accept your contributions, and you will get an
-author credit if we do. Active contributors might be asked to join the core team, and
-given the ability to merge pull requests.
-
-=== Code of Conduct
-This project adheres to the Contributor Covenant https://github.com/spring-cloud/spring-cloud-build/blob/master/docs/src/main/asciidoc/code-of-conduct.adoc[code of
-conduct]. By participating, you are expected to uphold this code. Please report
-unacceptable behavior to spring-code-of-conduct@pivotal.io.
-
-=== Code Conventions and Housekeeping
-None of these is essential for a pull request, but they will all help. They can also be
-added after the original pull request but before a merge.
-
-* Use the Spring Framework code format conventions. If you use Eclipse
- you can import formatter settings using the
- `eclipse-code-formatter.xml` file from the
- https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/master/spring-cloud-dependencies-parent/eclipse-code-formatter.xml[Spring
- Cloud Build] project. If using IntelliJ, you can use the
- http://plugins.jetbrains.com/plugin/6546[Eclipse Code Formatter
- Plugin] to import the same file.
-* Make sure all new `.java` files to have a simple Javadoc class comment with at least an
- `@author` tag identifying you, and preferably at least a paragraph on what the class is
- for.
-* Add the ASF license header comment to all new `.java` files (copy from existing files
- in the project)
-* Add yourself as an `@author` to the .java files that you modify substantially (more
- than cosmetic changes).
-* Add some Javadocs and, if you change the namespace, some XSD doc elements.
-* A few unit tests would help a lot as well -- someone has to do it.
-* If no-one else is using your branch, please rebase it against the current master (or
- other target branch in the main project).
-* When writing a commit message please follow http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html[these conventions],
- if you are fixing an existing issue please add `Fixes gh-XXXX` at the end of the commit
- message (where XXXX is the issue number).
-
-== Building and Deploying
-
-Since there is no code to compile in the starters they should do not need to compile, but a compiler has to be available because they are built and deployed as JAR artifacts. To install locally:
-
-----
-
-$ mvn install -s .settings.xml
-----
-
-and to deploy snapshots to repo.spring.io:
-
-----
-$ mvn install -DaltSnapshotDeploymentRepository=repo.spring.io::default::https://repo.spring.io/libs-snapshot-local
-----
-
-for a.BUILD-SNAPSHOT build use
-
-----
-$ mvn install -DaltReleaseDeploymentRepository=repo.spring.io::default::https://repo.spring.io/libs-release-local
-----
-
-and for Maven Central use
-
-----
-$ mvn install -P central -DaltReleaseDeploymentRepository=sonatype-nexus-staging::default::https://oss.sonatype.org/service/local/staging/deploy/maven2
-----
-
-(the "central" profile is available for all projects in Spring Cloud and it sets up the gpg jar signing, and the repository has to be specified separately for this project because it is a parent of the starter parent which users in turn have as their own parent).
\ No newline at end of file
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/docs/pom.xml b/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/docs/pom.xml
deleted file mode 100644
index 34780916..00000000
--- a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/docs/pom.xml
+++ /dev/null
@@ -1,54 +0,0 @@
-
-
- 4.0.0
- org.springframework.cloud
- spring-cloud-starter-docs
-
- org.springframework.cloud
- spring-cloud-starter-build
- Dalston.BUILD-SNAPSHOT
-
- pom
- Spring Cloud Starter Docs
- Spring Cloud Docs
-
- spring-cloud-starters
- ${basedir}/..
- Brixton,Camden,Dalston
-
-
-
-
- maven-deploy-plugin
-
- true
-
-
-
-
-
-
- docs
-
-
-
- org.asciidoctor
- asciidoctor-maven-plugin
- false
-
-
- org.apache.maven.plugins
- maven-antrun-plugin
- false
-
-
- org.codehaus.mojo
- build-helper-maven-plugin
- false
-
-
-
-
-
-
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/docs/src/main/asciidoc/README.adoc b/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/docs/src/main/asciidoc/README.adoc
deleted file mode 100644
index 454dda11..00000000
--- a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/docs/src/main/asciidoc/README.adoc
+++ /dev/null
@@ -1,34 +0,0 @@
-include::intro.adoc[]
-
-== Contributing
-
-include::https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/master/docs/src/main/asciidoc/contributing.adoc[]
-
-== Building and Deploying
-
-Since there is no code to compile in the starters they should do not need to compile, but a compiler has to be available because they are built and deployed as JAR artifacts. To install locally:
-
-----
-
-$ mvn install -s .settings.xml
-----
-
-and to deploy snapshots to repo.spring.io:
-
-----
-$ mvn install -DaltSnapshotDeploymentRepository=repo.spring.io::default::https://repo.spring.io/libs-snapshot-local
-----
-
-for a.BUILD-SNAPSHOT build use
-
-----
-$ mvn install -DaltReleaseDeploymentRepository=repo.spring.io::default::https://repo.spring.io/libs-release-local
-----
-
-and for Maven Central use
-
-----
-$ mvn install -P central -DaltReleaseDeploymentRepository=sonatype-nexus-staging::default::https://oss.sonatype.org/service/local/staging/deploy/maven2
-----
-
-(the "central" profile is available for all projects in Spring Cloud and it sets up the gpg jar signing, and the repository has to be specified separately for this project because it is a parent of the starter parent which users in turn have as their own parent).
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/docs/src/main/asciidoc/ghpages.sh b/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/docs/src/main/asciidoc/ghpages.sh
deleted file mode 100755
index a51d13c3..00000000
--- a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/docs/src/main/asciidoc/ghpages.sh
+++ /dev/null
@@ -1,330 +0,0 @@
-#!/bin/bash -x
-
-set -e
-
-# Set default props like MAVEN_PATH, ROOT_FOLDER etc.
-function set_default_props() {
- # The script should be executed from the root folder
- ROOT_FOLDER=`pwd`
- echo "Current folder is ${ROOT_FOLDER}"
-
- if [[ ! -e "${ROOT_FOLDER}/.git" ]]; then
- echo "You're not in the root folder of the project!"
- exit 1
- fi
-
- # Prop that will let commit the changes
- COMMIT_CHANGES="no"
- MAVEN_PATH=${MAVEN_PATH:-}
- echo "Path to Maven is [${MAVEN_PATH}]"
- REPO_NAME=${PWD##*/}
- echo "Repo name is [${REPO_NAME}]"
- SPRING_CLOUD_STATIC_REPO=${SPRING_CLOUD_STATIC_REPO:-git@github.com:spring-cloud/spring-cloud-static.git}
- echo "Spring Cloud Static repo is [${SPRING_CLOUD_STATIC_REPO}"
-}
-
-# Check if gh-pages exists and docs have been built
-function check_if_anything_to_sync() {
- git remote set-url --push origin `git config remote.origin.url | sed -e 's/^git:/https:/'`
-
- if ! (git remote set-branches --add origin gh-pages && git fetch -q); then
- echo "No gh-pages, so not syncing"
- exit 0
- fi
-
- if ! [ -d docs/target/generated-docs ] && ! [ "${BUILD}" == "yes" ]; then
- echo "No gh-pages sources in docs/target/generated-docs, so not syncing"
- exit 0
- fi
-}
-
-function retrieve_current_branch() {
- # Code getting the name of the current branch. For master we want to publish as we did until now
- # http://stackoverflow.com/questions/1593051/how-to-programmatically-determine-the-current-checked-out-git-branch
- # If there is a branch already passed will reuse it - otherwise will try to find it
- CURRENT_BRANCH=${BRANCH}
- if [[ -z "${CURRENT_BRANCH}" ]] ; then
- CURRENT_BRANCH=$(git symbolic-ref -q HEAD)
- CURRENT_BRANCH=${CURRENT_BRANCH##refs/heads/}
- CURRENT_BRANCH=${CURRENT_BRANCH:-HEAD}
- fi
- echo "Current branch is [${CURRENT_BRANCH}]"
- git checkout ${CURRENT_BRANCH} || echo "Failed to check the branch... continuing with the script"
-}
-
-# Switches to the provided value of the release version. We always prefix it with `v`
-function switch_to_tag() {
- git checkout v${VERSION}
-}
-
-# Build the docs if switch is on
-function build_docs_if_applicable() {
- if [[ "${BUILD}" == "yes" ]] ; then
- ./mvnw clean install -P docs -pl docs -DskipTests
- fi
-}
-
-# Get the name of the `docs.main` property
-# Get whitelisted branches - assumes that a `docs` module is available under `docs` profile
-function retrieve_doc_properties() {
- MAIN_ADOC_VALUE=$("${MAVEN_PATH}"mvn -q \
- -Dexec.executable="echo" \
- -Dexec.args='${docs.main}' \
- --non-recursive \
- org.codehaus.mojo:exec-maven-plugin:1.3.1:exec)
- echo "Extracted 'main.adoc' from Maven build [${MAIN_ADOC_VALUE}]"
-
-
- WHITELIST_PROPERTY=${WHITELIST_PROPERTY:-"docs.whitelisted.branches"}
- WHITELISTED_BRANCHES_VALUE=$("${MAVEN_PATH}"mvn -q \
- -Dexec.executable="echo" \
- -Dexec.args="\${${WHITELIST_PROPERTY}}" \
- org.codehaus.mojo:exec-maven-plugin:1.3.1:exec \
- -P docs \
- -pl docs)
- echo "Extracted '${WHITELIST_PROPERTY}' from Maven build [${WHITELISTED_BRANCHES_VALUE}]"
-}
-
-# Stash any outstanding changes
-function stash_changes() {
- git diff-index --quiet HEAD && dirty=$? || (echo "Failed to check if the current repo is dirty. Assuming that it is." && dirty="1")
- if [ "$dirty" != "0" ]; then git stash; fi
-}
-
-# Switch to gh-pages branch to sync it with current branch
-function add_docs_from_target() {
- local DESTINATION_REPO_FOLDER
- if [[ -z "${DESTINATION}" && -z "${CLONE}" ]] ; then
- DESTINATION_REPO_FOLDER=${ROOT_FOLDER}
- elif [[ "${CLONE}" == "yes" ]]; then
- mkdir -p ${ROOT_FOLDER}/target
- local clonedStatic=${ROOT_FOLDER}/target/spring-cloud-static
- if [[ ! -e "${clonedStatic}/.git" ]]; then
- echo "Cloning Spring Cloud Static to target"
- git clone ${SPRING_CLOUD_STATIC_REPO} ${clonedStatic} && git checkout gh-pages
- else
- echo "Spring Cloud Static already cloned - will pull changes"
- cd ${clonedStatic} && git checkout gh-pages && git pull origin gh-pages
- fi
- DESTINATION_REPO_FOLDER=${clonedStatic}/${REPO_NAME}
- mkdir -p ${DESTINATION_REPO_FOLDER}
- else
- if [[ ! -e "${DESTINATION}/.git" ]]; then
- echo "[${DESTINATION}] is not a git repository"
- exit 1
- fi
- DESTINATION_REPO_FOLDER=${DESTINATION}/${REPO_NAME}
- mkdir -p ${DESTINATION_REPO_FOLDER}
- echo "Destination was provided [${DESTINATION}]"
- fi
- cd ${DESTINATION_REPO_FOLDER}
- git checkout gh-pages
- git pull origin gh-pages
-
- # Add git branches
- ###################################################################
- if [[ -z "${VERSION}" ]] ; then
- copy_docs_for_current_version
- else
- copy_docs_for_provided_version
- fi
- commit_changes_if_applicable
-}
-
-
-# Copies the docs by using the retrieved properties from Maven build
-function copy_docs_for_current_version() {
- if [[ "${CURRENT_BRANCH}" == "master" ]] ; then
- echo -e "Current branch is master - will copy the current docs only to the root folder"
- for f in docs/target/generated-docs/*; do
- file=${f#docs/target/generated-docs/*}
- if ! git ls-files -i -o --exclude-standard --directory | grep -q ^$file$; then
- # Not ignored...
- cp -rf $f ${ROOT_FOLDER}/
- git add -A ${ROOT_FOLDER}/$file
- fi
- done
- COMMIT_CHANGES="yes"
- else
- echo -e "Current branch is [${CURRENT_BRANCH}]"
- # http://stackoverflow.com/questions/29300806/a-bash-script-to-check-if-a-string-is-present-in-a-comma-separated-list-of-strin
- if [[ ",${WHITELISTED_BRANCHES_VALUE}," = *",${CURRENT_BRANCH},"* ]] ; then
- mkdir -p ${ROOT_FOLDER}/${CURRENT_BRANCH}
- echo -e "Branch [${CURRENT_BRANCH}] is whitelisted! Will copy the current docs to the [${CURRENT_BRANCH}] folder"
- for f in docs/target/generated-docs/*; do
- file=${f#docs/target/generated-docs/*}
- if ! git ls-files -i -o --exclude-standard --directory | grep -q ^$file$; then
- # Not ignored...
- # We want users to access 1.0.0.BUILD-SNAPSHOT/ instead of 1.0.0.RELEASE/spring-cloud.sleuth.html
- if [[ "${file}" == "${MAIN_ADOC_VALUE}.html" ]] ; then
- # We don't want to copy the spring-cloud-sleuth.html
- # we want it to be converted to index.html
- cp -rf $f ${ROOT_FOLDER}/${CURRENT_BRANCH}/index.html
- git add -A ${ROOT_FOLDER}/${CURRENT_BRANCH}/index.html
- else
- cp -rf $f ${ROOT_FOLDER}/${CURRENT_BRANCH}
- git add -A ${ROOT_FOLDER}/${CURRENT_BRANCH}/$file
- fi
- fi
- done
- COMMIT_CHANGES="yes"
- else
- echo -e "Branch [${CURRENT_BRANCH}] is not on the white list! Check out the Maven [${WHITELIST_PROPERTY}] property in
- [docs] module available under [docs] profile. Won't commit any changes to gh-pages for this branch."
- fi
- fi
-}
-
-# Copies the docs by using the explicitly provided version
-function copy_docs_for_provided_version() {
- local FOLDER=${DESTINATION_REPO_FOLDER}/${VERSION}
- mkdir -p ${FOLDER}
- echo -e "Current tag is [v${VERSION}] Will copy the current docs to the [${FOLDER}] folder"
- for f in ${ROOT_FOLDER}/docs/target/generated-docs/*; do
- file=${f#${ROOT_FOLDER}/docs/target/generated-docs/*}
- copy_docs_for_branch ${file} ${FOLDER}
- done
- COMMIT_CHANGES="yes"
- CURRENT_BRANCH="v${VERSION}"
-}
-
-# Copies the docs from target to the provided destination
-# Params:
-# $1 - file from target
-# $2 - destination to which copy the files
-function copy_docs_for_branch() {
- local file=$1
- local destination=$2
- if ! git ls-files -i -o --exclude-standard --directory | grep -q ^${file}$; then
- # Not ignored...
- # We want users to access 1.0.0.BUILD-SNAPSHOT/ instead of 1.0.0.RELEASE/spring-cloud.sleuth.html
- if [[ ("${file}" == "${MAIN_ADOC_VALUE}.html") || ("${file}" == "${REPO_NAME}.html") ]] ; then
- # We don't want to copy the spring-cloud-sleuth.html
- # we want it to be converted to index.html
- cp -rf $f ${destination}/index.html
- git add -A ${destination}/index.html
- else
- cp -rf $f ${destination}
- git add -A ${destination}/$file
- fi
- fi
-}
-
-function commit_changes_if_applicable() {
- if [[ "${COMMIT_CHANGES}" == "yes" ]] ; then
- COMMIT_SUCCESSFUL="no"
- git commit -a -m "Sync docs from ${CURRENT_BRANCH} to gh-pages" && COMMIT_SUCCESSFUL="yes" || echo "Failed to commit changes"
-
- # Uncomment the following push if you want to auto push to
- # the gh-pages branch whenever you commit to master locally.
- # This is a little extreme. Use with care!
- ###################################################################
- if [[ "${COMMIT_SUCCESSFUL}" == "yes" ]] ; then
- git push origin gh-pages
- fi
- fi
-}
-
-# Switch back to the previous branch and exit block
-function checkout_previous_branch() {
- # If -version was provided we need to come back to root project
- cd ${ROOT_FOLDER}
- git checkout ${CURRENT_BRANCH} || echo "Failed to check the branch... continuing with the script"
- if [ "$dirty" != "0" ]; then git stash pop; fi
- exit 0
-}
-
-# Assert if properties have been properly passed
-function assert_properties() {
-echo "VERSION [${VERSION}], DESTINATION [${DESTINATION}], CLONE [${CLONE}]"
-if [[ "${VERSION}" != "" && (-z "${DESTINATION}" && -z "${CLONE}") ]] ; then echo "Version was set but destination / clone was not!"; exit 1;fi
-if [[ ("${DESTINATION}" != "" && "${CLONE}" != "") && -z "${VERSION}" ]] ; then echo "Destination / clone was set but version was not!"; exit 1;fi
-if [[ "${DESTINATION}" != "" && "${CLONE}" == "yes" ]] ; then echo "Destination and clone was set. Pick one!"; exit 1;fi
-}
-
-# Prints the usage
-function print_usage() {
-cat </`
-- if the destination switch is passed (-d) then the script will check if the provided dir is a git repo and then will
- switch to gh-pages of that repo and copy the generated docs to `docs//`
-
-USAGE:
-
-You can use the following options:
-
--v|--version - the script will apply the whole procedure for a particular library version
--d|--destination - the root of destination folder where the docs should be copied. You have to use the full path.
- E.g. point to spring-cloud-static folder. Can't be used with (-c)
--b|--build - will run the standard build process after checking out the branch
--c|--clone - will automatically clone the spring-cloud-static repo instead of providing the destination.
- Obviously can't be used with (-d)
-
-EOF
-}
-
-
-# ==========================================
-# ____ ____ _____ _____ _____ _______
-# / ____|/ ____| __ \|_ _| __ \__ __|
-# | (___ | | | |__) | | | | |__) | | |
-# \___ \| | | _ / | | | ___/ | |
-# ____) | |____| | \ \ _| |_| | | |
-# |_____/ \_____|_| \_\_____|_| |_|
-#
-# ==========================================
-
-while [[ $# > 0 ]]
-do
-key="$1"
-case ${key} in
- -v|--version)
- VERSION="$2"
- shift # past argument
- ;;
- -d|--destination)
- DESTINATION="$2"
- shift # past argument
- ;;
- -b|--build)
- BUILD="yes"
- ;;
- -c|--clone)
- CLONE="yes"
- ;;
- -h|--help)
- print_usage
- exit 0
- ;;
- *)
- echo "Invalid option: [$1]"
- print_usage
- exit 1
- ;;
-esac
-shift # past argument or value
-done
-
-assert_properties
-set_default_props
-check_if_anything_to_sync
-if [[ -z "${VERSION}" ]] ; then
- retrieve_current_branch
-else
- switch_to_tag
-fi
-build_docs_if_applicable
-retrieve_doc_properties
-stash_changes
-add_docs_from_target
-checkout_previous_branch
\ No newline at end of file
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/docs/src/main/asciidoc/intro.adoc b/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/docs/src/main/asciidoc/intro.adoc
deleted file mode 100644
index 5ae66a35..00000000
--- a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/docs/src/main/asciidoc/intro.adoc
+++ /dev/null
@@ -1,7 +0,0 @@
-Spring Cloud Release Train is a curated set of dependencies across a
-range of Spring Cloud projects. You consume it by using the
-spring-cloud-dependencies POM to manage dependencies in Maven or
-Gradle. The release trains have names, not versions, to avoid
-confusion with the sub-projects. The names are an alphabetic sequence
-(so you can sort them chronologically) with names of London Tube
-stations ("Angel" is the first release, "Brixton" is the second).
\ No newline at end of file
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/docs/src/main/asciidoc/spring-cloud-starters.adoc b/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/docs/src/main/asciidoc/spring-cloud-starters.adoc
deleted file mode 100644
index 4d473a4a..00000000
--- a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/docs/src/main/asciidoc/spring-cloud-starters.adoc
+++ /dev/null
@@ -1,65 +0,0 @@
-:github: https://github.com/spring-cloud/spring-cloud-release
-:githubmaster: {github}/tree/master
-:docslink: {githubmaster}/docs/src/main/asciidoc
-:springcloudversion: Dalston.BUILD-SNAPSHOT
-:springioplatformversion: Brussels-BUILD-SNAPSHOT
-:springBootVersion: 1.5.0.BUILD-SNAPSHOT
-
-= Spring Cloud Release Train
-
-include::intro.adoc[]
-
-== Using Spring Cloud Dependencies with Spring IO Platform
-
-The Spring IO Platform is a modular, enterprise-grade curated set of dependencies. To use the Spring Cloud Starters with Spring IO Platform, you must import the Spring Cloud Dependencies bill of materials (BOM) first.
-
-To use version {springioplatformversion} of the Spring IO Platform and Spring Cloud Release Train {springcloudversion} with Maven, update the pom.xml as follows:
-
-[source,xml,indent=0,subs="verbatim,attributes"]
-----
-
-
-
- org.springframework.cloud
- spring-cloud-dependencies
- {springcloudversion}
- pom
- import
-
-
- io.spring.platform
- platform-bom
- {springioplatformversion}
- pom
- import
-
-
-
-----
-
-NOTE: The Spring Cloud Dependencies BOM must go first, so that its dependencies have precedence of the Spring IO Platform dependencies.
-
-For gradle, update the build.gradle as follows:
-
-[source,groovy,indent=0,subs="verbatim,attributes"]
-----
-buildscript {
- repositories {
- mavenCentral()
- }
- dependencies {
- classpath("org.springframework.boot:spring-boot-gradle-plugin:{springBootVersion}")
- }
-}
-
-apply plugin: 'spring-boot'
-
-dependencyManagement {
- imports {
- mavenBom "org.springframework.cloud:spring-cloud-dependencies:{springcloudversion}"
- mavenBom 'io.spring.platform:platform-bom:{springioplatformversion}'
- }
-}
-----
-
-include::https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/master/docs/src/main/asciidoc/contributing-docs.adoc[]
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/docs/src/main/ruby/generate_readme.sh b/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/docs/src/main/ruby/generate_readme.sh
deleted file mode 100755
index 6d0ce9dc..00000000
--- a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/docs/src/main/ruby/generate_readme.sh
+++ /dev/null
@@ -1,37 +0,0 @@
-#!/usr/bin/env ruby
-
-base_dir = File.join(File.dirname(__FILE__),'../../..')
-src_dir = File.join(base_dir, "/src/main/asciidoc")
-require 'asciidoctor'
-require 'optparse'
-
-options = {}
-file = "#{src_dir}/README.adoc"
-
-OptionParser.new do |o|
- o.on('-o OUTPUT_FILE', 'Output file (default is stdout)') { |file| options[:to_file] = file unless file=='-' }
- o.on('-h', '--help') { puts o; exit }
- o.parse!
-end
-
-file = ARGV[0] if ARGV.length>0
-
-# Copied from https://github.com/asciidoctor/asciidoctor-extensions-lab/blob/master/scripts/asciidoc-coalescer.rb
-doc = Asciidoctor.load_file file, safe: :unsafe, header_only: true, attributes: options[:attributes]
-header_attr_names = (doc.instance_variable_get :@attributes_modified).to_a
-header_attr_names.each {|k| doc.attributes[%(#{k}!)] = '' unless doc.attr? k }
-attrs = doc.attributes
-attrs['allow-uri-read'] = true
-puts attrs
-
-out = "// Do not edit this file (e.g. go instead to src/main/asciidoc)\n\n"
-doc = Asciidoctor.load_file file, safe: :unsafe, parse: false, attributes: attrs
-out << doc.reader.read
-
-unless options[:to_file]
- puts out
-else
- File.open(options[:to_file],'w+') do |file|
- file.write(out)
- end
-end
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/FETCH_HEAD b/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/FETCH_HEAD
deleted file mode 100644
index 5330963c..00000000
--- a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/FETCH_HEAD
+++ /dev/null
@@ -1,14 +0,0 @@
-320597b84bb0312c15228c4d42f46c189b86ed90 branch 'master' of github.com:spring-cloud/spring-cloud-release
-fb730db9b3999e45c350015c6cf83be35910a159 not-for-merge branch '1.0.0.M2' of github.com:spring-cloud/spring-cloud-release
-474b03693496665434ab2615d6500bbb0b575a5b not-for-merge branch '1.0.0.M3' of github.com:spring-cloud/spring-cloud-release
-7fdc875cb2b1620e8bc87ef8a27da2858eef7cd1 not-for-merge branch '1.0.0.RC1' of github.com:spring-cloud/spring-cloud-release
-75d0bc7cc0995ac76b6cfad962ea54d05262a664 not-for-merge branch '1.0.0.RELEASE' of github.com:spring-cloud/spring-cloud-release
-8e8a2d41b4beb8985919bc5a2bca2aa66374bdbb not-for-merge branch '1.0.1.RELEASE' of github.com:spring-cloud/spring-cloud-release
-59414747ee8c095753a0b8c5641b328f80d47d33 not-for-merge branch '1.0.2.RELEASE' of github.com:spring-cloud/spring-cloud-release
-73ec179d7ce96d5a98c2acd5697cd81c49dfd7d5 not-for-merge branch '1.0.x' of github.com:spring-cloud/spring-cloud-release
-08c95747e807212c605d758bbb360f6d671b2932 not-for-merge branch 'Angel.SR3' of github.com:spring-cloud/spring-cloud-release
-6882449721e48f955b102606ae3fc2535ebbd4cb not-for-merge branch 'Brixton' of github.com:spring-cloud/spring-cloud-release
-7745834b138ffe1f647b14dd3c7d4d71eee8aac3 not-for-merge branch 'Brixton.M1' of github.com:spring-cloud/spring-cloud-release
-f2036f13515dc6aa997cc15827919acec634eaae not-for-merge branch 'Brixton.M2' of github.com:spring-cloud/spring-cloud-release
-928e0d8389dcee60189d6c0eb737ab9376e87f54 not-for-merge branch 'Camden.RC1' of github.com:spring-cloud/spring-cloud-release
-b566ab3bea0506bccaa10f83784a41673606d6ee not-for-merge branch 'Camden.x' of github.com:spring-cloud/spring-cloud-release
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/HEAD b/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/HEAD
deleted file mode 100644
index cb089cd8..00000000
--- a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/HEAD
+++ /dev/null
@@ -1 +0,0 @@
-ref: refs/heads/master
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/ORIG_HEAD b/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/ORIG_HEAD
deleted file mode 100644
index 8bff2828..00000000
--- a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/ORIG_HEAD
+++ /dev/null
@@ -1 +0,0 @@
-32ebcd2c317339400d65ad43999d4e5ddc05bd30
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/config b/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/config
deleted file mode 100644
index ee282a8a..00000000
--- a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/config
+++ /dev/null
@@ -1,7 +0,0 @@
-[core]
- repositoryformatversion = 0
- filemode = true
- bare = true
- logallrefupdates = true
-[branch "master"]
-[branch "Camden.x"]
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/description b/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/description
deleted file mode 100644
index 498b267a..00000000
--- a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/description
+++ /dev/null
@@ -1 +0,0 @@
-Unnamed repository; edit this file 'description' to name the repository.
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/index b/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/index
deleted file mode 100644
index 80297578..00000000
Binary files a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/index and /dev/null differ
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/logs/HEAD b/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/logs/HEAD
deleted file mode 100644
index c8d610e8..00000000
--- a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/logs/HEAD
+++ /dev/null
@@ -1,12 +0,0 @@
-0000000000000000000000000000000000000000 e1248f716b5656af04ded489b481db45ad3dfc8f Marcin Grzejszczak 1473364042 +0200 clone: from git@github.com:spring-cloud/spring-cloud-release.git
-e1248f716b5656af04ded489b481db45ad3dfc8f 1ab978f42299811efa4953b98a923699c95f6776 Marcin Grzejszczak 1474826109 +0200 checkout: moving from master to vCamden.RELEASE
-1ab978f42299811efa4953b98a923699c95f6776 e1248f716b5656af04ded489b481db45ad3dfc8f Marcin Grzejszczak 1474826610 +0200 checkout: moving from 1ab978f42299811efa4953b98a923699c95f6776 to master
-e1248f716b5656af04ded489b481db45ad3dfc8f b05cdc5318cbc5c049a391fe67ac4a8cf763689d Marcin Grzejszczak 1486373153 +0100 checkout: moving from master to Camden.x
-b05cdc5318cbc5c049a391fe67ac4a8cf763689d 25af4f2162cdf0642c78ea8e63c1744158b6ad1b Marcin Grzejszczak 1486377649 +0100 commit: Bumping versions before release
-25af4f2162cdf0642c78ea8e63c1744158b6ad1b a29f784a15fc3d039d4dfec619ebcddaf0ef8b8a Marcin Grzejszczak 1486378936 +0100 revert: Going back to snapshots
-a29f784a15fc3d039d4dfec619ebcddaf0ef8b8a b566ab3bea0506bccaa10f83784a41673606d6ee Marcin Grzejszczak 1486379057 +0100 commit (amend): Going back to snapshots
-b566ab3bea0506bccaa10f83784a41673606d6ee e1248f716b5656af04ded489b481db45ad3dfc8f Marcin Grzejszczak 1486379087 +0100 checkout: moving from Camden.x to master
-e1248f716b5656af04ded489b481db45ad3dfc8f 32ebcd2c317339400d65ad43999d4e5ddc05bd30 Marcin Grzejszczak 1486379095 +0100 pull --rebase origin master: checkout 32ebcd2c317339400d65ad43999d4e5ddc05bd30
-32ebcd2c317339400d65ad43999d4e5ddc05bd30 32ebcd2c317339400d65ad43999d4e5ddc05bd30 Marcin Grzejszczak 1486379095 +0100 rebase finished: returning to refs/heads/master
-32ebcd2c317339400d65ad43999d4e5ddc05bd30 320597b84bb0312c15228c4d42f46c189b86ed90 Marcin Grzejszczak 1488827673 +0100 pull --rebase origin master: checkout 320597b84bb0312c15228c4d42f46c189b86ed90
-320597b84bb0312c15228c4d42f46c189b86ed90 320597b84bb0312c15228c4d42f46c189b86ed90 Marcin Grzejszczak 1488827673 +0100 rebase finished: returning to refs/heads/master
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/logs/refs/heads/Camden.x b/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/logs/refs/heads/Camden.x
deleted file mode 100644
index 4885b95f..00000000
--- a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/logs/refs/heads/Camden.x
+++ /dev/null
@@ -1,4 +0,0 @@
-0000000000000000000000000000000000000000 b05cdc5318cbc5c049a391fe67ac4a8cf763689d Marcin Grzejszczak 1486373153 +0100 branch: Created from refs/remotes/origin/Camden.x
-b05cdc5318cbc5c049a391fe67ac4a8cf763689d 25af4f2162cdf0642c78ea8e63c1744158b6ad1b Marcin Grzejszczak 1486377649 +0100 commit: Bumping versions before release
-25af4f2162cdf0642c78ea8e63c1744158b6ad1b a29f784a15fc3d039d4dfec619ebcddaf0ef8b8a Marcin Grzejszczak 1486378936 +0100 revert: Going back to snapshots
-a29f784a15fc3d039d4dfec619ebcddaf0ef8b8a b566ab3bea0506bccaa10f83784a41673606d6ee Marcin Grzejszczak 1486379057 +0100 commit (amend): Going back to snapshots
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/logs/refs/heads/master b/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/logs/refs/heads/master
deleted file mode 100644
index b68bfdb1..00000000
--- a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/logs/refs/heads/master
+++ /dev/null
@@ -1,3 +0,0 @@
-0000000000000000000000000000000000000000 e1248f716b5656af04ded489b481db45ad3dfc8f Marcin Grzejszczak 1473364042 +0200 clone: from git@github.com:spring-cloud/spring-cloud-release.git
-e1248f716b5656af04ded489b481db45ad3dfc8f 32ebcd2c317339400d65ad43999d4e5ddc05bd30 Marcin Grzejszczak 1486379095 +0100 rebase finished: refs/heads/master onto 32ebcd2c317339400d65ad43999d4e5ddc05bd30
-32ebcd2c317339400d65ad43999d4e5ddc05bd30 320597b84bb0312c15228c4d42f46c189b86ed90 Marcin Grzejszczak 1488827673 +0100 rebase finished: refs/heads/master onto 320597b84bb0312c15228c4d42f46c189b86ed90
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/logs/refs/remotes/origin/Brixton b/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/logs/refs/remotes/origin/Brixton
deleted file mode 100644
index 9462eaac..00000000
--- a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/logs/refs/remotes/origin/Brixton
+++ /dev/null
@@ -1,2 +0,0 @@
-ccc57368d5e766e493c57f44333deae7eca6d864 7ac1649d4b941fdc03f877ab7d929a52018a1f75 Marcin Grzejszczak 1474826096 +0200 fetch: fast-forward
-7ac1649d4b941fdc03f877ab7d929a52018a1f75 6882449721e48f955b102606ae3fc2535ebbd4cb Marcin Grzejszczak 1486372922 +0100 fetch: fast-forward
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/logs/refs/remotes/origin/Camden.RC1 b/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/logs/refs/remotes/origin/Camden.RC1
deleted file mode 100644
index 4b689fa5..00000000
--- a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/logs/refs/remotes/origin/Camden.RC1
+++ /dev/null
@@ -1 +0,0 @@
-0000000000000000000000000000000000000000 928e0d8389dcee60189d6c0eb737ab9376e87f54 Marcin Grzejszczak 1474826096 +0200 fetch: storing head
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/logs/refs/remotes/origin/Camden.x b/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/logs/refs/remotes/origin/Camden.x
deleted file mode 100644
index 76c7e191..00000000
--- a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/logs/refs/remotes/origin/Camden.x
+++ /dev/null
@@ -1,2 +0,0 @@
-0000000000000000000000000000000000000000 b05cdc5318cbc5c049a391fe67ac4a8cf763689d Marcin Grzejszczak 1486372922 +0100 fetch: storing head
-b05cdc5318cbc5c049a391fe67ac4a8cf763689d b566ab3bea0506bccaa10f83784a41673606d6ee Marcin Grzejszczak 1486379066 +0100 update by push
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/logs/refs/remotes/origin/HEAD b/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/logs/refs/remotes/origin/HEAD
deleted file mode 100644
index 6e6747de..00000000
--- a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/logs/refs/remotes/origin/HEAD
+++ /dev/null
@@ -1 +0,0 @@
-0000000000000000000000000000000000000000 e1248f716b5656af04ded489b481db45ad3dfc8f Marcin Grzejszczak 1473364042 +0200 clone: from git@github.com:spring-cloud/spring-cloud-release.git
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/logs/refs/remotes/origin/master b/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/logs/refs/remotes/origin/master
deleted file mode 100644
index 4b630bbe..00000000
--- a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/logs/refs/remotes/origin/master
+++ /dev/null
@@ -1,3 +0,0 @@
-e1248f716b5656af04ded489b481db45ad3dfc8f 530a739b2abeaae75c267dec70ba03d507afe81b Marcin Grzejszczak 1474826096 +0200 fetch: fast-forward
-530a739b2abeaae75c267dec70ba03d507afe81b 32ebcd2c317339400d65ad43999d4e5ddc05bd30 Marcin Grzejszczak 1486372922 +0100 fetch: fast-forward
-32ebcd2c317339400d65ad43999d4e5ddc05bd30 320597b84bb0312c15228c4d42f46c189b86ed90 Marcin Grzejszczak 1488827673 +0100 pull --rebase origin master: fast-forward
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/logs/refs/stash b/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/logs/refs/stash
deleted file mode 100644
index 031c568d..00000000
--- a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/logs/refs/stash
+++ /dev/null
@@ -1 +0,0 @@
-0000000000000000000000000000000000000000 dd40ebe950c0a0cd5de542e3d0e7a0e1ac4e70aa Marcin Grzejszczak 1474826091 +0200 WIP on master: e1248f7 Revert to snapshots
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/02/bfd7c14f411309d0d710ca84c77cc68a1425e3 b/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/02/bfd7c14f411309d0d710ca84c77cc68a1425e3
deleted file mode 100644
index 1435f7c7..00000000
Binary files a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/02/bfd7c14f411309d0d710ca84c77cc68a1425e3 and /dev/null differ
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/05/2c269bb095f70ce6174838c2032ab8f9cf7bb3 b/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/05/2c269bb095f70ce6174838c2032ab8f9cf7bb3
deleted file mode 100644
index 07aab2ad..00000000
Binary files a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/05/2c269bb095f70ce6174838c2032ab8f9cf7bb3 and /dev/null differ
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/06/e0dc5816eb2b5c2a377d61848d9de4a3644ea5 b/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/06/e0dc5816eb2b5c2a377d61848d9de4a3644ea5
deleted file mode 100644
index 7eebed5f..00000000
Binary files a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/06/e0dc5816eb2b5c2a377d61848d9de4a3644ea5 and /dev/null differ
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/08/ca4797e9798630d33eb8977c25c48b1ad7002c b/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/08/ca4797e9798630d33eb8977c25c48b1ad7002c
deleted file mode 100644
index a885daf9..00000000
Binary files a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/08/ca4797e9798630d33eb8977c25c48b1ad7002c and /dev/null differ
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/09/33b69db0d39065595fe474ccdf590e95fcc984 b/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/09/33b69db0d39065595fe474ccdf590e95fcc984
deleted file mode 100644
index 75a397a3..00000000
Binary files a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/09/33b69db0d39065595fe474ccdf590e95fcc984 and /dev/null differ
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/09/46dce6d42e6209822f9ef1b36033b0af1a8309 b/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/09/46dce6d42e6209822f9ef1b36033b0af1a8309
deleted file mode 100644
index e099b60d..00000000
Binary files a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/09/46dce6d42e6209822f9ef1b36033b0af1a8309 and /dev/null differ
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/0a/7dac221c045701bf3c08f4d49ba80755e278af b/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/0a/7dac221c045701bf3c08f4d49ba80755e278af
deleted file mode 100644
index 434b334e..00000000
Binary files a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/0a/7dac221c045701bf3c08f4d49ba80755e278af and /dev/null differ
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/0c/d5c212471c054044677265d0306b6b8c281d60 b/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/0c/d5c212471c054044677265d0306b6b8c281d60
deleted file mode 100644
index fd486d61..00000000
Binary files a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/0c/d5c212471c054044677265d0306b6b8c281d60 and /dev/null differ
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/0e/73ce5907174c1734d1878f8f40899ee2df7d1f b/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/0e/73ce5907174c1734d1878f8f40899ee2df7d1f
deleted file mode 100644
index 3e995ba8..00000000
Binary files a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/0e/73ce5907174c1734d1878f8f40899ee2df7d1f and /dev/null differ
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/10/7afe2f2cfa57952648aecf534d4b7bf5253800 b/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/10/7afe2f2cfa57952648aecf534d4b7bf5253800
deleted file mode 100644
index 352610e0..00000000
--- a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/10/7afe2f2cfa57952648aecf534d4b7bf5253800
+++ /dev/null
@@ -1 +0,0 @@
-xν0@a>MLMqsr.-PH_FJtGZFWkVJFC\9lRqdqJQEkf*1
3 y ݼЂO8
[4v3TʮÞm%䱴>){*3i=V
\ No newline at end of file
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/10/f3c204347a6430d32435f25058cadd954f9b1a b/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/10/f3c204347a6430d32435f25058cadd954f9b1a
deleted file mode 100644
index d31efbc8..00000000
--- a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/10/f3c204347a6430d32435f25058cadd954f9b1a
+++ /dev/null
@@ -1,3 +0,0 @@
-x+)JMU013g040031QK,L/JeKa*~9vf]M@A/,aq]~Y,|\8y0DZ<
fHqjIIf^z^EnCi7KʹNtٴϧ0%Eez@e_ygoPg'*tvv+(aVl2uNƺ\|C:%'3Hyε@ٓ1Quמ q]8EOxSÛ/vK0@t\L/-Rkdї/`Sa̯[n!Uac@6;h¶ḽ
-]]MsZ\H!!X
-NH'o1d1ŝ+g@Jιon6hw|lE2ir1IDMU_Cxz^@.Vgu-
-݅
-
QwՊQ]UOVCĿW_5я#M1K_+S&ַHqo~IW.9_jl;|Ȭpj8z)tOQ.wqCpFEҚ
-j c vbYq)]#F螙b "hͦw#G%,ٔ~'+zf)<ۿDs4ݱ`wc
\ No newline at end of file
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/29/c61ee1a6d625b44cc7e23d086a8cf2adf2542a b/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/29/c61ee1a6d625b44cc7e23d086a8cf2adf2542a
deleted file mode 100644
index cff53bab..00000000
Binary files a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/29/c61ee1a6d625b44cc7e23d086a8cf2adf2542a and /dev/null differ
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/2e/3905698baa4969a8e27d6d347146c4f10b662d b/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/2e/3905698baa4969a8e27d6d347146c4f10b662d
deleted file mode 100644
index ae2ffa59..00000000
Binary files a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/2e/3905698baa4969a8e27d6d347146c4f10b662d and /dev/null differ
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/32/0597b84bb0312c15228c4d42f46c189b86ed90 b/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/32/0597b84bb0312c15228c4d42f46c189b86ed90
deleted file mode 100644
index f751df95..00000000
--- a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/32/0597b84bb0312c15228c4d42f46c189b86ed90
+++ /dev/null
@@ -1 +0,0 @@
-xmMJ@a9E]`ADEpQ!]gILe
_IE"cߑl8mI\>qlE&$v981ac]e*)gVf܁
]rWu3S]dٌl?9
\ No newline at end of file
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/57/8e15047403e46a1a05f7d45ced53dc89eb59b7 b/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/57/8e15047403e46a1a05f7d45ced53dc89eb59b7
deleted file mode 100644
index d742afad..00000000
Binary files a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/57/8e15047403e46a1a05f7d45ced53dc89eb59b7 and /dev/null differ
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/59/9d7f6c393d6dada17584ef3af4cd9e4ed432d6 b/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/59/9d7f6c393d6dada17584ef3af4cd9e4ed432d6
deleted file mode 100644
index 7280d774..00000000
Binary files a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/59/9d7f6c393d6dada17584ef3af4cd9e4ed432d6 and /dev/null differ
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/59/dce50b38ffedd9a73b50278faab9b041d1bd62 b/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/59/dce50b38ffedd9a73b50278faab9b041d1bd62
deleted file mode 100644
index 4fc82210..00000000
--- a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/59/dce50b38ffedd9a73b50278faab9b041d1bd62
+++ /dev/null
@@ -1,4 +0,0 @@
-xYo6ޫWhF_%m1d?2@q[hD
-$-HI,%q"t "yu;/3~{/}wT*&tͦH_O?}#h]!;#RdC#!zjΞn˷$Eo>|.z}GḱaJu8PJU"Ya/L;b-YqBT34kRJuHNDєٷ;"Wd-7{ΣyGxkYXe]|V"pm0`Oj%O宅dÖ`+Bt_Ǿ~XVdM&)*(5= :
-ZÒf%
D#RY CLm&"@K+nN^0hoSQӻVA>.1!5FȲ<Т/V2d])yqR߹xJ)sɨHCN>!]en<]/5Q7#n+~ yb|i o;Yւ9739{el灔;ϥm3?U&ڵάXVfAU<}In@ivU3N/Tj#r`M!PlQ,6mA}J_7"&PƖ3-TRi ,3ZfTo9yl.+.z7KY\VC]>o^뽄0_>Z`p5
\ No newline at end of file
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/5a/99c301214c9ada535c348cb2b7f4f30284d4cc b/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/5a/99c301214c9ada535c348cb2b7f4f30284d4cc
deleted file mode 100644
index 59da09ef..00000000
Binary files a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/5a/99c301214c9ada535c348cb2b7f4f30284d4cc and /dev/null differ
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/5a/a5242ea769c7569430fd907bdcbc572f4f7665 b/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/5a/a5242ea769c7569430fd907bdcbc572f4f7665
deleted file mode 100644
index 1baef7ab..00000000
Binary files a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/5a/a5242ea769c7569430fd907bdcbc572f4f7665 and /dev/null differ
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/5b/04c02e88cd7cdd8efefd1b17f02ca34c041959 b/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/5b/04c02e88cd7cdd8efefd1b17f02ca34c041959
deleted file mode 100644
index f785fb25..00000000
Binary files a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/5b/04c02e88cd7cdd8efefd1b17f02ca34c041959 and /dev/null differ
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/5b/090665fff8df7954b22b4beb18a99f170f576b b/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/5b/090665fff8df7954b22b4beb18a99f170f576b
deleted file mode 100644
index 5df6adf4..00000000
Binary files a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/5b/090665fff8df7954b22b4beb18a99f170f576b and /dev/null differ
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/5d/081b3e2509c34df5aa04d3049ce2d1f45c0039 b/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/5d/081b3e2509c34df5aa04d3049ce2d1f45c0039
deleted file mode 100644
index 2898fc16..00000000
Binary files a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/5d/081b3e2509c34df5aa04d3049ce2d1f45c0039 and /dev/null differ
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/60/8e99c011c5fb1bb65c5f8cdac873713dd9cb44 b/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/60/8e99c011c5fb1bb65c5f8cdac873713dd9cb44
deleted file mode 100644
index 5aa972a1..00000000
Binary files a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/60/8e99c011c5fb1bb65c5f8cdac873713dd9cb44 and /dev/null differ
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/62/fee2ccbbfde3f2a0b3c45ec0f4810899e0a909 b/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/62/fee2ccbbfde3f2a0b3c45ec0f4810899e0a909
deleted file mode 100644
index 1f3ecfda..00000000
Binary files a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/62/fee2ccbbfde3f2a0b3c45ec0f4810899e0a909 and /dev/null differ
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/63/5432508693f70b5c86b2fd99c3d47cdddf47e8 b/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/63/5432508693f70b5c86b2fd99c3d47cdddf47e8
deleted file mode 100644
index 08310f59..00000000
Binary files a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/63/5432508693f70b5c86b2fd99c3d47cdddf47e8 and /dev/null differ
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/65/4c098d3851d941610ff7b0c65e2b15d3bf6f7d b/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/65/4c098d3851d941610ff7b0c65e2b15d3bf6f7d
deleted file mode 100644
index 5e0895b9..00000000
Binary files a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/65/4c098d3851d941610ff7b0c65e2b15d3bf6f7d and /dev/null differ
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/65/fa6b9d62e05721e2ef7a5d5d6e09065d6a27b9 b/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/65/fa6b9d62e05721e2ef7a5d5d6e09065d6a27b9
deleted file mode 100644
index 7c987b2e..00000000
Binary files a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/65/fa6b9d62e05721e2ef7a5d5d6e09065d6a27b9 and /dev/null differ
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/67/b74141ad29eb4676494c232a2d402478905915 b/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/67/b74141ad29eb4676494c232a2d402478905915
deleted file mode 100644
index 5ce83661..00000000
Binary files a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/67/b74141ad29eb4676494c232a2d402478905915 and /dev/null differ
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/68/40fa58604ecee5ad2a08fc04730bb35159640a b/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/68/40fa58604ecee5ad2a08fc04730bb35159640a
deleted file mode 100644
index 10991003..00000000
Binary files a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/68/40fa58604ecee5ad2a08fc04730bb35159640a and /dev/null differ
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/68/8242a18f61f28db9f31338898bdd89d2ab6b0a b/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/68/8242a18f61f28db9f31338898bdd89d2ab6b0a
deleted file mode 100644
index 7c9082ab..00000000
Binary files a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/68/8242a18f61f28db9f31338898bdd89d2ab6b0a and /dev/null differ
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/69/36086c2801660a55909bdc38cc2926b3e44318 b/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/69/36086c2801660a55909bdc38cc2926b3e44318
deleted file mode 100644
index dc507c18..00000000
Binary files a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/69/36086c2801660a55909bdc38cc2926b3e44318 and /dev/null differ
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/69/5c2fdc3829a9e6acc43d220102b861997b69e9 b/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/69/5c2fdc3829a9e6acc43d220102b861997b69e9
deleted file mode 100644
index 2a5e9873..00000000
Binary files a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/69/5c2fdc3829a9e6acc43d220102b861997b69e9 and /dev/null differ
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/6b/49ef3e032baf487eb496da619849900e05a4f5 b/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/6b/49ef3e032baf487eb496da619849900e05a4f5
deleted file mode 100644
index 48f36d7d..00000000
Binary files a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/6b/49ef3e032baf487eb496da619849900e05a4f5 and /dev/null differ
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/6d/9542e0dc33a0feee4d4015963e20f99ab0ef6a b/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/6d/9542e0dc33a0feee4d4015963e20f99ab0ef6a
deleted file mode 100644
index fb1949e1..00000000
Binary files a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/6d/9542e0dc33a0feee4d4015963e20f99ab0ef6a and /dev/null differ
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/70/48cca600ee2068ed9636eee91dad375874293c b/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/70/48cca600ee2068ed9636eee91dad375874293c
deleted file mode 100644
index 5b21ea73..00000000
Binary files a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/70/48cca600ee2068ed9636eee91dad375874293c and /dev/null differ
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/71/27a157f38952adf42ecf6d77fa87221ff48e06 b/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/71/27a157f38952adf42ecf6d77fa87221ff48e06
deleted file mode 100644
index 317378f6..00000000
Binary files a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/71/27a157f38952adf42ecf6d77fa87221ff48e06 and /dev/null differ
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/71/af8d00fbc4e977c05e0e9826c0d45c1b1da5a7 b/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/71/af8d00fbc4e977c05e0e9826c0d45c1b1da5a7
deleted file mode 100644
index 48390888..00000000
Binary files a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/71/af8d00fbc4e977c05e0e9826c0d45c1b1da5a7 and /dev/null differ
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/72/1ca1835023196f893b54de196de569625ff0ea b/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/72/1ca1835023196f893b54de196de569625ff0ea
deleted file mode 100644
index 77d246fd..00000000
Binary files a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/72/1ca1835023196f893b54de196de569625ff0ea and /dev/null differ
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/72/f9c3796c120ae5775b3839544e845e17381578 b/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/72/f9c3796c120ae5775b3839544e845e17381578
deleted file mode 100644
index 99adb8b2..00000000
Binary files a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/72/f9c3796c120ae5775b3839544e845e17381578 and /dev/null differ
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/73/3865c10b0c4b2357437a8116c58c57d4730460 b/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/73/3865c10b0c4b2357437a8116c58c57d4730460
deleted file mode 100644
index 2858f9b8..00000000
Binary files a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/73/3865c10b0c4b2357437a8116c58c57d4730460 and /dev/null differ
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/74/9fbf3d85c7db1c8ea51866435d5b8dba317218 b/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/74/9fbf3d85c7db1c8ea51866435d5b8dba317218
deleted file mode 100644
index a82b6bb8..00000000
Binary files a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/74/9fbf3d85c7db1c8ea51866435d5b8dba317218 and /dev/null differ
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/75/c32f6484c2869474190924df4dd3bec4134a96 b/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/75/c32f6484c2869474190924df4dd3bec4134a96
deleted file mode 100644
index b5cf608b..00000000
Binary files a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/75/c32f6484c2869474190924df4dd3bec4134a96 and /dev/null differ
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/77/8d8e2c9ea14820f6fd8fe123ccf84c93f3bada b/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/77/8d8e2c9ea14820f6fd8fe123ccf84c93f3bada
deleted file mode 100644
index 86b3eef0..00000000
--- a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/77/8d8e2c9ea14820f6fd8fe123ccf84c93f3bada
+++ /dev/null
@@ -1,2 +0,0 @@
-xK
-1D]$t :3QojQWyǾ1aWVs.a\l[ĖdbZe*[jz49>iM[d6Iѫ<.~d#o5K
~>A6ZRq0*j&mOH>
\ No newline at end of file
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/78/ff75c9d467bc21df73be00747548f987ea5738 b/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/78/ff75c9d467bc21df73be00747548f987ea5738
deleted file mode 100644
index 33ca9ebf..00000000
Binary files a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/78/ff75c9d467bc21df73be00747548f987ea5738 and /dev/null differ
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/7a/bffc74caa8761c6cb924e6294a7adfceb4ed7a b/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/7a/bffc74caa8761c6cb924e6294a7adfceb4ed7a
deleted file mode 100644
index 3c1428eb..00000000
Binary files a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/7a/bffc74caa8761c6cb924e6294a7adfceb4ed7a and /dev/null differ
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/7a/c1649d4b941fdc03f877ab7d929a52018a1f75 b/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/7a/c1649d4b941fdc03f877ab7d929a52018a1f75
deleted file mode 100644
index 246c676d..00000000
--- a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/7a/c1649d4b941fdc03f877ab7d929a52018a1f75
+++ /dev/null
@@ -1 +0,0 @@
-xAj0E)f_(hdk .rhBe䉡
x_1 ҇uU8 ުČ\X"B"qC`Z.Ƅ$TFd[r,SJ<:ˮp{5o49N繋
u7{F
\ No newline at end of file
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/7b/069f0d9a9e695980d5d6119162c21433f91619 b/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/7b/069f0d9a9e695980d5d6119162c21433f91619
deleted file mode 100644
index d8c7b72b..00000000
Binary files a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/7b/069f0d9a9e695980d5d6119162c21433f91619 and /dev/null differ
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/7e/8e8c6fa3a7b2636d0994718aaba9e670c9d546 b/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/7e/8e8c6fa3a7b2636d0994718aaba9e670c9d546
deleted file mode 100644
index bf033f45..00000000
Binary files a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/7e/8e8c6fa3a7b2636d0994718aaba9e670c9d546 and /dev/null differ
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/7e/eebe7b497706c09c37955274496227f1ffc67f b/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/7e/eebe7b497706c09c37955274496227f1ffc67f
deleted file mode 100644
index 26a231ff..00000000
Binary files a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/7e/eebe7b497706c09c37955274496227f1ffc67f and /dev/null differ
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/83/1e2d55306d37b6d64d39abe2e5384c2341f787 b/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/83/1e2d55306d37b6d64d39abe2e5384c2341f787
deleted file mode 100644
index 471c1355..00000000
Binary files a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/83/1e2d55306d37b6d64d39abe2e5384c2341f787 and /dev/null differ
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/83/3b84acf1b3e49e5f8a1fa7a77e4cd9848f2852 b/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/83/3b84acf1b3e49e5f8a1fa7a77e4cd9848f2852
deleted file mode 100644
index a5da3aff..00000000
Binary files a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/83/3b84acf1b3e49e5f8a1fa7a77e4cd9848f2852 and /dev/null differ
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/84/26abee6d3454eb54ef646dda09bf4fae08c321 b/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/84/26abee6d3454eb54ef646dda09bf4fae08c321
deleted file mode 100644
index 937641f0..00000000
Binary files a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/84/26abee6d3454eb54ef646dda09bf4fae08c321 and /dev/null differ
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/8a/c5515bd0a29bd78efc3cf3f7a9c5e927ce5e60 b/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/8a/c5515bd0a29bd78efc3cf3f7a9c5e927ce5e60
deleted file mode 100644
index 2864cfd9..00000000
Binary files a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/8a/c5515bd0a29bd78efc3cf3f7a9c5e927ce5e60 and /dev/null differ
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/8b/cc54388eb056928602c4d5e90d8aa66559b8cc b/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/8b/cc54388eb056928602c4d5e90d8aa66559b8cc
deleted file mode 100644
index 5b2a4278..00000000
Binary files a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/8b/cc54388eb056928602c4d5e90d8aa66559b8cc and /dev/null differ
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/8e/4d2dcba74998a7e145a7e674b097b1fa230d7c b/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/8e/4d2dcba74998a7e145a7e674b097b1fa230d7c
deleted file mode 100644
index 101ad3c1..00000000
Binary files a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/8e/4d2dcba74998a7e145a7e674b097b1fa230d7c and /dev/null differ
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/8f/b29ffc7bef3477067a4e865b81b9caf47e90b2 b/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/8f/b29ffc7bef3477067a4e865b81b9caf47e90b2
deleted file mode 100644
index 03471cd9..00000000
--- a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/8f/b29ffc7bef3477067a4e865b81b9caf47e90b2
+++ /dev/null
@@ -1,2 +0,0 @@
-xA
-0E]$MjJoo?rM6u=SO#9eG(2Sj+d4} @oT97po:׳0b O:9S.'"{J>2,4NR*QK6YF\*|KMycg.O/Z_i'Xw&=jӣO9`tV`[dΥmT
\ No newline at end of file
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/b5/d1634b81813fba3b356ff23ce7f06798c89bdd b/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/b5/d1634b81813fba3b356ff23ce7f06798c89bdd
deleted file mode 100644
index 952dc680..00000000
Binary files a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/b5/d1634b81813fba3b356ff23ce7f06798c89bdd and /dev/null differ
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/b8/00fa18aa31215ff3eee46a55724c0556ad054b b/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/b8/00fa18aa31215ff3eee46a55724c0556ad054b
deleted file mode 100644
index f27c0625..00000000
Binary files a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/b8/00fa18aa31215ff3eee46a55724c0556ad054b and /dev/null differ
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/bb/17d0d5383d4c0a9e8b0a0cdde9d93aeccd09c8 b/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/bb/17d0d5383d4c0a9e8b0a0cdde9d93aeccd09c8
deleted file mode 100644
index 053069fe..00000000
Binary files a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/bb/17d0d5383d4c0a9e8b0a0cdde9d93aeccd09c8 and /dev/null differ
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/bc/b89f67890069c033195cc11e9fe763d28deffd b/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/bc/b89f67890069c033195cc11e9fe763d28deffd
deleted file mode 100644
index 5afc74a5..00000000
Binary files a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/bc/b89f67890069c033195cc11e9fe763d28deffd and /dev/null differ
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/c3/de752a4e5cffac3e3cac117647bced5f1a51c3 b/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/c3/de752a4e5cffac3e3cac117647bced5f1a51c3
deleted file mode 100644
index c0bdf1f6..00000000
Binary files a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/c3/de752a4e5cffac3e3cac117647bced5f1a51c3 and /dev/null differ
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/c4/f020bb7e203e13ad0a21dc1d806cfb4d9f99f0 b/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/c4/f020bb7e203e13ad0a21dc1d806cfb4d9f99f0
deleted file mode 100644
index 15efc1e7..00000000
Binary files a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/c4/f020bb7e203e13ad0a21dc1d806cfb4d9f99f0 and /dev/null differ
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/c5/007a615807cdb57b5cc7530edd9d4c29f7f24d b/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/c5/007a615807cdb57b5cc7530edd9d4c29f7f24d
deleted file mode 100644
index d9943a6e..00000000
Binary files a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/c5/007a615807cdb57b5cc7530edd9d4c29f7f24d and /dev/null differ
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/ca/bb24b5e21ac27e89dc04e412d74e03aa76f380 b/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/ca/bb24b5e21ac27e89dc04e412d74e03aa76f380
deleted file mode 100644
index 4125edd9..00000000
Binary files a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/ca/bb24b5e21ac27e89dc04e412d74e03aa76f380 and /dev/null differ
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/cd/5bb1cb7e32ad4b5f4d8eb0aa04f7eddbb603ae b/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/cd/5bb1cb7e32ad4b5f4d8eb0aa04f7eddbb603ae
deleted file mode 100644
index f1d0d64f..00000000
Binary files a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/cd/5bb1cb7e32ad4b5f4d8eb0aa04f7eddbb603ae and /dev/null differ
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/d2/af663c095050933c10d57125fe6158fad4fe2c b/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/d2/af663c095050933c10d57125fe6158fad4fe2c
deleted file mode 100644
index 18161b20..00000000
Binary files a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/d2/af663c095050933c10d57125fe6158fad4fe2c and /dev/null differ
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/d9/7c5378fda25bd0280c942dc304d218bf2a0816 b/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/d9/7c5378fda25bd0280c942dc304d218bf2a0816
deleted file mode 100644
index a1195dfb..00000000
Binary files a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/d9/7c5378fda25bd0280c942dc304d218bf2a0816 and /dev/null differ
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/db/abd636abb1f110493884620b2f075987c54f70 b/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/db/abd636abb1f110493884620b2f075987c54f70
deleted file mode 100644
index 53a27bd6..00000000
Binary files a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/db/abd636abb1f110493884620b2f075987c54f70 and /dev/null differ
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/dd/40ebe950c0a0cd5de542e3d0e7a0e1ac4e70aa b/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/dd/40ebe950c0a0cd5de542e3d0e7a0e1ac4e70aa
deleted file mode 100644
index c9c097c4..00000000
--- a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/git/objects/dd/40ebe950c0a0cd5de542e3d0e7a0e1ac4e70aa
+++ /dev/null
@@ -1 +0,0 @@
-xJ1F)$?Al'w,x}z/N
-
- 4.0.0
- spring-cloud-starter-build
- pom
- Spring Cloud Starter Build
- Spring Cloud Starter Build
- Dalston.BUILD-SNAPSHOT
-
- org.springframework.cloud
- spring-cloud-build
- 1.3.1.BUILD-SNAPSHOT
-
-
-
-
- https://github.com/spring-cloud/spring-cloud-starters
- scm:git:git://github.com/spring-cloud/spring-cloud-starters.git
- scm:git:ssh://git@github.com/spring-cloud/spring-cloud-starters.git
- HEAD
-
-
-
- starters
-
-
-
- spring-cloud-dependencies
- spring-cloud-starter-parent
- docs
-
-
-
-
-
- org.apache.maven.plugins
- maven-enforcer-plugin
-
-
- enforce-rules
-
- enforce
-
-
-
-
-
- commons-logging:*:*
-
- true
-
-
-
- true
-
-
-
-
-
-
-
-
-
- spring
-
-
- spring-snapshots
- Spring Snapshots
- https://repo.spring.io/libs-snapshot-local
-
- true
-
-
-
- spring-milestones
- Spring Milestones
- https://repo.spring.io/libs-milestone-local
-
- false
-
-
-
- spring-releases
- Spring Releases
- https://repo.spring.io/release
-
- false
-
-
-
-
-
- spring-snapshots
- Spring Snapshots
- https://repo.spring.io/libs-snapshot-local
-
- true
-
-
-
- spring-milestones
- Spring Milestones
- https://repo.spring.io/libs-milestone-local
-
- false
-
-
-
-
-
-
-
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/spring-cloud-dependencies/pom.xml b/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/spring-cloud-dependencies/pom.xml
deleted file mode 100644
index a136f9eb..00000000
--- a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/spring-cloud-dependencies/pom.xml
+++ /dev/null
@@ -1,185 +0,0 @@
-
-
- 4.0.0
-
- org.springframework.cloud
- spring-cloud-dependencies-parent
- 1.3.1.BUILD-SNAPSHOT
-
-
- spring-cloud-dependencies
- Dalston.BUILD-SNAPSHOT
- spring-cloud-dependencies
- Spring Cloud Dependencies
- pom
-
- ${basedir}/../..
- 1.2.0.BUILD-SNAPSHOT
- 1.3.0.BUILD-SNAPSHOT
- 1.1.0.BUILD-SNAPSHOT
- 1.1.0.BUILD-SNAPSHOT
- 1.2.0.BUILD-SNAPSHOT
- 1.3.0.BUILD-SNAPSHOT
- 1.3.0.BUILD-SNAPSHOT
- 1.2.0.BUILD-SNAPSHOT
- 1.2.0.BUILD-SNAPSHOT
- 1.2.0.BUILD-SNAPSHOT
- Chelsea.BUILD-SNAPSHOT
- 1.1.2.BUILD-SNAPSHOT
- 1.0.0.BUILD-SNAPSHOT
- 1.1.0.BUILD-SNAPSHOT
-
-
-
-
-
- org.springframework.cloud
- spring-cloud-commons-dependencies
- ${spring-cloud-commons.version}
- pom
- import
-
-
- org.springframework.cloud
- spring-cloud-netflix-dependencies
- ${spring-cloud-netflix.version}
- pom
- import
-
-
- org.springframework.cloud
- spring-cloud-stream-dependencies
- ${spring-cloud-stream.version}
- pom
- import
-
-
- org.springframework.cloud
- spring-cloud-task-dependencies
- ${spring-cloud-task.version}
- pom
- import
-
-
- org.springframework.cloud
- spring-cloud-config-dependencies
- ${spring-cloud-config.version}
- pom
- import
-
-
- org.springframework.cloud
- spring-cloud-consul-dependencies
- ${spring-cloud-consul.version}
- pom
- import
-
-
- org.springframework.cloud
- spring-cloud-sleuth-dependencies
- ${spring-cloud-sleuth.version}
- pom
- import
-
-
- org.springframework.cloud
- spring-cloud-vault-dependencies
- ${spring-cloud-vault.version}
- pom
- import
-
-
- org.springframework.cloud
- spring-cloud-zookeeper-dependencies
- ${spring-cloud-zookeeper.version}
- pom
- import
-
-
- org.springframework.cloud
- spring-cloud-security-dependencies
- ${spring-cloud-security.version}
- pom
- import
-
-
- org.springframework.cloud
- spring-cloud-cloudfoundry-dependencies
- ${spring-cloud-cloudfoundry.version}
- pom
- import
-
-
- org.springframework.cloud
- spring-cloud-bus-dependencies
- ${spring-cloud-bus.version}
- pom
- import
-
-
- org.springframework.cloud
- spring-cloud-contract-dependencies
- ${spring-cloud-contract.version}
- pom
- import
-
-
- org.springframework.cloud
- spring-cloud-aws-dependencies
- ${spring-cloud-aws.version}
- pom
- import
-
-
-
-
-
- spring
-
-
- spring-snapshots
- Spring Snapshots
- https://repo.spring.io/libs-snapshot-local
-
- true
-
-
-
- spring-milestones
- Spring Milestones
- https://repo.spring.io/libs-milestone-local
-
- false
-
-
-
- spring-releases
- Spring Releases
- https://repo.spring.io/release
-
- false
-
-
-
-
-
- spring-snapshots
- Spring Snapshots
- https://repo.spring.io/libs-snapshot-local
-
- true
-
-
-
- spring-milestones
- Spring Milestones
- https://repo.spring.io/libs-milestone-local
-
- false
-
-
-
-
-
-
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/spring-cloud-dependencies/src/main/resources/META-INF/spring.provides b/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/spring-cloud-dependencies/src/main/resources/META-INF/spring.provides
deleted file mode 100644
index 3628be6e..00000000
--- a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/spring-cloud-dependencies/src/main/resources/META-INF/spring.provides
+++ /dev/null
@@ -1 +0,0 @@
-provides: spring-cloud-config-client
\ No newline at end of file
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/spring-cloud-starter-parent/pom.xml b/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/spring-cloud-starter-parent/pom.xml
deleted file mode 100644
index 578e1504..00000000
--- a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/spring-cloud-starter-parent/pom.xml
+++ /dev/null
@@ -1,155 +0,0 @@
-
-
- 4.0.0
-
- org.springframework.boot
- spring-boot-starter-parent
- 1.5.1.BUILD-SNAPSHOT
-
- org.springframework.cloud
- spring-cloud-starter-parent
- Dalston.BUILD-SNAPSHOT
- spring-cloud-starter-parent
- Spring Cloud Starter Parent
- pom
- https://projects.spring.io/spring-cloud
-
- Pivotal Software, Inc.
- https://www.spring.io
-
-
- ${basedir}/../..
- Dalston.BUILD-SNAPSHOT
-
-
-
-
- org.springframework.cloud
- spring-cloud-dependencies
- ${spring-cloud.version}
- pom
- import
-
-
-
-
- https://github.com/spring-cloud
-
- spring-docs
- scp://static.springframework.org/var/www/domains/springframework.org/static/htdocs/spring-cloud/docs/${project.artifactId}/${project.version}
-
-
-
- repo.spring.io
- Spring Release Repository
- https://repo.spring.io/libs-release-local
-
-
- repo.spring.io
- Spring Snapshot Repository
- https://repo.spring.io/libs-snapshot-local
-
-
-
-
- spring
-
-
- spring-snapshots
- Spring Snapshots
- https://repo.spring.io/libs-snapshot-local
-
- true
-
-
-
- spring-milestones
- Spring Milestones
- https://repo.spring.io/libs-milestone-local
-
- false
-
-
-
- spring-releases
- Spring Releases
- https://repo.spring.io/release
-
- false
-
-
-
-
-
- spring-snapshots
- Spring Snapshots
- https://repo.spring.io/libs-snapshot-local
-
- true
-
-
-
- spring-milestones
- Spring Milestones
- https://repo.spring.io/libs-milestone-local
-
- false
-
-
-
-
-
- milestone
-
-
- repo.spring.io
- Spring Milestone Repository
- https://repo.spring.io/libs-milestone-local
-
-
-
-
- bintray
-
-
- bintray
- Jcenter Repository
- https://api.bintray.com/maven/spring/jars/org.springframework.cloud:${bintray.package}
-
-
-
-
- central
-
-
-
- org.apache.maven.plugins
- maven-gpg-plugin
-
-
- sign-artifacts
- verify
-
- sign
-
-
-
-
-
-
-
-
- sonatype-nexus-snapshots
- Sonatype Nexus Snapshots
- https://oss.sonatype.org/content/repositories/snapshots/
-
-
- sonatype-nexus-staging
- Nexus Release Repository
- https://oss.sonatype.org/service/local/staging/deploy/maven2/
-
-
-
-
-
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/spring-cloud-starter-parent/src/main/resources/META-INF/spring.provides b/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/spring-cloud-starter-parent/src/main/resources/META-INF/spring.provides
deleted file mode 100644
index 3628be6e..00000000
--- a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-release/spring-cloud-starter-parent/src/main/resources/META-INF/spring.provides
+++ /dev/null
@@ -1 +0,0 @@
-provides: spring-cloud-config-client
\ No newline at end of file
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-sleuth/pom.xml b/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-sleuth/pom.xml
deleted file mode 100644
index ac5f1b59..00000000
--- a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-sleuth/pom.xml
+++ /dev/null
@@ -1,376 +0,0 @@
-
-
- 4.0.0
-
- spring-cloud-sleuth
- 0.2.0.BUILD-SNAPSHOT
- pom
- Spring Cloud Sleuth
- Spring Cloud Sleuth
-
-
- org.springframework.cloud
- spring-cloud-build
- 0.3.1.BUILD-SNAPSHOT
-
-
-
-
-
- https://github.com/spring-cloud/spring-cloud-sleuth
- scm:git:git://github.com/spring-cloud/spring-cloud-sleuth.git
- scm:git:ssh://git@github.com/spring-cloud/spring-cloud-sleuth.git
- HEAD
-
-
-
- spring-cloud-sleuth-dependencies
- spring-cloud-sleuth-core
- spring-cloud-sleuth-zipkin
- spring-cloud-sleuth-stream
- spring-cloud-sleuth-zipkin-stream
- spring-cloud-starter-sleuth
- spring-cloud-starter-zipkin
- spring-cloud-sleuth-samples
- docs
-
-
-
-
-
-
- org.apache.maven.plugins
- maven-compiler-plugin
- 3.1
-
-
- default-compile
-
- true
- true
-
- ${maven.compiler.source}
- ${maven.compiler.target}
-
-
-
-
- default-testCompile
-
- true
- true
-
- ${maven.compiler.testSource}
- ${maven.compiler.testTarget}
-
-
-
-
-
-
- org.apache.maven.plugins
- maven-enforcer-plugin
- 1.3.1
-
-
- enforce-java
-
- enforce
-
-
-
-
- ${maven.compiler.testTarget}
-
-
-
-
-
-
-
-
-
-
- org.apache.maven.plugins
- maven-checkstyle-plugin
- ${checkstyle.version}
-
-
- org.springframework.cloud
- spring-cloud-build-tools
- ${spring-cloud-build.version}
-
-
-
-
- validate
- validate
-
- checkstyle.xml
- LICENSE.txt
- true
- true
-
-
- check
-
-
-
-
-
-
-
-
-
-
- org.apache.maven.plugins
- maven-checkstyle-plugin
- ${checkstyle.version}
-
- checkstyle.xml
- LICENSE.txt
-
-
-
-
-
-
-
-
- org.springframework.cloud
- spring-cloud-sleuth-dependencies
- ${project.version}
- pom
- import
-
-
- org.springframework.cloud
- spring-cloud-netflix-dependencies
- ${spring-cloud-netflix.version}
- pom
- import
-
-
- org.springframework.cloud
- spring-cloud-commons-dependencies
- ${spring-cloud-commons.version}
- pom
- import
-
-
- org.springframework.cloud
- spring-cloud-stream-dependencies
- ${spring-cloud-stream.version}
- pom
- import
-
-
-
- org.spockframework
- spock-core
- ${spock.version}
- test
-
-
- org.spockframework
- spock-spring
- ${spock.version}
- test
-
-
- cglib
- cglib-nodep
- 3.1
-
-
- org.objenesis
- objenesis
- 2.1
-
-
-
- org.hamcrest
- hamcrest-core
- test
-
-
- com.jayway.awaitility
- awaitility
- 1.7.0
- test
-
-
- com.github.tomakehurst
- wiremock
- 2.5.1
- test
-
-
- pl.pragmatists
- JUnitParams
- 1.0.6
- test
-
-
- org.assertj
- assertj-core
- 3.6.2
- test
-
-
-
-
-
- 1.7
- 1.7
- 1.8
- 1.8
- 2.19.1
- 2.17
- 0.3.1.BUILD-SNAPSHOT
- 0.2.0.BUILD-SNAPSHOT
- Foo.BUILD-SNAPSHOT
- 0.3.0.BUILD-SNAPSHOT
-
-
-
-
- spring
-
-
- spring-snapshots
- Spring Snapshots
- https://repo.spring.io/libs-snapshot-local
-
- true
-
-
- false
-
-
-
- spring-milestones
- Spring Milestones
- https://repo.spring.io/libs-milestone-local
-
- false
-
-
- false
-
-
-
- spring-releases
- Spring Releases
- https://repo.spring.io/release
-
- false
-
-
-
-
-
- spring-snapshots
- Spring Snapshots
- https://repo.spring.io/libs-snapshot-local
-
- true
-
-
- false
-
-
-
- spring-milestones
- Spring Milestones
- https://repo.spring.io/libs-milestone-local
-
- false
-
-
-
- spring-releases
- Spring Releases
- https://repo.spring.io/libs-release-local
-
- false
-
-
-
-
-
- ide
-
- false
-
-
-
-
- org.apache.maven.plugins
- maven-compiler-plugin
- 3.1
-
- ${maven.compiler.testSource}
- ${maven.compiler.testTarget}
-
-
-
-
-
-
- benchmarks
-
- false
-
-
- benchmarks
-
-
-
- sonar
-
-
-
- org.jacoco
- jacoco-maven-plugin
-
-
- pre-unit-test
-
- prepare-agent
-
-
- surefireArgLine
- ${project.build.directory}/jacoco.exec
-
-
-
- post-unit-test
- test
-
- report
-
-
-
- ${project.build.directory}/jacoco.exec
-
-
-
-
-
- org.apache.maven.plugins
- maven-surefire-plugin
- ${surefire.plugin.version}
-
-
- ${surefireArgLine}
-
-
-
-
-
-
-
-
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-sleuth/spring-cloud-sleuth-core/pom.xml b/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-sleuth/spring-cloud-sleuth-core/pom.xml
deleted file mode 100644
index 95e39305..00000000
--- a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-sleuth/spring-cloud-sleuth-core/pom.xml
+++ /dev/null
@@ -1,165 +0,0 @@
-
-
- 4.0.0
-
- spring-cloud-sleuth-core
- jar
- Spring Cloud Sleuth Core
- Spring Cloud Sleuth Core
-
-
- org.springframework.cloud
- spring-cloud-sleuth
- 0.2.0.BUILD-SNAPSHOT
- ..
-
-
-
-
- org.springframework.boot
- spring-boot-starter-web
- true
-
-
- org.springframework.boot
- spring-boot-starter-websocket
- true
-
-
- org.springframework.boot
- spring-boot-configuration-processor
- true
-
-
- org.springframework.boot
- spring-boot-starter-actuator
- true
-
-
- org.springframework.cloud
- spring-cloud-commons
-
-
- org.springframework.cloud
- spring-cloud-starter-feign
- true
-
-
- org.springframework.cloud
- spring-cloud-starter-zuul
- true
-
-
- org.springframework.integration
- spring-integration-core
- true
-
-
- org.springframework
- spring-context
-
-
- com.netflix.hystrix
- hystrix-core
- true
-
-
- io.github.openfeign
- feign-core
- true
-
-
- com.netflix.zuul
- zuul-core
- true
-
-
- io.reactivex
- rxjava
- true
-
-
-
- org.springframework.data
- spring-data-rest-webmvc
- true
-
-
- com.squareup.okhttp3
- okhttp
- true
-
-
- org.apache.httpcomponents
- httpclient
- true
-
-
- io.github.openfeign
- feign-okhttp
- true
-
-
- org.aspectj
- aspectjrt
-
-
- org.springframework.boot
- spring-boot-starter-test
- test
-
-
- com.netflix.archaius
- archaius-core
- test
-
-
- com.squareup.okhttp3
- mockwebserver
- 3.1.2
- test
-
-
- org.assertj
- assertj-core
- test
-
-
- com.jayway.awaitility
- awaitility
- test
-
-
- pl.pragmatists
- JUnitParams
- test
-
-
- org.springframework.boot
- spring-boot-starter-data-jpa
- test
-
-
- org.springframework
- spring-orm
- test
-
-
- org.springframework.boot
- spring-boot-starter-data-rest
- test
-
-
- com.h2database
- h2
- test
-
-
- org.springframework.cloud
- spring-cloud-starter-eureka
- test
-
-
-
-
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-sleuth/spring-cloud-sleuth-dependencies/pom.xml b/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-sleuth/spring-cloud-sleuth-dependencies/pom.xml
deleted file mode 100644
index eff7bb02..00000000
--- a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-sleuth/spring-cloud-sleuth-dependencies/pom.xml
+++ /dev/null
@@ -1,139 +0,0 @@
-
-
- 4.0.0
-
- spring-cloud-dependencies-parent
- org.springframework.cloud
- 0.3.1.BUILD-SNAPSHOT
-
-
- spring-cloud-sleuth-dependencies
- 0.2.0.BUILD-SNAPSHOT
- pom
- spring-cloud-sleuth-dependencies
- Spring Cloud Sleuth Dependencies
-
- 1.19.2
- 0.6.12
-
-
-
-
- org.springframework.cloud
- spring-cloud-sleuth-core
- ${project.version}
-
-
- org.springframework.cloud
- spring-cloud-sleuth-zipkin
- ${project.version}
-
-
- org.springframework.cloud
- spring-cloud-sleuth-stream
- ${project.version}
-
-
- org.springframework.cloud
- spring-cloud-sleuth-zipkin-stream
- ${project.version}
-
-
- org.springframework.cloud
- spring-cloud-starter-zipkin
- ${project.version}
-
-
- org.springframework.cloud
- spring-cloud-starter-sleuth
- ${project.version}
-
-
- io.zipkin.java
- zipkin
- ${zipkin.version}
-
-
- io.zipkin.java
- zipkin-server
- ${zipkin.version}
-
-
- io.zipkin.java
- zipkin-autoconfigure-ui
- ${zipkin.version}
-
-
- io.zipkin.java
- zipkin-autoconfigure-storage-mysql
- ${zipkin.version}
-
-
- io.zipkin.java
- zipkin-junit
- ${zipkin.version}
-
-
- io.zipkin.reporter
- zipkin-reporter
- ${zipkin-reporter.version}
-
-
-
-
-
- spring
-
-
- spring-snapshots
- Spring Snapshots
- https://repo.spring.io/libs-snapshot-local
-
- true
-
-
- false
-
-
-
- spring-milestones
- Spring Milestones
- https://repo.spring.io/libs-milestone-local
-
- false
-
-
-
- spring-releases
- Spring Releases
- https://repo.spring.io/release
-
- false
-
-
-
-
-
- spring-snapshots
- Spring Snapshots
- https://repo.spring.io/libs-snapshot-local
-
- true
-
-
- false
-
-
-
- spring-milestones
- Spring Milestones
- https://repo.spring.io/libs-milestone-local
-
- false
-
-
-
-
-
-
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-sleuth/spring-cloud-sleuth-samples/pom.xml b/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-sleuth/spring-cloud-sleuth-samples/pom.xml
deleted file mode 100644
index acbc7e0c..00000000
--- a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-sleuth/spring-cloud-sleuth-samples/pom.xml
+++ /dev/null
@@ -1,72 +0,0 @@
-
-
- 4.0.0
-
- spring-cloud-sleuth-samples
- pom
- Spring Cloud Sleuth Samples
- Spring Cloud Sleuth Samples
-
-
- org.springframework.cloud
- spring-cloud-sleuth
- 0.2.0.BUILD-SNAPSHOT
- ..
-
-
-
- spring-cloud-sleuth-sample
- spring-cloud-sleuth-sample-test-core
- spring-cloud-sleuth-sample-messaging
- spring-cloud-sleuth-sample-websocket
- spring-cloud-sleuth-sample-feign
- spring-cloud-sleuth-sample-ribbon
- spring-cloud-sleuth-sample-zipkin
- spring-cloud-sleuth-sample-stream
- spring-cloud-sleuth-sample-zipkin-stream
-
-
-
-
-
-
-
- maven-deploy-plugin
-
- true
-
-
-
-
-
-
-
-
-
- org.springframework.cloud
- spring-cloud-sleuth-dependencies
- ${project.version}
- pom
- import
-
-
- org.springframework.cloud
- spring-cloud-sleuth-sample-test-core
- ${project.version}
-
-
- io.zipkin.java
- zipkin
- 1.19.2
-
-
- io.zipkin.java
- zipkin-server
- 1.19.2
-
-
-
-
-
diff --git a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-sleuth/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-zipkin-stream/pom.xml b/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-sleuth/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-zipkin-stream/pom.xml
deleted file mode 100644
index 977e07d4..00000000
--- a/spring-cloud-release-tools-core/src/test/resources/projects/spring-cloud-sleuth/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-zipkin-stream/pom.xml
+++ /dev/null
@@ -1,107 +0,0 @@
-
-
-
-
- 4.0.0
-
- spring-cloud-sleuth-sample-zipkin-stream
- jar
-
- spring-cloud-sleuth-sample-zipkin-stream
- Spring Boot Zipkin Server
-
-
- org.springframework.cloud
- spring-cloud-sleuth-samples
- 0.2.0.BUILD-SNAPSHOT
- ..
-
-
-
- springio
- UTF-8
- 1.8
- true
-
-
-
-
- org.springframework.boot
- spring-boot-configuration-processor
- true
-
-
- org.springframework.boot
- spring-boot-starter-jdbc
-
-
- org.springframework.cloud
- spring-cloud-sleuth-zipkin-stream
-
-
- io.zipkin.java
- zipkin-autoconfigure-ui
-
-
- org.springframework.integration
- spring-integration-jmx
-
-
- org.springframework.cloud
- spring-cloud-stream-binder-rabbit
-
-
- com.h2database
- h2
- true
-
-
- mysql
- mysql-connector-java
- true
-
-
- org.springframework.cloud
- spring-cloud-stream-test-support
- test
-
-
- org.springframework.boot
- spring-boot-starter-test
- test
-
-
- org.springframework.cloud
- spring-cloud-sleuth-sample-test-core
- test
-
-
-
-
-
-
- org.springframework.boot
- spring-boot-maven-plugin
-
- exec
-
-
-
-
-
-
diff --git a/spring-cloud-release-tools-spring/.jdk8 b/spring-cloud-release-tools-spring/.jdk8
deleted file mode 100644
index e69de29b..00000000
diff --git a/spring-cloud-release-tools-spring/pom.xml b/spring-cloud-release-tools-spring/pom.xml
deleted file mode 100644
index c950e3c6..00000000
--- a/spring-cloud-release-tools-spring/pom.xml
+++ /dev/null
@@ -1,93 +0,0 @@
-
-
- 4.0.0
-
- org.springframework.cloud.internal
- spring-cloud-release-tools-spring
- 1.0.0.M1
- jar
-
-
- org.springframework.cloud
- spring-cloud-build
- 1.2.2.RELEASE
-
-
-
-
-
- UTF-8
- 1.8
-
-
-
-
- org.springframework.cloud.internal
- spring-cloud-release-tools-core
- ${project.version}
-
-
-
- org.springframework.boot
- spring-boot-starter-test
- test
-
-
-
-
-
-
- org.springframework.boot
- spring-boot-maven-plugin
-
-
-
-
-
-
- sonar
-
-
-
- org.jacoco
- jacoco-maven-plugin
-
-
- pre-unit-test
-
- prepare-agent
-
-
- surefireArgLine
- ${project.build.directory}/jacoco.exec
-
-
-
- post-unit-test
- test
-
- report
-
-
-
- ${project.build.directory}/jacoco.exec
-
-
-
-
-
- org.apache.maven.plugins
- maven-surefire-plugin
-
-
- ${surefireArgLine}
-
-
-
-
-
-
-
-
diff --git a/spring-cloud-release-tools-spring/src/main/java/org/springframework/cloud/release/ReleaserApplication.java b/spring-cloud-release-tools-spring/src/main/java/org/springframework/cloud/release/ReleaserApplication.java
deleted file mode 100644
index fdeb8d83..00000000
--- a/spring-cloud-release-tools-spring/src/main/java/org/springframework/cloud/release/ReleaserApplication.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright 2013-2017 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.springframework.cloud.release;
-
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.CommandLineRunner;
-import org.springframework.boot.SpringApplication;
-import org.springframework.boot.autoconfigure.SpringBootApplication;
-import org.springframework.cloud.release.internal.Releaser;
-
-@SpringBootApplication
-public class ReleaserApplication implements CommandLineRunner {
-
- public static void main(String[] args) {
- SpringApplication.run(ReleaserApplication.class, args);
- }
-
- @Autowired Releaser releaser;
-
- @Override public void run(String... strings) throws Exception {
- this.releaser.release();
- System.exit(0);
- }
-}
diff --git a/spring-cloud-release-tools-spring/src/main/java/org/springframework/cloud/release/spring/ReleaserConfiguration.java b/spring-cloud-release-tools-spring/src/main/java/org/springframework/cloud/release/spring/ReleaserConfiguration.java
deleted file mode 100644
index 006fb8df..00000000
--- a/spring-cloud-release-tools-spring/src/main/java/org/springframework/cloud/release/spring/ReleaserConfiguration.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright 2013-2017 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.springframework.cloud.release.spring;
-
-import org.springframework.boot.context.properties.EnableConfigurationProperties;
-import org.springframework.cloud.release.internal.Releaser;
-import org.springframework.cloud.release.internal.ReleaserProperties;
-import org.springframework.cloud.release.internal.build.ProjectBuilder;
-import org.springframework.cloud.release.internal.pom.ProjectUpdater;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-
-@Configuration
-@EnableConfigurationProperties(ReleaserProperties.class)
-class ReleaserConfiguration {
-
- @Bean Releaser releaser(ReleaserProperties properties) {
- return new Releaser(properties, new ProjectUpdater(properties), new ProjectBuilder(properties));
- }
-}
diff --git a/spring-cloud-release-tools-spring/src/main/resources/application.properties b/spring-cloud-release-tools-spring/src/main/resources/application.properties
deleted file mode 100644
index e69de29b..00000000
diff --git a/spring-cloud-release-tools-spring/src/test/java/org/springframework/cloud/release/ReleaserApplicationTests.java b/spring-cloud-release-tools-spring/src/test/java/org/springframework/cloud/release/ReleaserApplicationTests.java
deleted file mode 100644
index e3a94430..00000000
--- a/spring-cloud-release-tools-spring/src/test/java/org/springframework/cloud/release/ReleaserApplicationTests.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright 2013-2017 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.springframework.cloud.release;
-
-import org.junit.Test;
-import org.springframework.boot.test.context.SpringBootTest;
-
-@SpringBootTest
-public class ReleaserApplicationTests {
-
- @Test
- public void contextLoads() {
-
- }
-}