mirror of
				https://github.com/KevinMidboe/linguist.git
				synced 2025-10-29 17:50:22 +00:00 
			
		
		
		
	hwhoops
This commit is contained in:
		| @@ -2,8 +2,7 @@ before_install: sudo apt-get install libicu-dev -y | ||||
| rvm: | ||||
|   - 1.8.7 | ||||
|   - 1.9.2 | ||||
|   - jruby | ||||
|   - rbx | ||||
|   - 1.9.3 | ||||
|   - ree | ||||
| notifications: | ||||
|   disabled: true | ||||
|   | ||||
| @@ -53,7 +53,7 @@ module Linguist | ||||
|     # | ||||
|     # Returns a content type String. | ||||
|     def content_type | ||||
|       @content_type ||= binary? ? mime_type : | ||||
|       @content_type ||= (binary_mime_type? || binary?) ? mime_type : | ||||
|         (encoding ? "text/plain; charset=#{encoding.downcase}" : "text/plain") | ||||
|     end | ||||
|  | ||||
| @@ -423,8 +423,15 @@ module Linguist | ||||
|     def guess_cls_language | ||||
|       if lines.grep(/^(%|\\)/).any? | ||||
|         Language['TeX'] | ||||
|       else | ||||
|       elsif lines.grep(/^\s*(CLASS|METHOD|INTERFACE).*:\s*/i).any? || lines.grep(/^\s*(USING|DEFINE)/i).any? | ||||
|         Language['OpenEdge ABL'] | ||||
|       elsif lines.grep(/\{$/).any? || lines.grep(/\}$/).any? | ||||
|         Language['Apex'] | ||||
|       elsif lines.grep(/^(\'\*|Attribute|Option|Sub|Private|Protected|Public|Friend)/i).any? | ||||
|         Language['Visual Basic'] | ||||
|       else | ||||
|         # The most common language should be the fallback | ||||
|         Language['TeX'] | ||||
|       end | ||||
|     end | ||||
|  | ||||
|   | ||||
| @@ -1,5 +1,6 @@ | ||||
| require 'yaml' | ||||
| require 'escape_utils' | ||||
| require 'pygments' | ||||
| require 'yaml' | ||||
|  | ||||
| module Linguist | ||||
|   # Language names that are recognizable by GitHub. Defined languages | ||||
| @@ -193,6 +194,13 @@ module Linguist | ||||
|       @unpopular ||= all.select(&:unpopular?).sort_by { |lang| lang.name.downcase } | ||||
|     end | ||||
|  | ||||
|     # Public: A List of languages compatible with Ace. | ||||
|     # | ||||
|     # Returns an Array of Languages. | ||||
|     def self.ace_modes | ||||
|       @ace_modes ||= all.select(&:ace_mode).sort_by { |lang| lang.name.downcase } | ||||
|     end | ||||
|  | ||||
|     # Internal: Initialize a new Language | ||||
|     # | ||||
|     # attributes - A hash of attributes | ||||
| @@ -213,6 +221,8 @@ module Linguist | ||||
|       @lexer = Pygments::Lexer.find_by_name(attributes[:lexer] || name) || | ||||
|         raise(ArgumentError, "#{@name} is missing lexer") | ||||
|  | ||||
|       @ace_mode = attributes[:ace_mode] | ||||
|  | ||||
|       # Set legacy search term | ||||
|       @search_term = attributes[:search_term] || default_alias_name | ||||
|  | ||||
| @@ -285,6 +295,17 @@ module Linguist | ||||
|     # Returns the Lexer | ||||
|     attr_reader :lexer | ||||
|  | ||||
|     # Public: Get Ace mode | ||||
|     # | ||||
|     # Examples | ||||
|     # | ||||
|     #  # => "text" | ||||
|     #  # => "javascript" | ||||
|     #  # => "c_cpp" | ||||
|     # | ||||
|     # Returns a String name or nil | ||||
|     attr_reader :ace_mode | ||||
|  | ||||
|     # Public: Get extensions | ||||
|     # | ||||
|     # Examples | ||||
| @@ -322,6 +343,19 @@ module Linguist | ||||
|     # Returns the extensions Array | ||||
|     attr_reader :filenames | ||||
|  | ||||
|     # Public: Get URL escaped name. | ||||
|     # | ||||
|     # Examples | ||||
|     # | ||||
|     #   "C%23" | ||||
|     #   "C%2B%2B" | ||||
|     #   "Common%20Lisp" | ||||
|     # | ||||
|     # Returns the escaped String. | ||||
|     def escaped_name | ||||
|       EscapeUtils.escape_url(name).gsub('+', '%20') | ||||
|     end | ||||
|  | ||||
|     # Internal: Get default alias name | ||||
|     # | ||||
|     # Returns the alias name String | ||||
| @@ -403,6 +437,7 @@ module Linguist | ||||
|       :type              => options['type'], | ||||
|       :aliases           => options['aliases'], | ||||
|       :lexer             => options['lexer'], | ||||
|       :ace_mode          => options['ace_mode'], | ||||
|       :group_name        => options['group'], | ||||
|       :searchable        => options.key?('searchable') ? options['searchable'] : true, | ||||
|       :search_term       => options['search_term'], | ||||
|   | ||||
| @@ -9,6 +9,7 @@ | ||||
| # lexer             - An explicit lexer String (defaults to name.downcase) | ||||
| # aliases           - An Array of additional aliases (implicitly | ||||
| #                     includes name.downcase) | ||||
| # ace_mode          - A String name of Ace Mode (if available) | ||||
| # extension         - An Array of associated extensions | ||||
| # primary_extension - A String for the main extension associated with | ||||
| #                     the langauge. (defaults to extensions.first) | ||||
| @@ -54,6 +55,12 @@ Ada: | ||||
|   - .adb | ||||
|   - .ads | ||||
|  | ||||
| Apex: | ||||
|   type: programming | ||||
|   lexer: Text only | ||||
|   extensions: | ||||
|   - .cls | ||||
|  | ||||
| AppleScript: | ||||
|   aliases: | ||||
|   - osascript | ||||
| @@ -137,6 +144,7 @@ C: | ||||
|  | ||||
| C#: | ||||
|   type: programming | ||||
|   ace_mode: csharp | ||||
|   search_term: csharp | ||||
|   aliases: | ||||
|   - csharp | ||||
| @@ -145,6 +153,7 @@ C#: | ||||
|  | ||||
| C++: | ||||
|   type: programming | ||||
|   ace_mode: c_cpp | ||||
|   search_term: cpp | ||||
|   aliases: | ||||
|   - cpp | ||||
| @@ -185,6 +194,7 @@ CMake: | ||||
|   - CMakeLists.txt | ||||
|  | ||||
| CSS: | ||||
|   ace_mode: css | ||||
|   extensions: | ||||
|   - .css | ||||
|  | ||||
| @@ -195,6 +205,7 @@ ChucK: | ||||
|  | ||||
| Clojure: | ||||
|   type: programming | ||||
|   ace_mode: clojure | ||||
|   primary_extension: .clj | ||||
|   extensions: | ||||
|   - .clj | ||||
| @@ -202,6 +213,7 @@ Clojure: | ||||
|  | ||||
| CoffeeScript: | ||||
|   type: programming | ||||
|   ace_mode: coffee | ||||
|   aliases: | ||||
|   - coffee | ||||
|   extensions: | ||||
| @@ -212,6 +224,7 @@ CoffeeScript: | ||||
| ColdFusion: | ||||
|   type: programming | ||||
|   lexer: Coldfusion HTML | ||||
|   ace_mode: coldfusion | ||||
|   search_term: cfm | ||||
|   aliases: | ||||
|   - cfm | ||||
| @@ -227,6 +240,7 @@ Common Lisp: | ||||
|   primary_extension: .lisp | ||||
|   extensions: | ||||
|   - .lisp | ||||
|   - .lsp | ||||
|   - .ny | ||||
|  | ||||
| Coq: | ||||
| @@ -295,6 +309,13 @@ Dylan: | ||||
|   extensions: | ||||
|   - .dylan | ||||
|  | ||||
| Ecere Projects: | ||||
|   type: data | ||||
|   group: JavaScript | ||||
|   lexer: JSON | ||||
|   extensions: | ||||
|   - .epj | ||||
|  | ||||
| Eiffel: | ||||
|   type: programming | ||||
|   lexer: Text only | ||||
| @@ -328,7 +349,7 @@ Erlang: | ||||
|  | ||||
| F#: | ||||
|   type: programming | ||||
|   lexer: OCaml | ||||
|   lexer: FSharp | ||||
|   search_term: ocaml | ||||
|   extensions: | ||||
|   - .fs | ||||
| @@ -371,7 +392,6 @@ Fancy: | ||||
|  | ||||
| Fantom: | ||||
|   type: programming | ||||
|   lexer: Java | ||||
|   extensions: | ||||
|   - .fan | ||||
|  | ||||
| @@ -437,7 +457,7 @@ Groff: | ||||
|  | ||||
| Groovy: | ||||
|   type: programming | ||||
|   lexer: Java | ||||
|   ace_mode: groovy | ||||
|   primary_extension: .groovy | ||||
|   extensions: | ||||
|   - .gradle | ||||
| @@ -455,6 +475,7 @@ Groovy Server Pages: | ||||
|  | ||||
| HTML: | ||||
|   type: markup | ||||
|   ace_mode: html | ||||
|   primary_extension: .html | ||||
|   extensions: | ||||
|   - .htm | ||||
| @@ -487,6 +508,7 @@ HTML+PHP: | ||||
| HaXe: | ||||
|   type: programming | ||||
|   lexer: haXe | ||||
|   ace_mode: haxe | ||||
|   extensions: | ||||
|   - .hx | ||||
|   - .hxml | ||||
| @@ -535,13 +557,14 @@ Ioke: | ||||
| JSON: | ||||
|   type: data | ||||
|   group: JavaScript | ||||
|   lexer: JavaScript | ||||
|   ace_mode: json | ||||
|   searchable: false | ||||
|   extensions: | ||||
|   - .json | ||||
|  | ||||
| Java: | ||||
|   type: programming | ||||
|   ace_mode: java | ||||
|   extensions: | ||||
|   - .java | ||||
|   - .pde | ||||
| @@ -557,6 +580,7 @@ Java Server Pages: | ||||
|  | ||||
| JavaScript: | ||||
|   type: programming | ||||
|   ace_mode: javascript | ||||
|   aliases: | ||||
|   - js | ||||
|   - node | ||||
| @@ -565,6 +589,7 @@ JavaScript: | ||||
|   - .bones | ||||
|   - .jake | ||||
|   - .js | ||||
|   - .jsfl | ||||
|   - .jsm | ||||
|   - .jss | ||||
|   - .jsx | ||||
| @@ -574,6 +599,14 @@ JavaScript: | ||||
|   filenames: | ||||
|   - Jakefile | ||||
|  | ||||
| Kotlin: | ||||
|   type: programming | ||||
|   lexer: Kotlin | ||||
|   extensions: | ||||
|   - .kt | ||||
|   - .ktm | ||||
|   - .kts | ||||
|  | ||||
| LLVM: | ||||
|   extensions: | ||||
|   - .ll | ||||
| @@ -602,6 +635,7 @@ Logtalk: | ||||
|  | ||||
| Lua: | ||||
|   type: programming | ||||
|   ace_mode: lua | ||||
|   primary_extension: .lua | ||||
|   extensions: | ||||
|   - .lua | ||||
| @@ -624,6 +658,7 @@ Mako: | ||||
| Markdown: | ||||
|   type: markup | ||||
|   lexer: Text only | ||||
|   ace_mode: markdown | ||||
|   primary_extension: .md | ||||
|   extensions: | ||||
|   - .markdown | ||||
| @@ -698,6 +733,7 @@ NumPy: | ||||
|  | ||||
| OCaml: | ||||
|   type: programming | ||||
|   ace_mode: ocaml | ||||
|   primary_extension: .ml | ||||
|   extensions: | ||||
|   - .ml | ||||
| @@ -729,7 +765,6 @@ Objective-J: | ||||
|  | ||||
| Opa: | ||||
|   type: programming | ||||
|   lexer: Text only | ||||
|   extensions: | ||||
|   - .opa | ||||
|  | ||||
| @@ -747,14 +782,13 @@ OpenEdge ABL: | ||||
|   - openedge | ||||
|   - abl | ||||
|   primary_extension: .p | ||||
|   overrides: | ||||
|   - .cls | ||||
|   extensions: | ||||
|   - .cls | ||||
|   - .p | ||||
|  | ||||
| PHP: | ||||
|   type: programming | ||||
|   ace_mode: php | ||||
|   extensions: | ||||
|   - .aw | ||||
|   - .ctp | ||||
| @@ -763,6 +797,8 @@ PHP: | ||||
|   - .php4 | ||||
|   - .php5 | ||||
|   - .phpt | ||||
|   filenames: | ||||
|   - Phakefile | ||||
|  | ||||
| Parrot: | ||||
|   type: programming | ||||
| @@ -789,6 +825,7 @@ Parrot Assembly: | ||||
|  | ||||
| Perl: | ||||
|   type: programming | ||||
|   ace_mode: perl | ||||
|   overrides: | ||||
|   - .pl | ||||
|   - .t | ||||
| @@ -804,9 +841,9 @@ Perl: | ||||
|   - .psgi | ||||
|   - .t | ||||
|  | ||||
| Powershell: | ||||
| PowerShell: | ||||
|   type: programming | ||||
|   lexer: Text only | ||||
|   ace_mode: powershell | ||||
|   aliases: | ||||
|   - posh | ||||
|   extensions: | ||||
| @@ -825,6 +862,8 @@ Puppet: | ||||
|   lexer: Text only | ||||
|   extensions: | ||||
|   - .pp | ||||
|   filenames: | ||||
|   - Modulefile | ||||
|  | ||||
| Pure Data: | ||||
|   type: programming | ||||
| @@ -834,6 +873,7 @@ Pure Data: | ||||
|  | ||||
| Python: | ||||
|   type: programming | ||||
|   ace_mode: python | ||||
|   primary_extension: .py | ||||
|   extensions: | ||||
|   - .py | ||||
| @@ -897,6 +937,7 @@ Redcode: | ||||
|  | ||||
| Ruby: | ||||
|   type: programming | ||||
|   ace_mode: ruby | ||||
|   aliases: | ||||
|   - jruby | ||||
|   - macruby | ||||
| @@ -937,11 +978,13 @@ Rust: | ||||
| SCSS: | ||||
|   type: markup | ||||
|   group: CSS | ||||
|   ace_mode: scss | ||||
|   extensions: | ||||
|   - .scss | ||||
|  | ||||
| SQL: | ||||
|   type: data | ||||
|   ace_mode: sql | ||||
|   searchable: false | ||||
|   extensions: | ||||
|   - .sql | ||||
| @@ -962,6 +1005,7 @@ Sass: | ||||
|  | ||||
| Scala: | ||||
|   type: programming | ||||
|   ace_mode: scala | ||||
|   primary_extension: .scala | ||||
|   extensions: | ||||
|   - .sbt | ||||
| @@ -1052,7 +1096,10 @@ Tcsh: | ||||
|  | ||||
| TeX: | ||||
|   type: markup | ||||
|   ace_mode: latex | ||||
|   primary_extension: .tex | ||||
|   overrides: | ||||
|   - .cls | ||||
|   extensions: | ||||
|   - .aux | ||||
|   - .cls | ||||
| @@ -1063,15 +1110,23 @@ TeX: | ||||
|   - .tex | ||||
|   - .toc | ||||
|  | ||||
| Tea: | ||||
|   type: markup | ||||
|   lexer: Tea | ||||
|   extensions: | ||||
|   - .tea | ||||
|  | ||||
| Text: | ||||
|   type: data | ||||
|   lexer: Text only | ||||
|   ace_mode: text | ||||
|   extensions: | ||||
|   - .txt | ||||
|  | ||||
| Textile: | ||||
|   type: markup | ||||
|   lexer: Text only | ||||
|   ace_mode: textile | ||||
|   extensions: | ||||
|   - .textile | ||||
|  | ||||
| @@ -1092,7 +1147,7 @@ Twig: | ||||
|  | ||||
| VHDL: | ||||
|   type: programming | ||||
|   lexer: Text only | ||||
|   lexer: vhdl | ||||
|   primary_extension: .vhd | ||||
|   extensions: | ||||
|   - .vhd | ||||
| @@ -1138,6 +1193,7 @@ Visual Basic: | ||||
|  | ||||
| XML: | ||||
|   type: markup | ||||
|   ace_mode: xml | ||||
|   primary_extension: .xml | ||||
|   extensions: | ||||
|   - .glade | ||||
| @@ -1184,6 +1240,14 @@ YAML: | ||||
|   filenames: | ||||
|   - .gemrc | ||||
|  | ||||
| eC: | ||||
|   type: programming | ||||
|   search_term: ec | ||||
|   primary_extension: .ec | ||||
|   extensions: | ||||
|   - .ec | ||||
|   - .eh | ||||
|  | ||||
| mupad: | ||||
|   lexer: MuPAD | ||||
|   extensions: | ||||
|   | ||||
| @@ -1,6 +1,10 @@ | ||||
| require 'mime/types' | ||||
| require 'yaml' | ||||
|  | ||||
| class MIME::Type | ||||
|   attr_accessor :override | ||||
| end | ||||
|  | ||||
| # Register additional mime type extensions | ||||
| # | ||||
| # Follows same format as mime-types data file | ||||
| @@ -33,6 +37,8 @@ File.read(File.expand_path("../mimes.yml", __FILE__)).lines.each do |line| | ||||
|     mime_type.encoding = encoding | ||||
|   end | ||||
|  | ||||
|   mime_type.override = true | ||||
|  | ||||
|   # Kind of hacky, but we need to reindex the mime type after making changes | ||||
|   MIME::Types.add_type_variant(mime_type) | ||||
|   MIME::Types.index_extensions(mime_type) | ||||
| @@ -72,6 +78,9 @@ module Linguist | ||||
|         guesses = ::MIME::Types.type_for(ext_or_mime_type) | ||||
|       end | ||||
|  | ||||
|       # Use custom override first | ||||
|       guesses.detect { |type| type.override } || | ||||
|  | ||||
|         # Prefer text mime types over binary | ||||
|         guesses.detect { |type| type.ascii? } || | ||||
|  | ||||
|   | ||||
| @@ -18,7 +18,7 @@ | ||||
| - ^tools/ | ||||
|  | ||||
| # Node depedencies | ||||
| - ^node_modules/ | ||||
| - node_modules/ | ||||
|  | ||||
| # Vendored depedencies | ||||
| - vendor/ | ||||
| @@ -88,4 +88,9 @@ | ||||
|  | ||||
| # NuGet | ||||
| - ^[Pp]ackages/ | ||||
|  | ||||
| # ExtJS | ||||
| - (^|/)ext(js)?(-\d\.\d\.\d)?(-gpl)?/ | ||||
|  | ||||
| # Samples folders | ||||
| - ^[Ss]amples/ | ||||
|   | ||||
| @@ -10,7 +10,7 @@ Gem::Specification.new do |s| | ||||
|  | ||||
|   s.add_dependency 'charlock_holmes', '~> 0.6.6' | ||||
|   s.add_dependency 'escape_utils',    '~> 0.2.3' | ||||
|   s.add_dependency 'mime-types',      '~> 1.16' | ||||
|   s.add_dependency 'pygments.rb',     '~> 0.2.7' | ||||
|   s.add_dependency 'mime-types',      '~> 1.18' | ||||
|   s.add_dependency 'pygments.rb',     '~> 0.2.8' | ||||
|   s.add_development_dependency 'rake' | ||||
| end | ||||
|   | ||||
							
								
								
									
										458
									
								
								test/fixtures/ArrayUtils.cls
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										458
									
								
								test/fixtures/ArrayUtils.cls
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,458 @@ | ||||
| /* ============================================================ | ||||
|  * This code is part of the "apex-lang" open source project avaiable at: | ||||
|  *  | ||||
|  *      http://code.google.com/p/apex-lang/ | ||||
|  * | ||||
|  * This code is licensed under the Apache License, Version 2.0.  You may obtain a  | ||||
|  * copy of the License at: | ||||
|  *  | ||||
|  *      http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  * ============================================================ | ||||
|  */ | ||||
| global class ArrayUtils {    | ||||
|      | ||||
|     global static String[] EMPTY_STRING_ARRAY = new String[]{}; | ||||
|     global static Integer MAX_NUMBER_OF_ELEMENTS_IN_LIST {get{return 1000;}} | ||||
|      | ||||
|     global static List<String> objectToString(List<Object> objects){ | ||||
|         List<String> strings = null; | ||||
|         if(objects != null){ | ||||
|         	strings = new List<String>(); | ||||
|         	if(objects.size() > 0){ | ||||
| 	            for(Object obj : objects){ | ||||
| 	                if(obj instanceof String){ | ||||
| 	                    strings.add((String)obj); | ||||
| 	                } | ||||
| 	            } | ||||
|         	} | ||||
|         } | ||||
|         return strings; | ||||
|     } | ||||
|  | ||||
|     global static Object[] reverse(Object[] anArray) { | ||||
|         if (anArray == null) { | ||||
|             return null; | ||||
|         } | ||||
|         Integer i = 0; | ||||
|         Integer j = anArray.size() - 1; | ||||
|         Object tmp; | ||||
|         while (j > i) { | ||||
|             tmp = anArray[j]; | ||||
|             anArray[j] = anArray[i]; | ||||
|             anArray[i] = tmp; | ||||
|             j--; | ||||
|             i++; | ||||
|         } | ||||
|         return anArray; | ||||
|     } | ||||
|      | ||||
|     global static SObject[] reverse(SObject[] anArray) { | ||||
|         if (anArray == null) { | ||||
|             return null; | ||||
|         } | ||||
|         Integer i = 0; | ||||
|         Integer j = anArray.size() - 1; | ||||
|         SObject tmp; | ||||
|         while (j > i) { | ||||
|             tmp = anArray[j]; | ||||
|             anArray[j] = anArray[i]; | ||||
|             anArray[i] = tmp; | ||||
|             j--; | ||||
|             i++; | ||||
|         } | ||||
|         return anArray; | ||||
|     } | ||||
|      | ||||
|     global static List<String> lowerCase(List<String> strs){ | ||||
|         List<String> returnValue = null; | ||||
|         if(strs != null){ | ||||
|             returnValue = new List<String>(); | ||||
|         	if(strs.size() > 0){ | ||||
| 	            for(String str : strs){ | ||||
| 	                returnValue.add(str == null ? null : str.toLowerCase()); | ||||
| 	            } | ||||
|             } | ||||
|         } | ||||
|         return returnValue; | ||||
|     } | ||||
|      | ||||
|     global static List<String> upperCase(List<String> strs){ | ||||
|         List<String> returnValue = null; | ||||
|         if(strs != null){ | ||||
|             returnValue = new List<String>(); | ||||
|             if(strs.size() > 0){ | ||||
| 	            for(String str : strs){ | ||||
| 	                returnValue.add(str == null ? null : str.toUpperCase()); | ||||
| 	            } | ||||
|             } | ||||
|         } | ||||
|         return returnValue; | ||||
|     } | ||||
|      | ||||
|     global static List<String> trim(List<String> strs){ | ||||
|         List<String> returnValue = null; | ||||
|         if(strs != null){ | ||||
|             returnValue = new List<String>(); | ||||
|             if(strs.size() > 0){ | ||||
| 	            for(String str : strs){ | ||||
| 	                returnValue.add(str == null ? null : str.trim()); | ||||
| 	            } | ||||
|             } | ||||
|         } | ||||
|         return returnValue; | ||||
|     } | ||||
|      | ||||
|     global static Object[] mergex(Object[] array1, Object[] array2){ | ||||
|         if(array1 == null){ return array2; } | ||||
|         if(array2 == null){ return array1; } | ||||
|         Object[] merged = new Object[array1.size() + array2.size()]; | ||||
|         for(Integer i = 0; i < array1.size(); i++){ | ||||
|             merged[i] = array1[i]; | ||||
|         } | ||||
|         for(Integer i = 0; i < array2.size(); i++){ | ||||
|             merged[i+array1.size()] = array2[i]; | ||||
|         } | ||||
|         return merged; | ||||
|     }    | ||||
|       | ||||
|     global static SObject[] mergex(SObject[] array1, SObject[] array2){ | ||||
|         if(array1 == null){ return array2; } | ||||
|         if(array2 == null){ return array1; } | ||||
|         if(array1.size() <= 0){ return array2; } | ||||
|         List<SObject> merged = new List<SObject>(); | ||||
|         for(SObject sObj : array1){ merged.add(sObj); } | ||||
|         for(SObject sObj : array2){ merged.add(sObj); } | ||||
|         return merged; | ||||
|     }    | ||||
|      | ||||
|     global static Boolean isEmpty(Object[] objectArray){ | ||||
|         if(objectArray == null){ | ||||
|             return true; | ||||
|         } | ||||
|         return objectArray.size() == 0; | ||||
|     } | ||||
|      | ||||
|     global static Boolean isEmpty(SObject[] objectArray){ | ||||
|         if(objectArray == null){ | ||||
|             return true; | ||||
|         } | ||||
|         return objectArray.size() == 0; | ||||
|     } | ||||
|      | ||||
|     global static Boolean isNotEmpty(Object[] objectArray){ | ||||
|         return !isEmpty(objectArray); | ||||
|     } | ||||
|      | ||||
|     global static Boolean isNotEmpty(SObject[] objectArray){ | ||||
|         return !isEmpty(objectArray); | ||||
|     } | ||||
|      | ||||
|     global static Object[] pluck(SObject[] objectArray, String fieldName){ | ||||
|         if(isEmpty(objectArray) || fieldName == null || fieldName.trim() == null || fieldName.trim().length() == 0){ | ||||
|             return new Object[]{}; | ||||
|         } | ||||
|         Object[] plucked = new Object[objectArray.size()]; | ||||
|         for(Integer i = 0; i < objectArray.size(); i++){ | ||||
|             plucked[i] = objectArray[i].get(fieldName); | ||||
|         } | ||||
|         return plucked; | ||||
|     } | ||||
|      | ||||
|      | ||||
|     global static String toString(Object[] objectArray){ | ||||
|         if(objectArray == null){ | ||||
|             return 'null';     | ||||
|         } | ||||
|         String returnValue = '{'; | ||||
|         for(Integer i = 0; i < objectArray.size(); i++){ | ||||
|             if(i!=0){ returnValue += ','; } | ||||
|             returnValue += '\'' + objectArray[i] + '\''; | ||||
|         } | ||||
|         returnValue += '}'; | ||||
|         return returnValue;  | ||||
|     } | ||||
|      | ||||
|     global static String toString(SObject[] objectArray){ | ||||
|         if(objectArray == null){ | ||||
|             return 'null';     | ||||
|         } | ||||
|         String returnValue = '{'; | ||||
|         for(Integer i = 0; i < objectArray.size(); i++){ | ||||
|             if(i!=0){ returnValue += ','; } | ||||
|             returnValue += '\'' + objectArray[i] + '\''; | ||||
|         } | ||||
|         returnValue += '}'; | ||||
|         return returnValue;  | ||||
|     } | ||||
|      | ||||
|     global static void assertArraysAreEqual(Object[] expected, Object[] actual){ | ||||
|         //check to see if one param is null but the other is not | ||||
|         System.assert((expected == null && actual == null)|| (expected != null && actual != null), | ||||
|             'Assertion failed, the following two arrays are not equal.  Expected: '  | ||||
|                     + ArrayUtils.toString(expected) + ', Actual: ' + ArrayUtils.toString(actual)); | ||||
|         if(expected != null && actual != null){ | ||||
|             System.assert(expected.size() == actual.size(), 'Assertion failed, the following two arrays are not equal.  Expected: '  | ||||
|                     + ArrayUtils.toString(expected) + ', Actual: ' + ArrayUtils.toString(actual)); | ||||
|             for(Integer i = 0; i < expected.size(); i++){ | ||||
|                 System.assert(expected[i] == actual[i], 'Assertion failed, the following two arrays are not equal.  Expected: '  | ||||
|                     + ArrayUtils.toString(expected) + ', Actual: ' + ArrayUtils.toString(actual)); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|      | ||||
|     global static void assertArraysAreEqual(SObject[] expected, SObject[] actual){ | ||||
|         //check to see if one param is null but the other is not | ||||
|         System.assert((expected == null && actual == null)|| (expected != null && actual != null), | ||||
|             'Assertion failed, the following two arrays are not equal.  Expected: '  | ||||
|                     + ArrayUtils.toString(expected) + ', Actual: ' + ArrayUtils.toString(actual)); | ||||
|         if(expected != null && actual != null){ | ||||
|             System.assert(expected.size() == actual.size(), 'Assertion failed, the following two arrays are not equal.  Expected: '  | ||||
|                     + ArrayUtils.toString(expected) + ', Actual: ' + ArrayUtils.toString(actual)); | ||||
|             for(Integer i = 0; i < expected.size(); i++){ | ||||
|                 System.assert(expected[i] == actual[i], 'Assertion failed, the following two arrays are not equal.  Expected: '  | ||||
|                     + ArrayUtils.toString(expected) + ', Actual: ' + ArrayUtils.toString(actual)); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|      | ||||
|     global static List<Object> merg(List<Object> list1, List<Object> list2) { | ||||
|         List<Object> returnList = new List<Object>(); | ||||
|         if(list1 != null && list2 != null && (list1.size()+list2.size()) > MAX_NUMBER_OF_ELEMENTS_IN_LIST){ | ||||
|             throw new IllegalArgumentException('Lists cannot be merged because new list would be greater than maximum number of elements in a list: ' + MAX_NUMBER_OF_ELEMENTS_IN_LIST); | ||||
|         } | ||||
|         if(isNotEmpty(list1)){ | ||||
|             for(Object elmt : list1){ | ||||
|                 returnList.add(elmt); | ||||
|             } | ||||
|         } | ||||
|         if(isNotEmpty(list2)){ | ||||
|             for(Object elmt : list2){ | ||||
|                 returnList.add(elmt); | ||||
|             } | ||||
|         } | ||||
|         return returnList; | ||||
|     } | ||||
|  | ||||
|      | ||||
|     global static List<SObject> merg(List<SObject> list1, List<SObject> list2) { | ||||
|         if(list1 != null && list2 != null && (list1.size()+list2.size()) > MAX_NUMBER_OF_ELEMENTS_IN_LIST){ | ||||
|             throw new IllegalArgumentException('Lists cannot be merged because new list would be greater than maximum number of elements in a list: ' + MAX_NUMBER_OF_ELEMENTS_IN_LIST); | ||||
|         } | ||||
|         if(isEmpty(list1) && isEmpty(list2)){ | ||||
|             return null; | ||||
|         } | ||||
|         List<SObject> returnList = new List<SObject>(); | ||||
|         if(list1 != null){ | ||||
|             for(SObject elmt : list1){ | ||||
|                 returnList.add(elmt); | ||||
|             } | ||||
|         } | ||||
|         if(list2 != null){ | ||||
|             for(SObject elmt : list2){ | ||||
|                 returnList.add(elmt); | ||||
|             } | ||||
|         } | ||||
|         return returnList; | ||||
|     } | ||||
|      | ||||
|     global static List<Object> subset(List<Object> aList, Integer count) { | ||||
|         return subset(aList,0,count); | ||||
|     } | ||||
|  | ||||
|     global static List<Object> subset(List<Object> list1, Integer startIndex, Integer count) { | ||||
|         List<Object> returnList = new List<Object>(); | ||||
|         if(list1 != null && list1.size() > 0 && startIndex >= 0 && startIndex <= list1.size()-1 && count > 0){ | ||||
|             for(Integer i = startIndex; i < list1.size() && i - startIndex < count; i++){ | ||||
|                 returnList.add(list1.get(i)); | ||||
|             } | ||||
|         } | ||||
|         return returnList; | ||||
|     } | ||||
|  | ||||
|      | ||||
|     global static List<SObject> subset(List<SObject> aList, Integer count) { | ||||
|         return subset(aList,0,count); | ||||
|     } | ||||
|  | ||||
|     global static List<SObject> subset(List<SObject> list1, Integer startIndex, Integer count) { | ||||
|         List<SObject> returnList = null; | ||||
|         if(list1 != null && list1.size() > 0 && startIndex <= list1.size()-1 && count > 0){ | ||||
|             returnList = new List<SObject>(); | ||||
|             for(Integer i = startIndex; i < list1.size() && i - startIndex < count; i++){ | ||||
|                 returnList.add(list1.get(i)); | ||||
|             } | ||||
|         } | ||||
|         return returnList; | ||||
|     } | ||||
|      | ||||
|     //=============================================== | ||||
|     //LIST/ARRAY SORTING | ||||
|     //=============================================== | ||||
|  | ||||
|     //FOR FORCE.COM PRIMITIVES (Double,Integer,ID,etc.): | ||||
|     global static List<Object> qsort(List<Object> theList) { | ||||
|         return qsort(theList,new PrimitiveComparator()); | ||||
|     } | ||||
|  | ||||
|     global static List<Object> qsort(List<Object> theList, Boolean sortAsc) { | ||||
|         return qsort(theList,new PrimitiveComparator(),sortAsc); | ||||
|     } | ||||
|      | ||||
|     global static List<Object> qsort(List<Object> theList, ObjectComparator comparator) { | ||||
|         return qsort(theList,comparator,true); | ||||
|     } | ||||
|      | ||||
|     global static List<Object> qsort(List<Object> theList, ObjectComparator comparator, Boolean sortAsc) { | ||||
|         return qsort(theList, 0, (theList == null ? 0 : theList.size()-1),comparator,sortAsc); | ||||
|     } | ||||
|      | ||||
|  | ||||
|      | ||||
|     //FOR SALESFORCE OBJECTS (sObjects): | ||||
|     global static List<SObject> qsort(List<SObject> theList, ISObjectComparator comparator) { | ||||
|         return qsort(theList,comparator,true); | ||||
|     } | ||||
|      | ||||
|     global static List<SObject> qsort(List<SObject> theList, ISObjectComparator comparator,Boolean sortAsc ) { | ||||
|         return qsort(theList,  0, (theList == null ? 0 : theList.size()-1),comparator,sortAsc); | ||||
|     } | ||||
|  | ||||
|     private static List<Object> qsort(List<Object> theList, | ||||
|                                 Integer lo0,  | ||||
|                                 Integer hi0,  | ||||
|                                 ObjectComparator comparator, | ||||
|                                 Boolean sortAsc){ | ||||
|         Integer lo = lo0; | ||||
|         Integer hi = hi0; | ||||
|       | ||||
|         if (lo >= hi) { | ||||
|             return theList; | ||||
|         } else if( lo == hi - 1 ) { | ||||
|          | ||||
|             if (( comparator.compare(theList[lo],theList[hi])>0 && sortAsc) ||  | ||||
|                   (comparator.compare(theList[lo],theList[hi])<0 && !sortAsc)     | ||||
|                 ) { | ||||
|                  Object prs = theList[lo]; | ||||
|                  theList[lo]         = theList[hi]; | ||||
|                  theList[hi]         = prs; | ||||
|             } | ||||
|             return theList; | ||||
|         } | ||||
|  | ||||
|         Object pivot = theList[(lo + hi) / 2]; | ||||
|         theList[(lo + hi) / 2] = theList[hi]; | ||||
|         theList[hi] = pivot; | ||||
|  | ||||
|         while( lo < hi ) { | ||||
|             while ((comparator.compare(theList[lo], pivot)<=0 && lo < hi && sortAsc) ||  | ||||
|                    (comparator.compare(theList[lo], pivot)>=0 && lo < hi && !sortAsc) | ||||
|                   ) { lo++; } | ||||
|             while (( comparator.compare(pivot,theList[hi])<=0 && lo < hi && sortAsc) || | ||||
|                    ( comparator.compare(pivot,theList[hi])>=0 && lo < hi && !sortAsc) | ||||
|                   ) { hi--; } | ||||
|              | ||||
|             if( lo < hi ){ | ||||
|                  Object prs = theList[lo]; | ||||
|                  theList[lo]   = theList[hi]; | ||||
|                  theList[hi]    = prs; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         theList[hi0] = theList[hi]; | ||||
|         theList[hi] = pivot; | ||||
|          | ||||
|         qsort(theList, lo0, lo-1,comparator,sortAsc); | ||||
|         qsort(theList, hi+1, hi0,comparator,sortAsc); | ||||
|         return theList; | ||||
|     }     | ||||
|          | ||||
|      | ||||
|     private static List<SObject> qsort(List<SObject> theList, | ||||
|                                 Integer lo0,  | ||||
|                                 Integer hi0,  | ||||
|                                 ISObjectComparator comparator, | ||||
|                                 Boolean sortAsc){ | ||||
|         Integer lo = lo0; | ||||
|         Integer hi = hi0; | ||||
|       | ||||
|         if (lo >= hi) { | ||||
|             return theList; | ||||
|         } else if( lo == hi - 1 ) { | ||||
|          | ||||
|             if (( comparator.compare(theList[lo],theList[hi])>0 && sortAsc) ||  | ||||
|                   (comparator.compare(theList[lo],theList[hi])<0 && !sortAsc)     | ||||
|                 ) { | ||||
|                  SObject prs = theList[lo]; | ||||
|                  theList[lo]         = theList[hi]; | ||||
|                  theList[hi]         = prs; | ||||
|             } | ||||
|             return theList; | ||||
|         } | ||||
|  | ||||
|         SObject pivot = theList[(lo + hi) / 2]; | ||||
|         theList[(lo + hi) / 2] = theList[hi]; | ||||
|         theList[hi] = pivot; | ||||
|  | ||||
|         while( lo < hi ) { | ||||
|             while ((comparator.compare(theList[lo], pivot)<=0 && lo < hi && sortAsc) ||  | ||||
|                    (comparator.compare(theList[lo], pivot)>=0 && lo < hi && !sortAsc) | ||||
|                   ) { lo++; } | ||||
|             while (( comparator.compare(pivot,theList[hi])<=0 && lo < hi && sortAsc) || | ||||
|                    ( comparator.compare(pivot,theList[hi])>=0 && lo < hi && !sortAsc) | ||||
|                   ) { hi--; } | ||||
|              | ||||
|             if( lo < hi ){ | ||||
|                  SObject prs = theList[lo]; | ||||
|                  theList[lo]   = theList[hi]; | ||||
|                  theList[hi]    = prs; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         theList[hi0] = theList[hi]; | ||||
|         theList[hi] = pivot; | ||||
|          | ||||
|         qsort(theList, lo0, lo-1,comparator,sortAsc); | ||||
|         qsort(theList, hi+1, hi0,comparator,sortAsc); | ||||
|         return theList; | ||||
|     } | ||||
| /* | ||||
|     global static List<Object> unique(List<Object> theList) { | ||||
|         List<Object> uniques = new List<Object>(); | ||||
|         Set<Object> keys = new Set<Object>();  | ||||
|         if(theList != null && theList.size() > 0){ | ||||
|             for(Object obj : theList){ | ||||
|                 if(keys.contains(obj)){ | ||||
|                     continue; | ||||
|                 } else { | ||||
|                     keys.add(obj); | ||||
|                     uniques.add(obj); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         return uniques; | ||||
|     } | ||||
|  | ||||
|     global static List<SObject> unique(List<SObject> theList) { | ||||
|         if(theList == null){ | ||||
|             return null; | ||||
|         } | ||||
|         List<SObject> uniques = createEmptySObjectList(theList.get(0)); | ||||
|         Set<String> keys = new Set<String>();  | ||||
|         if(theList != null && theList.size() > 0){ | ||||
|             String key = null; | ||||
|             for(SObject obj : theList){ | ||||
|                 key = obj == null ? null : ''+obj; | ||||
|                 if(keys.contains(key)){ | ||||
|                     continue; | ||||
|                 } else { | ||||
|                     keys.add(key); | ||||
|                     uniques.add(obj); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         return uniques; | ||||
|     } | ||||
| */ | ||||
|  | ||||
|  | ||||
| } | ||||
							
								
								
									
										574
									
								
								test/fixtures/Email.cls
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										574
									
								
								test/fixtures/Email.cls
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,574 @@ | ||||
|  | ||||
|  /*------------------------------------------------------------------------ | ||||
|     File        : Email | ||||
|     Purpose     : Abstraction of an Email message | ||||
|     Description : Holds information needed for an email message - senders, | ||||
|                   recipients, subject, a message body, attachment files, and | ||||
|                   other extra information such as importance, priority, | ||||
|                   sensitivity, custom reply-to addresses, delivery receipts, | ||||
|                   read receipts, custom sent date, reply-by date, and expire date. | ||||
|     Author(s)   : Abe Voelker | ||||
|     Created     : Sat Jul 17 16:27:05 CDT 2010 | ||||
|   ----------------------------------------------------------------------*/ | ||||
|  | ||||
| USING Progress.Lang.*. | ||||
|  | ||||
|  | ||||
| CLASS email.Email  USE-WIDGET-POOL: | ||||
|  | ||||
|     &SCOPED-DEFINE QUOTES                """" | ||||
|     &SCOPED-DEFINE CR                    CHR(13) | ||||
|     &SCOPED-DEFINE LF                    CHR(10) | ||||
|     &SCOPED-DEFINE DEFAULT_MIME_BOUNDARY "!@#$%^&*+-._MIME_BOUNDARY_.-+*&^%$#@!" | ||||
|  | ||||
|     /*------------------------------------------------------------------------------ | ||||
|             Purpose: | ||||
|             Notes: | ||||
|     ------------------------------------------------------------------------------*/ | ||||
|  | ||||
|     DEFINE PRIVATE VARIABLE objSendEmailAlgorithm AS email.SendEmailAlgorithm NO-UNDO. | ||||
|  | ||||
|     DEFINE PRIVATE TEMP-TABLE ttSenders NO-UNDO | ||||
|       FIELD cEmailAddress AS CHARACTER | ||||
|       FIELD cRealName     AS CHARACTER INITIAL ? | ||||
|       INDEX IXPK_ttSenders cEmailAddress. | ||||
|  | ||||
|     DEFINE PRIVATE TEMP-TABLE ttToRecipients NO-UNDO | ||||
|       FIELD cEmailAddress AS CHARACTER | ||||
|       FIELD cRealName     AS CHARACTER INITIAL ? | ||||
|       INDEX IXPK_ttToRecipients cEmailAddress. | ||||
|  | ||||
|     DEFINE PRIVATE TEMP-TABLE ttCCRecipients NO-UNDO | ||||
|       FIELD cEmailAddress AS CHARACTER | ||||
|       FIELD cRealName     AS CHARACTER INITIAL ? | ||||
|       INDEX IXPK_ttCCRecipients cEmailAddress. | ||||
|  | ||||
|     DEFINE PRIVATE TEMP-TABLE ttBCCRecipients NO-UNDO | ||||
|       FIELD cEmailAddress AS CHARACTER | ||||
|       FIELD cRealName     AS CHARACTER INITIAL ? | ||||
|       INDEX IXPK_ttBCCRecipients cEmailAddress. | ||||
|  | ||||
|     DEFINE PRIVATE TEMP-TABLE ttReplyToRecipients NO-UNDO | ||||
|       FIELD cEmailAddress AS CHARACTER | ||||
|       FIELD cRealName     AS CHARACTER INITIAL ? | ||||
|       INDEX IXPK_ttReplyToRecipients cEmailAddress. | ||||
|  | ||||
|     DEFINE PRIVATE TEMP-TABLE ttReadReceiptRecipients NO-UNDO | ||||
|       FIELD cEmailAddress AS CHARACTER | ||||
|       FIELD cRealName     AS CHARACTER INITIAL ? | ||||
|       INDEX IXPK_ttReadReceiptRecipients cEmailAddress. | ||||
|  | ||||
|     DEFINE PRIVATE TEMP-TABLE ttDeliveryReceiptRecipients NO-UNDO | ||||
|       FIELD cEmailAddress AS CHARACTER | ||||
|       FIELD cRealName     AS CHARACTER INITIAL ? | ||||
|       INDEX IXPK_ttDeliveryReceiptRecipients cEmailAddress. | ||||
|  | ||||
|     DEFINE PRIVATE TEMP-TABLE ttAttachments NO-UNDO | ||||
|       FIELD cFileName     AS CHARACTER | ||||
|       FIELD lcData        AS Object    /* Longchar object */ | ||||
|       FIELD lBase64Encode AS LOGICAL. | ||||
|  | ||||
|     DEFINE PRIVATE VARIABLE cMimeBoundary     AS CHARACTER   NO-UNDO. | ||||
|     DEFINE PRIVATE VARIABLE lcBody            AS LONGCHAR    NO-UNDO. | ||||
|     DEFINE PRIVATE VARIABLE lBodyIsBase64     AS LOGICAL     NO-UNDO. | ||||
|     DEFINE PRIVATE VARIABLE cSubject          AS CHARACTER   NO-UNDO. | ||||
|     DEFINE PRIVATE VARIABLE mptrAttachments   AS MEMPTR      NO-UNDO. | ||||
|     DEFINE PRIVATE VARIABLE cImportance       AS CHARACTER   NO-UNDO. | ||||
|     DEFINE PRIVATE VARIABLE cSensitivity      AS CHARACTER   NO-UNDO. | ||||
|     DEFINE PRIVATE VARIABLE cPriority         AS CHARACTER   NO-UNDO. | ||||
|     DEFINE PRIVATE VARIABLE dttmtzSentDate    AS DATETIME-TZ INITIAL ? NO-UNDO. | ||||
|     DEFINE PRIVATE VARIABLE dttmtzReplyByDate AS DATETIME-TZ INITIAL ? NO-UNDO. | ||||
|     DEFINE PRIVATE VARIABLE dttmtzExpireDate  AS DATETIME-TZ INITIAL ? NO-UNDO. | ||||
|  | ||||
|     DEFINE PRIVATE VARIABLE cNewLine          AS CHARACTER   NO-UNDO. | ||||
|  | ||||
|     /* Other email headers: */ | ||||
|  | ||||
|     CONSTRUCTOR PUBLIC Email (INPUT ipobjSendEmailAlgorithm AS email.SendEmailAlgorithm): | ||||
|         SUPER (). | ||||
|         ASSIGN objSendEmailAlgorithm = ipobjSendEmailAlgorithm | ||||
|                cMimeBoundary         = {&DEFAULT_MIME_BOUNDARY} | ||||
|                lBodyIsBase64         = TRUE. | ||||
|         IF (OPSYS BEGINS "WIN") THEN | ||||
|             ASSIGN cNewLine          = {&CR} + {&LF}. | ||||
|         ELSE | ||||
|             ASSIGN cNewLine          = {&LF}. | ||||
|     END CONSTRUCTOR. | ||||
|  | ||||
|     DESTRUCTOR PUBLIC Email (): | ||||
|         FOR EACH ttAttachments: | ||||
|             IF VALID-OBJECT(ttAttachments.lcData) THEN | ||||
|                 DELETE OBJECT ttAttachments.lcData NO-ERROR. | ||||
|         END. /* FOR EACH ttAttachments */ | ||||
|     END DESTRUCTOR. | ||||
|  | ||||
|     /* Add a sender ("From:" address) to the email */ | ||||
|     METHOD PUBLIC VOID addSender(INPUT ipcEmailAddress AS CHARACTER): | ||||
|         IF NOT CAN-FIND(FIRST ttSenders | ||||
|                         WHERE ttSenders.cEmailAddress EQ ipcEmailAddress) THEN DO: | ||||
|             CREATE ttSenders. | ||||
|             ASSIGN ttSenders.cEmailAddress = ipcEmailAddress. | ||||
|         END. | ||||
|     END METHOD. | ||||
|  | ||||
|     /* Add a sender ("From:" address) (with Real Name) to the email */ | ||||
|     METHOD PUBLIC VOID addSender(INPUT ipcEmailAddress AS CHARACTER, | ||||
|                                  INPUT ipcRealName     AS CHARACTER): | ||||
|         IF NOT CAN-FIND(FIRST ttSenders | ||||
|                         WHERE ttSenders.cEmailAddress EQ ipcEmailAddress) THEN DO: | ||||
|             CREATE ttSenders. | ||||
|             ASSIGN ttSenders.cEmailAddress = ipcEmailAddress | ||||
|                    ttSenders.cRealName     = ipcRealName. | ||||
|         END. | ||||
|     END METHOD. | ||||
|  | ||||
|     /* Add a "To:" recipient to the email */ | ||||
|     METHOD PUBLIC VOID addToRecipient(INPUT ipcEmailAddress AS CHARACTER): | ||||
|         IF NOT CAN-FIND(FIRST ttToRecipients | ||||
|                         WHERE ttToRecipients.cEmailAddress EQ ipcEmailAddress) THEN DO: | ||||
|             CREATE ttToRecipients. | ||||
|             ASSIGN ttToRecipients.cEmailAddress = ipcEmailAddress. | ||||
|         END. | ||||
|     END METHOD. | ||||
|  | ||||
|     /* Add a "To:" recipient (with Real Name) to the email */ | ||||
|     METHOD PUBLIC VOID addToRecipient(INPUT ipcEmailAddress AS CHARACTER, | ||||
|                                       INPUT ipcRealName     AS CHARACTER): | ||||
|         IF NOT CAN-FIND(FIRST ttToRecipients | ||||
|                         WHERE ttToRecipients.cEmailAddress EQ ipcEmailAddress) THEN DO: | ||||
|             CREATE ttToRecipients. | ||||
|             ASSIGN ttToRecipients.cEmailAddress = ipcEmailAddress | ||||
|                    ttToRecipients.cRealName     = ipcRealName. | ||||
|         END. | ||||
|     END METHOD. | ||||
|  | ||||
|     /* Add a "CC:" recipient to the email */ | ||||
|     METHOD PUBLIC VOID addCCRecipient(INPUT ipcEmailAddress AS CHARACTER): | ||||
|         IF NOT CAN-FIND(FIRST ttCCRecipients | ||||
|                         WHERE ttCCRecipients.cEmailAddress EQ ipcEmailAddress) THEN DO: | ||||
|             CREATE ttCCRecipients. | ||||
|             ASSIGN ttCCRecipients.cEmailAddress = ipcEmailAddress. | ||||
|         END. | ||||
|     END METHOD. | ||||
|  | ||||
|     /* Add a "CC:" recipient (with Real Name) to the email */ | ||||
|     METHOD PUBLIC VOID addCCRecipient(INPUT ipcEmailAddress AS CHARACTER, | ||||
|                                       INPUT ipcRealName     AS CHARACTER): | ||||
|         IF NOT CAN-FIND(FIRST ttCCRecipients | ||||
|                         WHERE ttCCRecipients.cEmailAddress EQ ipcEmailAddress) THEN DO: | ||||
|             CREATE ttCCRecipients. | ||||
|             ASSIGN ttCCRecipients.cEmailAddress = ipcEmailAddress | ||||
|                    ttToRecipients.cRealName     = ipcRealName. | ||||
|         END. | ||||
|     END METHOD. | ||||
|  | ||||
|     /* Add a "BCC:" recipient to the email */ | ||||
|     METHOD PUBLIC VOID addBCCRecipient(INPUT ipcEmailAddress AS CHARACTER): | ||||
|         IF NOT CAN-FIND(FIRST ttBCCRecipients | ||||
|                         WHERE ttBCCRecipients.cEmailAddress EQ ipcEmailAddress) THEN DO: | ||||
|             CREATE ttBCCRecipients. | ||||
|             ASSIGN ttBCCRecipients.cEmailAddress = ipcEmailAddress. | ||||
|         END. | ||||
|     END METHOD. | ||||
|  | ||||
|     /* Add a "BCC:" recipient (with Real Name) to the email */ | ||||
|     METHOD PUBLIC VOID addBCCRecipient(INPUT ipcEmailAddress AS CHARACTER, | ||||
|                                        INPUT ipcRealName     AS CHARACTER): | ||||
|         IF NOT CAN-FIND(FIRST ttBCCRecipients | ||||
|                         WHERE ttBCCRecipients.cEmailAddress EQ ipcEmailAddress) THEN DO: | ||||
|             CREATE ttBCCRecipients. | ||||
|             ASSIGN ttBCCRecipients.cEmailAddress = ipcEmailAddress | ||||
|                    ttToRecipients.cRealName      = ipcRealName. | ||||
|         END. | ||||
|     END METHOD. | ||||
|  | ||||
|     /* Add a reply-to recipient to the email */ | ||||
|     METHOD PUBLIC VOID addReplyToRecipient(INPUT ipcEmailAddress AS CHARACTER): | ||||
|         IF NOT CAN-FIND(FIRST ttReplyToRecipients | ||||
|                         WHERE ttReplyToRecipients.cEmailAddress EQ ipcEmailAddress) THEN DO: | ||||
|             CREATE ttReplyToRecipients. | ||||
|             ASSIGN ttReplyToRecipients.cEmailAddress = ipcEmailAddress. | ||||
|         END. | ||||
|     END METHOD. | ||||
|  | ||||
|     /* Add a  reply-to recipient (with Real Name) to the email */ | ||||
|     METHOD PUBLIC VOID addReplyToRecipient(INPUT ipcEmailAddress AS CHARACTER, | ||||
|                                            INPUT ipcRealName     AS CHARACTER): | ||||
|         IF NOT CAN-FIND(FIRST ttReplyToRecipients | ||||
|                         WHERE ttReplyToRecipients.cEmailAddress EQ ipcEmailAddress) THEN DO: | ||||
|             CREATE ttReplyToRecipients. | ||||
|             ASSIGN ttReplyToRecipients.cEmailAddress = ipcEmailAddress | ||||
|                    ttReplyToRecipients.cRealName     = ipcRealName. | ||||
|         END. | ||||
|     END METHOD. | ||||
|  | ||||
|     /* Add a delivery receipt recipient to the email */ | ||||
|     METHOD PUBLIC VOID addDeliveryReceiptRecipient(INPUT ipcEmailAddress AS CHARACTER): | ||||
|         IF NOT CAN-FIND(FIRST ttDeliveryReceiptRecipients | ||||
|                         WHERE ttDeliveryReceiptRecipients.cEmailAddress EQ ipcEmailAddress) THEN DO: | ||||
|             CREATE ttDeliveryReceiptRecipients. | ||||
|             ASSIGN ttDeliveryReceiptRecipients.cEmailAddress = ipcEmailAddress. | ||||
|         END. | ||||
|     END METHOD. | ||||
|  | ||||
|     /* Add a delivery receipt recipient (with Real Name) to the email */ | ||||
|     METHOD PUBLIC VOID addDeliveryReceiptRecipient(INPUT ipcEmailAddress AS CHARACTER, | ||||
|                                                    INPUT ipcRealName     AS CHARACTER): | ||||
|         IF NOT CAN-FIND(FIRST ttDeliveryReceiptRecipients | ||||
|                         WHERE ttDeliveryReceiptRecipients.cEmailAddress EQ ipcEmailAddress) THEN DO: | ||||
|             CREATE ttDeliveryReceiptRecipients. | ||||
|             ASSIGN ttDeliveryReceiptRecipients.cEmailAddress = ipcEmailAddress | ||||
|                    ttDeliveryReceiptRecipients.cRealName     = ipcRealName. | ||||
|         END. | ||||
|     END METHOD. | ||||
|  | ||||
|     /* Add a read receipt recipient to the email */ | ||||
|     METHOD PUBLIC VOID addReadReceiptRecipient(INPUT ipcEmailAddress AS CHARACTER): | ||||
|         IF NOT CAN-FIND(FIRST ttReadReceiptRecipients | ||||
|                         WHERE ttReadReceiptRecipients.cEmailAddress EQ ipcEmailAddress) THEN DO: | ||||
|             CREATE ttReadReceiptRecipients. | ||||
|             ASSIGN ttReadReceiptRecipients.cEmailAddress = ipcEmailAddress. | ||||
|         END. | ||||
|     END METHOD. | ||||
|  | ||||
|     /* Add a read receipt recipient (with Real Name) to the email */ | ||||
|     METHOD PUBLIC VOID addReadReceiptRecipient(INPUT ipcEmailAddress AS CHARACTER, | ||||
|                                                INPUT ipcRealName     AS CHARACTER): | ||||
|         IF NOT CAN-FIND(FIRST ttReadReceiptRecipients | ||||
|                         WHERE ttReadReceiptRecipients.cEmailAddress EQ ipcEmailAddress) THEN DO: | ||||
|             CREATE ttReadReceiptRecipients. | ||||
|             ASSIGN ttReadReceiptRecipients.cEmailAddress = ipcEmailAddress | ||||
|                    ttReadReceiptRecipients.cRealName     = ipcRealName. | ||||
|         END. | ||||
|     END METHOD. | ||||
|  | ||||
|     /* Set the subject of the email */ | ||||
|     METHOD PUBLIC VOID setSubject(INPUT ipcSubject AS CHARACTER): | ||||
|         ASSIGN cSubject = ipcSubject. | ||||
|     END METHOD. | ||||
|  | ||||
|     /* Set the importance of the email. H = High, L = Low, anything else = Medium/None */ | ||||
|     METHOD PUBLIC VOID setImportance(INPUT ipcImportance AS CHARACTER): | ||||
|         ASSIGN cImportance = ipcImportance. | ||||
|     END METHOD. | ||||
|  | ||||
|     /* Set the sensitivity of the email. */ | ||||
|     /* Possible values (from RFC 2156): "Personal", "Private", or "Company confidential" ("Company-confidential") */ | ||||
|     METHOD PUBLIC VOID setSensitivity(INPUT ipcSensitivity AS CHARACTER): | ||||
|         ASSIGN cSensitivity = ipcSensitivity. | ||||
|     END METHOD. | ||||
|  | ||||
|     /* Set the priority of the email (to affect transmission speed and delivery) */ | ||||
|     /* Possible values (from RFC 2156): "normal", "urgent", or "non-urgent" */ | ||||
|     METHOD PUBLIC VOID setPriority(INPUT ipcPriority AS CHARACTER): | ||||
|         ASSIGN cPriority = ipcPriority. | ||||
|     END METHOD. | ||||
|  | ||||
|     /* Set the date/time the email was sent */ | ||||
|     METHOD PUBLIC VOID setSentDate(INPUT ipdttmtzSentDate AS DATETIME-TZ): | ||||
|         ASSIGN dttmtzSentDate = ipdttmtzSentDate. | ||||
|     END METHOD. | ||||
|  | ||||
|     /* Set the date/time recipient(s) should reply by */ | ||||
|     METHOD PUBLIC VOID setReplyByDate(INPUT ipdttmtzReplyByDate AS DATETIME-TZ): | ||||
|         ASSIGN dttmtzReplyByDate = ipdttmtzReplyByDate. | ||||
|     END METHOD. | ||||
|  | ||||
|     /* Set the date/time the message expires */ | ||||
|     METHOD PUBLIC VOID setExpireDate(INPUT ipdttmtzExpireDate AS DATETIME-TZ): | ||||
|         ASSIGN dttmtzExpireDate = ipdttmtzExpireDate. | ||||
|     END METHOD. | ||||
|  | ||||
|     /* If send email algorithm not set in constructor, you must set it using this method before the email can be sent */ | ||||
|     METHOD PUBLIC VOID setSendEmailAlgorithm(INPUT ipobjSendEmailAlgorithm AS email.SendEmailAlgorithm): | ||||
|         ASSIGN objSendEmailAlgorithm = ipobjSendEmailAlgorithm. | ||||
|     END METHOD. | ||||
|  | ||||
|     METHOD PUBLIC VOID setBodyText(INPUT ipcBodyText AS CHARACTER): | ||||
|         ASSIGN lcBody = ipcBodyText. | ||||
|     END METHOD. | ||||
|  | ||||
|     METHOD PUBLIC VOID setBodyText(INPUT iplcBodyText AS LONGCHAR): | ||||
|         ASSIGN lcBody = iplcBodyText. | ||||
|     END METHOD. | ||||
|  | ||||
|     /* Set the body by reading in an external file */ | ||||
|     METHOD PUBLIC CHARACTER setBodyFile(INPUT ipcBodyFile AS CHARACTER): | ||||
|         FILE-INFO:FILE-NAME = ipcBodyFile. | ||||
|         IF FILE-INFO:FULL-PATHNAME EQ ? THEN | ||||
|             RETURN "Cannot locate file '" + ipcBodyFile + "' in the filesystem!". | ||||
|         IF INDEX(FILE-INFO:FILE-TYPE, "R") EQ 0 THEN | ||||
|             RETURN "File '" + FILE-INFO:FULL-PATHNAME + "' exists but is not readable!". | ||||
|         COPY-LOB FROM FILE FILE-INFO:FULL-PATHNAME TO OBJECT lcBody NO-ERROR. | ||||
|         IF ERROR-STATUS:ERROR THEN | ||||
|             RETURN "Error copying from file: " + ERROR-STATUS:GET-MESSAGE(1). | ||||
|         RETURN "". /* Success */ | ||||
|     END METHOD. | ||||
|  | ||||
|     /* Body defaults to base64 encoding, but can be manually disabled */ | ||||
|     METHOD PUBLIC VOID setBodyEncoding(INPUT iplBase64Encode AS LOGICAL): | ||||
|         ASSIGN lBodyIsBase64 = iplBase64Encode. | ||||
|     END METHOD. | ||||
|  | ||||
|     /* Add a non-encoded file attachment to the email */ | ||||
|     METHOD PUBLIC CHARACTER addTextAttachment(INPUT ipcFileName AS CHARACTER): | ||||
|         DEFINE VARIABLE lcTemp AS LONGCHAR NO-UNDO. | ||||
|         FILE-INFO:FILE-NAME = ipcFileName. | ||||
|         IF FILE-INFO:FULL-PATHNAME EQ ? THEN | ||||
|             RETURN "Cannot locate file '" + ipcFileName + "' in the filesystem!". | ||||
|         IF INDEX(FILE-INFO:FILE-TYPE, "R") EQ 0 THEN | ||||
|             RETURN "File '" + FILE-INFO:FULL-PATHNAME + "' exists but is not readable!". | ||||
|         /* Load file into memory */ | ||||
|         COPY-LOB FROM FILE FILE-INFO:FULL-PATHNAME TO OBJECT lcTemp NO-ERROR. | ||||
|         IF ERROR-STATUS:ERROR THEN | ||||
|             RETURN "Error copying from file: " + ERROR-STATUS:GET-MESSAGE(1). | ||||
|         CREATE ttAttachments. | ||||
|         ASSIGN ttAttachments.cFileName     = ipcFileName | ||||
|                ttAttachments.lcData        = NEW email.LongcharWrapper(lcTemp) | ||||
|                ttAttachments.lBase64Encode = FALSE. | ||||
|         RETURN "". /* Success */ | ||||
|     END. | ||||
|  | ||||
|     /* Add a file attachment to the email; it defaults to base-64 encoding */ | ||||
|     METHOD PUBLIC CHARACTER addAttachment(INPUT ipcFileName AS CHARACTER): | ||||
|         DEFINE VARIABLE lcTemp AS LONGCHAR NO-UNDO. | ||||
|         FILE-INFO:FILE-NAME = ipcFileName. | ||||
|         IF FILE-INFO:FULL-PATHNAME EQ ? THEN | ||||
|             RETURN "Cannot locate file '" + ipcFileName + "' in the filesystem!". | ||||
|         IF INDEX(FILE-INFO:FILE-TYPE, "R") EQ 0 THEN | ||||
|             RETURN "File '" + FILE-INFO:FULL-PATHNAME + "' exists but is not readable!". | ||||
|         /* Load file into memory */ | ||||
|         COPY-LOB FROM FILE FILE-INFO:FULL-PATHNAME TO OBJECT lcTemp NO-ERROR. | ||||
|         IF ERROR-STATUS:ERROR THEN | ||||
|             RETURN "Error copying from file: " + ERROR-STATUS:GET-MESSAGE(1). | ||||
|         CREATE ttAttachments. | ||||
|         ASSIGN ttAttachments.cFileName     = ipcFileName | ||||
|                ttAttachments.lcData        = NEW email.LongcharWrapper(EmailClient.Util:ConvertDataToBase64(lcTemp)) | ||||
|                ttAttachments.lBase64Encode = TRUE. | ||||
|         RETURN "". /* Success */ | ||||
|     END. | ||||
|  | ||||
|     /* Override default MIME boundary */ | ||||
|     METHOD PUBLIC VOID setMimeBoundary(INPUT ipcMimeBoundary AS CHARACTER): | ||||
|         ASSIGN cMimeBoundary = ipcMimeBoundary. | ||||
|     END METHOD. | ||||
|  | ||||
|     /* Return a concatenated list of To:, CC:, and BCC: recipients */ | ||||
|     METHOD PUBLIC CHARACTER getRecipients(): | ||||
|         DEFINE VARIABLE cRecipients AS CHARACTER NO-UNDO. | ||||
|  | ||||
|         FOR EACH ttToRecipients | ||||
|           BREAK BY ttToRecipients.cEmailAddress: | ||||
|             ASSIGN cRecipients = cRecipients + ttToRecipients.cEmailAddress. | ||||
|             IF NOT LAST(ttToRecipients.cEmailAddress) THEN DO: | ||||
|                 ASSIGN cRecipients = cRecipients + ", ". | ||||
|             END. | ||||
|         END. | ||||
|         FOR EACH ttCCRecipients | ||||
|           BREAK BY ttCCRecipients.cEmailAddress: | ||||
|             IF FIRST(ttCCRecipients.cEmailAddress) AND | ||||
|                cRecipients NE "" THEN | ||||
|                 ASSIGN cRecipients = cRecipients + ", ". | ||||
|             ASSIGN cRecipients = cRecipients + ttCCRecipients.cEmailAddress. | ||||
|             IF NOT LAST(ttCCRecipients.cEmailAddress) THEN | ||||
|                 ASSIGN cRecipients = cRecipients + ttCCRecipients.cEmailAddress. | ||||
|         END. | ||||
|         FOR EACH ttBCCRecipients | ||||
|           BREAK BY ttBCCRecipients.cEmailAddress: | ||||
|             IF FIRST(ttBCCRecipients.cEmailAddress) AND | ||||
|                cRecipients NE "" THEN | ||||
|                 ASSIGN cRecipients = cRecipients + ", ". | ||||
|             ASSIGN cRecipients = cRecipients + ttBCCRecipients.cEmailAddress. | ||||
|             IF NOT LAST(ttBCCRecipients.cEmailAddress) THEN | ||||
|                 ASSIGN cRecipients = cRecipients + ttBCCRecipients.cEmailAddress. | ||||
|         END. | ||||
|         RETURN cRecipients. | ||||
|     END METHOD. | ||||
|  | ||||
|     /* Dumps all email message headers to CHAR */ | ||||
|     METHOD PUBLIC CHARACTER getHeaders(): | ||||
|         DEFINE VARIABLE cReturnData AS CHARACTER NO-UNDO. | ||||
|  | ||||
|         /* Write the "From:" header */ | ||||
|         ASSIGN cReturnData = cReturnData + {"ES} + "From:". | ||||
|         FOR EACH ttSenders | ||||
|           BREAK BY ttSenders.cEmailAddress: | ||||
|             IF ttSenders.cRealName NE ? THEN | ||||
|                 ASSIGN cReturnData = cReturnData + ttSenders.cRealName + " <" + ttSenders.cEmailAddress + ">". | ||||
|             ELSE | ||||
|                 ASSIGN cReturnData = cReturnData + ttSenders.cEmailAddress. | ||||
|             IF NOT LAST(ttSenders.cEmailAddress) THEN | ||||
|                 ASSIGN cReturnData = cReturnData + ", ". | ||||
|         END. | ||||
|         ASSIGN cReturnData = cReturnData + {"ES} + "\n". | ||||
|         /* Write the "To:" header */ | ||||
|         ASSIGN cReturnData = cReturnData + {"ES} + "To:". | ||||
|         FOR EACH ttToRecipients | ||||
|           BREAK BY ttToRecipients.cEmailAddress: | ||||
|             IF ttToRecipients.cRealName NE ? THEN | ||||
|                 ASSIGN cReturnData = cReturnData + ttToRecipients.cRealName + " <" + ttToRecipients.cEmailAddress + ">". | ||||
|             ELSE | ||||
|                 ASSIGN cReturnData = cReturnData + ttToRecipients.cEmailAddress. | ||||
|             IF NOT LAST(ttToRecipients.cEmailAddress) THEN | ||||
|                 ASSIGN cReturnData = cReturnData + ", ". | ||||
|         END. | ||||
|         ASSIGN cReturnData = cReturnData + {"ES} + "\n". | ||||
|         /* Write the "Reply-To:" header */ | ||||
|         ASSIGN cReturnData = cReturnData + {"ES} + "Reply-To:". | ||||
|         IF TEMP-TABLE ttReplyToRecipients:HAS-RECORDS THEN DO: | ||||
|             /* Use manually-overridden reply-to addresses */ | ||||
|             FOR EACH ttReplyToRecipients | ||||
|               BREAK BY ttReplyToRecipients.cEmailAddress: | ||||
|                 IF ttReplyToRecipients.cRealName NE ? THEN | ||||
|                     ASSIGN cReturnData = cReturnData + ttReplyToRecipients.cRealName + " <" + ttReplyToRecipients.cEmailAddress + ">". | ||||
|                 ELSE | ||||
|                     ASSIGN cReturnData = cReturnData + ttReplyToRecipients.cEmailAddress. | ||||
|                 IF NOT LAST(ttReplyToRecipients.cEmailAddress) THEN | ||||
|                     ASSIGN cReturnData = cReturnData + ", ". | ||||
|             END. /* FOR EACH ttReplyToRecipients ... */ | ||||
|         END. /* IF TEMP-TABLE ttReplyToRecipients:HAS-RECORDS */ | ||||
|         ELSE DO: | ||||
|             /* Write reply-to using sender addresses if reply-to addresses not manually overriddden */ | ||||
|             FOR EACH ttSenders | ||||
|               BREAK BY ttSenders.cEmailAddress: | ||||
|                 IF ttSenders.cRealName NE ? THEN | ||||
|                     ASSIGN cReturnData = cReturnData + ttSenders.cRealName + " <" + ttSenders.cEmailAddress + ">". | ||||
|                 ELSE | ||||
|                     ASSIGN cReturnData = cReturnData + ttSenders.cEmailAddress. | ||||
|                 IF NOT LAST(ttSenders.cEmailAddress) THEN | ||||
|                     ASSIGN cReturnData = cReturnData + ", ". | ||||
|             END. | ||||
|         END. /* ELSE / IF TEMP-TABLE ttReplyToRecipients:HAS-RECORDS */ | ||||
|         ASSIGN cReturnData = cReturnData + {"ES} + "\n". | ||||
|         /* Write the "Cc:" header */ | ||||
|         ASSIGN cReturnData = cReturnData + {"ES} + "Cc:". | ||||
|         FOR EACH ttCCRecipients | ||||
|           BREAK BY ttCCRecipients.cEmailAddress: | ||||
|             IF ttCCRecipients.cRealName NE ? THEN | ||||
|                 ASSIGN cReturnData = cReturnData + ttCCRecipients.cRealName + " <" + ttCCRecipients.cEmailAddress + ">". | ||||
|             ELSE | ||||
|                 ASSIGN cReturnData = cReturnData + ttCCRecipients.cEmailAddress. | ||||
|             IF NOT LAST(ttCCRecipients.cEmailAddress) THEN | ||||
|                 ASSIGN cReturnData = cReturnData + ", ". | ||||
|         END. | ||||
|         ASSIGN cReturnData = cReturnData + {"ES} + "\n". | ||||
|         /* Write the "Bcc:" header */ | ||||
|         ASSIGN cReturnData = cReturnData + {"ES} + "Bcc:". | ||||
|         FOR EACH ttBCCRecipients | ||||
|           BREAK BY ttBCCRecipients.cEmailAddress: | ||||
|             IF ttBCCRecipients.cRealName NE ? THEN | ||||
|                 ASSIGN cReturnData = cReturnData + ttBCCRecipients.cRealName + " <" + ttBCCRecipients.cEmailAddress + ">". | ||||
|             ELSE | ||||
|                 ASSIGN cReturnData = cReturnData + ttBCCRecipients.cEmailAddress. | ||||
|             IF NOT LAST(ttBCCRecipients.cEmailAddress) THEN | ||||
|                 ASSIGN cReturnData = cReturnData + ", ". | ||||
|         END. | ||||
|         ASSIGN cReturnData = cReturnData + {"ES} + "\n". | ||||
|         /* If delivery recipients specified, write each recipient out */ | ||||
|         IF TEMP-TABLE ttDeliveryReceiptRecipients:HAS-RECORDS THEN DO: | ||||
|             ASSIGN cReturnData = cReturnData + {"ES} + "Return-Receipt-To:". | ||||
|             FOR EACH ttDeliveryReceiptRecipients | ||||
|               BREAK BY ttDeliveryReceiptRecipients.cEmailAddress: | ||||
|                 IF ttDeliveryReceiptRecipients.cRealName NE ? THEN | ||||
|                     ASSIGN cReturnData = cReturnData + ttDeliveryReceiptRecipients.cRealName + " <" + ttDeliveryReceiptRecipients.cEmailAddress + ">". | ||||
|                 ELSE | ||||
|                     ASSIGN cReturnData = cReturnData + ttDeliveryReceiptRecipients.cEmailAddress. | ||||
|                 IF NOT LAST(ttDeliveryReceiptRecipients.cEmailAddress) THEN | ||||
|                     ASSIGN cReturnData = cReturnData + ", ". | ||||
|             END. /* FOR EACH ttDeliveryReceiptRecipients */ | ||||
|             ASSIGN cReturnData = cReturnData + {"ES}. | ||||
|         END. /* IF TEMP-TABLE ttDeliveryReceiptRecipients:HAS-RECORDS */ | ||||
|         /* If read recipients specified, write each recipient out */ | ||||
|         IF TEMP-TABLE ttReadReceiptRecipients:HAS-RECORDS THEN DO: | ||||
|             ASSIGN cReturnData = cReturnData + {"ES} + "Disposition-Notification-To:". | ||||
|             FOR EACH ttReadReceiptRecipients | ||||
|               BREAK BY ttReadReceiptRecipients.cEmailAddress: | ||||
|                 IF ttReadReceiptRecipients.cRealName NE ? THEN | ||||
|                     ASSIGN cReturnData = cReturnData + ttReadReceiptRecipients.cRealName + " <" + ttReadReceiptRecipients.cEmailAddress + ">". | ||||
|                 ELSE | ||||
|                     ASSIGN cReturnData = cReturnData + ttReadReceiptRecipients.cEmailAddress. | ||||
|                 IF NOT LAST(ttReadReceiptRecipients.cEmailAddress) THEN | ||||
|                     ASSIGN cReturnData = cReturnData + ", ". | ||||
|             END. /* FOR EACH ttReadReceiptRecipients */ | ||||
|             ASSIGN cReturnData = cReturnData + {"ES}. | ||||
|         END. /* IF TEMP-TABLE ttReadReceiptRecipients:HAS-RECORDS */ | ||||
|         /* Write the "Subject:" header */ | ||||
|         ASSIGN cReturnData = cReturnData + "\n" + {"ES} + "Subject:" + cSubject + {"ES}. | ||||
|         /* Write the "Importance:" header */ | ||||
|         IF cImportance BEGINS "H" THEN | ||||
|             ASSIGN cReturnData = cReturnData + "\n" + {"ES} + "Importance:High" + {"ES}. | ||||
|         ELSE IF cImportance BEGINS "L" THEN | ||||
|             ASSIGN cReturnData = cReturnData + "\n" + {"ES} + "Importance:Low" + {"ES}. | ||||
|         /* Write the "Sensitivity" header */ | ||||
|         IF cSensitivity NE "" THEN | ||||
|             ASSIGN cReturnData = cReturnData + "\n" + {"ES} + "Sensitivity:" + cSensitivity + {"ES}. | ||||
|         /* Write the "Priority" header */ | ||||
|         IF cPriority NE "" THEN | ||||
|             ASSIGN cReturnData = cReturnData + "\n" + {"ES} + "Priority:" + cPriority + {"ES}. | ||||
|         /* Write the "Date" (sent date) header */ | ||||
|         IF dttmtzSentDate NE ? THEN | ||||
|             ASSIGN cReturnData = cReturnData + "\n" + {"ES} + "Date:" + email.Util:ABLDateTimeToEmail(dttmtzSentDate) + {"ES}. | ||||
|         IF dttmtzReplyByDate NE ? THEN | ||||
|             ASSIGN cReturnData = cReturnData + "\n" + {"ES} + "Reply-By:" + email.Util:ABLDateTimeToEmail(dttmtzReplyByDate) + {"ES}. | ||||
|         /* Write the "Expiry-Date" header */ | ||||
|         IF dttmtzExpireDate NE ? THEN | ||||
|             ASSIGN cReturnData = cReturnData + "\n" + {"ES} + "Expiry-Date:" + email.Util:ABLDateTimeToEmail(dttmtzExpireDate) + {"ES}. | ||||
|         RETURN cReturnData. | ||||
|     END METHOD. | ||||
|  | ||||
|     /* Dumps all email message payload data (body and attachments) to LONGCHAR */ | ||||
|     METHOD PUBLIC LONGCHAR getPayload(): | ||||
|         DEFINE VARIABLE lcReturnData AS LONGCHAR NO-UNDO. | ||||
|  | ||||
|         /* If no body and no text, then return empty string ("") */ | ||||
|         IF lcBody EQ "" AND NOT TEMP-TABLE ttAttachments:HAS-RECORDS THEN | ||||
|             RETURN lcReturnData. | ||||
|  | ||||
|         /* Write payload header */ | ||||
|         ASSIGN lcReturnData = "Mime-Version: 1.0" + cNewLine + | ||||
|                               "Content-Type: multipart/mixed; boundary=" + cMimeBoundary + cNewLine + cNewLine. | ||||
|  | ||||
|         /* Write out the email body, if it exists */ | ||||
|         IF lcBody NE "" THEN DO: | ||||
|             ASSIGN lcReturnData = lcReturnData + "--" + cMimeBoundary + cNewLine + | ||||
|                                   "Content-Type: text/plain; charset=~"us-ascii~"" + cNewLine. | ||||
|             IF lBodyIsBase64 THEN DO: | ||||
|                 ASSIGN lcReturnData = lcReturnData + "Content-Transfer-Encoding: base64" + cNewLine + | ||||
|                                       cNewLine + | ||||
|                                       email.Util:ConvertDataToBase64(lcBody) + cNewLine. | ||||
|             END. | ||||
|             ELSE DO: | ||||
|                 ASSIGN lcReturnData = lcReturnData + "Content-Transfer-Encoding: 7bit"   + cNewLine + | ||||
|                                       cNewLine + | ||||
|                                       lcBody + cNewLine. | ||||
|             END. | ||||
|         END. | ||||
|  | ||||
|         /* Write out each email attachment */ | ||||
|         FOR EACH ttAttachments: | ||||
|             ASSIGN lcReturnData = lcReturnData + "--" + cMimeBoundary + cNewLine. | ||||
|             IF ttAttachments.lBase64Encode THEN DO: | ||||
|                 ASSIGN lcReturnData = lcReturnData + "Content-Type: application/octet-stream" + cNewLine + | ||||
|                                       "Content-Disposition: attachment; filename=~"" + ttAttachments.cFileName + "~"" + cNewLine + | ||||
|                                       "Content-Transfer-Encoding: base64" + cNewLine + cNewLine + | ||||
|                                       CAST(ttAttachments.lcData, email.LongcharWrapper):getLongchar() + cNewLine. | ||||
|             END. | ||||
|             ELSE DO: | ||||
|                 ASSIGN lcReturnData = lcReturnData + "Content-Type: text/plain; charset=~"us-ascii~"" + cNewLine + | ||||
|                                       "Content-Disposition: attachment; filename=~"" + ttAttachments.cFileName + "~"" + cNewLine + | ||||
|                                       "Content-Transfer-Encoding: 7bit" + cNewLine + cNewLine + | ||||
|                                       CAST(ttAttachments.lcData, email.LongcharWrapper):getLongchar() + cNewLine. | ||||
|             END. | ||||
|         END. | ||||
|  | ||||
|         /* Write payload footer */ | ||||
|         ASSIGN lcReturnData = lcReturnData + "--" + cMimeBoundary + "--" + cNewLine. | ||||
|  | ||||
|         RETURN lcReturnData. | ||||
|     END METHOD. | ||||
|  | ||||
|     METHOD PUBLIC CHARACTER send(): | ||||
|         RETURN objSendEmailAlgorithm:sendEmail(INPUT THIS-OBJECT). | ||||
|     END METHOD. | ||||
|  | ||||
| END CLASS. | ||||
							
								
								
									
										47
									
								
								test/fixtures/Foo.kt
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								test/fixtures/Foo.kt
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,47 @@ | ||||
| package addressbook | ||||
|  | ||||
| class Contact( | ||||
|   val name : String, | ||||
|   val emails : List<EmailAddress>, | ||||
|   val addresses : List<PostalAddress>, | ||||
|   val phonenums : List<PhoneNumber> | ||||
| ) | ||||
|  | ||||
| class EmailAddress( | ||||
|   val user : String, | ||||
|   val host : String | ||||
| ) | ||||
|  | ||||
| class PostalAddress( | ||||
|   val streetAddress : String, | ||||
|   val city : String, | ||||
|   val zip : String, | ||||
|   val state : USState?, | ||||
|   val country : Country | ||||
| ) { | ||||
|    assert {(state == null) xor (country == Countries["US"]) } | ||||
| } | ||||
|  | ||||
| class PhoneNumber( | ||||
|   val country : Country, | ||||
|   val areaCode : Int, | ||||
|   val number : Long | ||||
| ) | ||||
|  | ||||
| object Countries { | ||||
|   fun get(id : CountryID) : Country = countryTable[id] | ||||
|    | ||||
|   private var table : Map<String, Country>? = null | ||||
|   private val countryTable : Map<String, Country> | ||||
|     get() { | ||||
|       if (table == null) { | ||||
|         table = HashMap() | ||||
|         for (line in TextFile("countries.txt").lines(stripWhiteSpace = true)) { | ||||
|           table[line] = Country(line) | ||||
|         } | ||||
|       } | ||||
|       return table | ||||
|     } | ||||
| } | ||||
|  | ||||
| class Country(val name : String) | ||||
							
								
								
									
										240
									
								
								test/fixtures/cApplication.cls
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										240
									
								
								test/fixtures/cApplication.cls
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,240 @@ | ||||
| VERSION 1.0 CLASS | ||||
| BEGIN | ||||
|   MultiUse = -1  'True | ||||
|   Persistable = 0  'NotPersistable | ||||
|   DataBindingBehavior = 0  'vbNone | ||||
|   DataSourceBehavior  = 0  'vbNone | ||||
|   MTSTransactionMode  = 0  'NotAnMTSObject | ||||
| END | ||||
| Attribute VB_Name = "cApplication" | ||||
| Attribute VB_GlobalNameSpace = False | ||||
| Attribute VB_Creatable = True | ||||
| Attribute VB_PredeclaredId = False | ||||
| Attribute VB_Exposed = False | ||||
| '************************************************************************************************************************************************************************************************************************************************* | ||||
| ' | ||||
| ' Copyright (c) David Briant 2009-2012 - All rights reserved | ||||
| ' | ||||
| '************************************************************************************************************************************************************************************************************************************************* | ||||
|  | ||||
| Option Explicit | ||||
|  | ||||
| Private Declare Function apiSetProp Lib "user32" Alias "SetPropA" (ByVal hwnd As Long, ByVal lpString As String, ByVal hData As Long) As Long | ||||
| Private Declare Function apiGlobalAddAtom Lib "kernel32" Alias "GlobalAddAtomA" (ByVal lpString As String) As Long | ||||
| Private Declare Function apiSetForegroundWindow Lib "user32" Alias "SetForegroundWindow" (ByVal hwnd As Long) As Long | ||||
|  | ||||
| Private myMouseEventsForm As fMouseEventsForm | ||||
| Private WithEvents myAST As cTP_AdvSysTray | ||||
| Attribute myAST.VB_VarHelpID = -1 | ||||
|  | ||||
| Private myClassName As String | ||||
| Private myWindowName As String | ||||
| Private Const TEN_MILLION As Single = 10000000 | ||||
|  | ||||
| Private WithEvents myListener As VLMessaging.VLMMMFileListener | ||||
| Attribute myListener.VB_VarHelpID = -1 | ||||
| Private WithEvents myMMFileTransports As VLMessaging.VLMMMFileTransports | ||||
| Attribute myMMFileTransports.VB_VarHelpID = -1 | ||||
|  | ||||
| Private myMachineID As Long | ||||
|  | ||||
| Private myRouterSeed As Long | ||||
| Private myRouterIDsByMMTransportID As New Dictionary | ||||
| Private myMMTransportIDsByRouterID As New Dictionary | ||||
|  | ||||
| Private myDirectoryEntriesByIDString As New Dictionary | ||||
|  | ||||
| Private Const GET_ROUTER_ID As String = "GET_ROUTER_ID" | ||||
| Private Const GET_ROUTER_ID_REPLY As String = "GET_ROUTER_ID_REPLY" | ||||
| Private Const REGISTER_SERVICE As String = "REGISTER_SERVICE" | ||||
| Private Const REGISTER_SERVICE_REPLY As String = "REGISTER_SERVICE_REPLY" | ||||
| Private Const UNREGISTER_SERVICE As String = "UNREGISTER_SERVICE" | ||||
| Private Const UNREGISTER_SERVICE_REPLY As String = "UNREGISTER_SERVICE_REPLY" | ||||
| Private Const GET_SERVICES As String = "GET_SERVICES" | ||||
| Private Const GET_SERVICES_REPLY As String = "GET_SERVICES_REPLY" | ||||
|  | ||||
|  | ||||
| '************************************************************************************************************************************************************************************************************************************************* | ||||
| ' Initialize / Release | ||||
| '************************************************************************************************************************************************************************************************************************************************* | ||||
|  | ||||
| Private Sub class_Initialize() | ||||
|     Dim atomID As Long | ||||
|     Randomize | ||||
|     ' hide us from the Applications list in the Windows Task Manager | ||||
|     App.TaskVisible = False | ||||
|      | ||||
|     ' listen for connections | ||||
|     myClassName = "VLMMachineRouter" & CStr(Int(Rnd() * TEN_MILLION) + 1) | ||||
|     Randomize | ||||
|     myWindowName = "VLMMachineRouter" & CStr(Int(Rnd() * TEN_MILLION) + 1) | ||||
|     Set myListener = New VLMMMFileListener | ||||
|     myListener.listenViaNamedWindow myClassName, myWindowName, 1024 * 8 | ||||
|     Set myMMFileTransports = New VLMMMFileTransports | ||||
|     myRouterSeed = 1 | ||||
|      | ||||
|     ' create tray icon | ||||
|     Set myMouseEventsForm = New fMouseEventsForm | ||||
|     Set myAST = New cTP_AdvSysTray | ||||
|     myAST.create myMouseEventsForm, myMouseEventsForm.icon, "VLM Directory" | ||||
|     'myAST.showBalloon "Current Shell32.dll version is " & myAST.shellVersion & ".x", "AdvSysTray VB Class", NIIF_INFO | ||||
|      | ||||
|     ' make myself easily found | ||||
|     apiSetProp myMouseEventsForm.hwnd, "IsVLMachineRouter", 1 | ||||
|     apiSetProp myMouseEventsForm.hwnd, "WindowNameAtom", apiGlobalAddAtom(myWindowName) | ||||
|     apiSetProp myMouseEventsForm.hwnd, "ClassNameAtom", apiGlobalAddAtom(myClassName) | ||||
|      | ||||
| End Sub | ||||
|  | ||||
| Sub shutdown() | ||||
|     myAST.destroy | ||||
|     Set myAST = Nothing | ||||
|     Unload myMouseEventsForm | ||||
|     Set myMouseEventsForm = Nothing | ||||
| End Sub | ||||
|  | ||||
| Private Sub myAST_RButtonUp() | ||||
|     Dim epm As New cTP_EasyPopupMenu, menuItemSelected As Long | ||||
|     'SetForegroundWindow myMouseEventsForm.hwnd | ||||
| '    epm.addMenuItem "Main form...", MF_STRING, 1 | ||||
| '    epm.createSubmenu "Radio items" | ||||
| '    epm.addSubmenuItem "Radio item 1", MF_STRING, 2 | ||||
| '    epm.addSubmenuItem "Radio item 2", MF_STRING, 3 | ||||
| '    epm.addSubmenuItem "Radio item 3", MF_STRING, 4 | ||||
| '    epm.checkRadioItem 0, 2, 1 | ||||
| '    epm.addMenuItem "", MF_SEPARATOR, 0 | ||||
| '    epm.addMenuItem "Disabled item", MF_GRAYED, 5 | ||||
| '    epm.addMenuItem "Checked item", MF_CHECKED, 6 | ||||
| '    epm.addMenuItem "", MF_SEPARATOR, 0 | ||||
|     epm.addMenuItem "Exit", MF_STRING, 12 | ||||
|     apiSetForegroundWindow myMouseEventsForm.hwnd | ||||
|     menuItemSelected = epm.trackMenu(myMouseEventsForm.hwnd) | ||||
|     Select Case menuItemSelected | ||||
|         Case 12 | ||||
|             Set epm = Nothing | ||||
|             globalShutdown | ||||
|     End Select | ||||
| End Sub | ||||
|  | ||||
| Private Sub myListener_newConnection(ByVal newTransport As VLMessaging.VLMMMFileTransport, oReceived As Boolean) | ||||
|     Dim id As Long | ||||
|     oReceived = True | ||||
|     id = myMMFileTransports.addTransport(newTransport) | ||||
| End Sub | ||||
|  | ||||
| Private Function messageFromBytes(buffer() As Byte) As VLMMessage | ||||
|     Dim i1 As Long, i2 As Long, messageArray As Variant, message As New VLMMessage | ||||
|     DBGetArrayBounds buffer, 1, i1, i2 | ||||
|     messageArray = g_VLMUtils.BytesAsVariant(buffer, i2 + 1, 1) | ||||
|     message.fromMessageArray messageArray | ||||
|     Set messageFromBytes = message | ||||
| End Function | ||||
|  | ||||
| Private Function messageToBytes(message As VLMMessage) As Byte() | ||||
|     Dim messageArray As Variant, length As Long, buffer() As Byte | ||||
|     message.toMessageArray messageArray | ||||
|     length = g_VLMUtils.LengthOfVariantAsBytes(messageArray) | ||||
|     DBCreateNewArrayOfBytes buffer, 1, length | ||||
|     g_VLMUtils.VariantAsBytes messageArray, buffer, length + 1, 1 | ||||
|     messageToBytes = buffer | ||||
| End Function | ||||
|  | ||||
| Private Sub myMMFileTransports_bytesArrived(ByVal id As Long, buffer() As Byte, oReceived As Boolean) | ||||
|     Dim message As VLMMessage, toAddress As VLMAddress | ||||
|     oReceived = True | ||||
|     Set message = messageFromBytes(buffer) | ||||
|     Set toAddress = message.toAddress | ||||
|     On Error GoTo errorHandler | ||||
|     If (toAddress.MachineID = myMachineID Or toAddress.MachineID = 0) And toAddress.RouterID = 1 And toAddress.AgentID = 1 Then | ||||
|         handleMessageToRouter id, message | ||||
|     Else | ||||
|         routeMessage message | ||||
|     End If | ||||
| Exit Sub | ||||
| errorHandler: | ||||
|     MsgBox Err.Description & ", " & Erl | ||||
| End Sub | ||||
|  | ||||
| Sub handleMessageToRouter(MMFileTransportID As Long, message As VLMMessage) | ||||
|     Dim reply As VLMMessage, transport As VLMMMFileTransport, RouterID As Long, address As New VLMAddress | ||||
|     Dim IDString As String, vs As Variant, i As Long, entries As New Collection, answer1D As Variant | ||||
|      | ||||
|     Select Case True | ||||
|      | ||||
|         Case message.subject = GET_ROUTER_ID | ||||
|             If myRouterIDsByMMTransportID.Exists(MMFileTransportID) Then | ||||
|                 RouterID = myRouterIDsByMMTransportID(MMFileTransportID) | ||||
|             Else | ||||
|                 myRouterSeed = myRouterSeed + 1 | ||||
|                 RouterID = myRouterSeed | ||||
|                 myRouterIDsByMMTransportID(MMFileTransportID) = RouterID | ||||
|                 myMMTransportIDsByRouterID(RouterID) = MMFileTransportID | ||||
|             End If | ||||
|             Set reply = message.reply | ||||
|             reply.subject = GET_ROUTER_ID_REPLY | ||||
|             reply.Contents = RouterID | ||||
|             Set transport = myMMFileTransports.transport(MMFileTransportID) | ||||
|             transport.send messageToBytes(reply) | ||||
|              | ||||
|         Case message.subject = REGISTER_SERVICE | ||||
|             address.initialise CLng(message.Contents(1)(1)), CLng(message.Contents(1)(2)), CLng(message.Contents(1)(3)) | ||||
|             myDirectoryEntriesByIDString(directoryEntryIDString(CStr(message.Contents(2)), address)) = message.Contents | ||||
|             Set reply = message.reply | ||||
|             reply.subject = REGISTER_SERVICE_REPLY | ||||
|             Set transport = myMMFileTransports.transport(MMFileTransportID) | ||||
|             transport.send messageToBytes(reply) | ||||
|          | ||||
|         Case message.subject = UNREGISTER_SERVICE | ||||
|             address.initialise CLng(message.Contents(1)(1)), CLng(message.Contents(1)(2)), CLng(message.Contents(1)(3)) | ||||
|             IDString = directoryEntryIDString(CStr(message.Contents(2)), address) | ||||
|             If myDirectoryEntriesByIDString.Exists(IDString) Then myDirectoryEntriesByIDString.Remove IDString | ||||
|             Set reply = message.reply | ||||
|             reply.subject = UNREGISTER_SERVICE_REPLY | ||||
|             Set transport = myMMFileTransports.transport(MMFileTransportID) | ||||
|             transport.send messageToBytes(reply) | ||||
|          | ||||
|         Case message.subject = GET_SERVICES | ||||
|             vs = myDirectoryEntriesByIDString.Items | ||||
|             For i = 0 To UBound(vs) | ||||
|                 If IsEmpty(message.Contents) Then | ||||
|                     entries.Add vs(i) | ||||
|                 Else | ||||
|                     If vs(i)(2) = message.Contents Then entries.Add vs(i) | ||||
|                 End If | ||||
|             Next | ||||
|             If entries.Count > 0 Then | ||||
|                 ReDim answer1D(1 To entries.Count) | ||||
|                 For i = 1 To entries.Count | ||||
|                     answer1D(i) = entries(i) | ||||
|                 Next | ||||
|             End If | ||||
|             Set reply = message.reply | ||||
|             reply.subject = GET_SERVICES_REPLY | ||||
|             reply.Contents = answer1D | ||||
|             Set transport = myMMFileTransports.transport(MMFileTransportID) | ||||
|             transport.send messageToBytes(reply) | ||||
|              | ||||
|     End Select | ||||
|  | ||||
| End Sub | ||||
|  | ||||
| Sub routeMessage(message As VLMMessage) | ||||
|     Dim buffer() As Byte, transport As VLMMMFileTransport | ||||
|     If message.toAddress.MachineID <> 0 And message.toAddress.MachineID <> myMachineID Then | ||||
|         ' route to a remote machine | ||||
|     Else | ||||
|         ' for the moment just route between MMFileTransports | ||||
|         If myMMTransportIDsByRouterID.Exists(message.toAddress.RouterID) Then | ||||
|             Set transport = myMMFileTransports(myMMTransportIDsByRouterID(message.toAddress.RouterID)) | ||||
|             transport.send messageToBytes(message) | ||||
|         End If | ||||
|     End If | ||||
| End Sub | ||||
|  | ||||
| Function directoryEntryIDString(serviceType As String, address As VLMAddress) | ||||
|     directoryEntryIDString = serviceType & "<" & address.MachineID & "," & address.RouterID & "," & address.AgentID & ">" | ||||
| End Function | ||||
|  | ||||
| Private Sub myMMFileTransports_disconnecting(ByVal id As Long, oReceived As Boolean) | ||||
|     oReceived = True | ||||
| End Sub | ||||
							
								
								
									
										1
									
								
								test/fixtures/foo.tea
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								test/fixtures/foo.tea
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| <% template foo() %> | ||||
							
								
								
									
										14
									
								
								test/fixtures/foo.vhd
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								test/fixtures/foo.vhd
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,14 @@ | ||||
| -- VHDL example file | ||||
|  | ||||
| library ieee; | ||||
| use ieee.std_logic_1164.all; | ||||
|  | ||||
| entity inverter is | ||||
| 	port(a : in std_logic; | ||||
| 	     b : out std_logic); | ||||
| end entity; | ||||
|  | ||||
| architecture rtl of inverter is | ||||
| begin | ||||
| 	b <= not a; | ||||
| end architecture; | ||||
							
								
								
									
										8
									
								
								test/fixtures/latex.cls
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										8
									
								
								test/fixtures/latex.cls
									
									
									
									
										vendored
									
									
								
							| @@ -1,8 +0,0 @@ | ||||
| % latex.cls | ||||
| % | ||||
| % A barebones LaTeX2e class file | ||||
|  | ||||
| \def\author{Abe Voelker} | ||||
| \def\fileversion{0.1} | ||||
| \NeedsTeXFormat{LaTeX2e} | ||||
|  | ||||
							
								
								
									
										10
									
								
								test/fixtures/openedge.cls
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										10
									
								
								test/fixtures/openedge.cls
									
									
									
									
										vendored
									
									
								
							| @@ -1,10 +0,0 @@ | ||||
| USING Progress.Lang.*. | ||||
|  | ||||
| CLASS HelloWorld: | ||||
|  | ||||
|   CONSTRUCTOR PUBLIC HelloWorld(): | ||||
|     SUPER(). | ||||
|     MESSAGE "Hello, world!". | ||||
|   END CONSTRUCTOR. | ||||
|  | ||||
| END CLASS. | ||||
							
								
								
									
										245
									
								
								test/fixtures/reedthesis.cls
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										245
									
								
								test/fixtures/reedthesis.cls
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,245 @@ | ||||
| % | ||||
| % This file is copyright (C) 2003 Sam Noble. It may be modified so long | ||||
| % as my name is not removed and the modifier adds his name to the file. | ||||
| % Redistribution permitted. | ||||
| % | ||||
| % 27 Jan 2004	Sam Noble	Removed tocbibind dependency. | ||||
| % 04 Dec 2001 	Sam Noble	Class file | ||||
| % 03 Sep 1995	David Perkinson	Title Page | ||||
| % Acknowledgements Page, David Perkinson & Sam Noble | ||||
| % May 2005 Patrick Carlisle Table of contents chapter definition | ||||
| % 2004-2005 Ben Salzberg (BTS) a variety of tweaks here and in the template | ||||
| % | ||||
| % Oddities: | ||||
| % | ||||
| %   We *ASSUME* that any time \cleardoublepage is called | ||||
| %  we actually want a blank back side with NO page number/heading | ||||
| % | ||||
| %   Minor bug -- seems to be a more general LaTeX thing: | ||||
| %  If you use \frontmatter \mainmatter without any chapters inbetween | ||||
| %  be prepared to have the page numbering messed up. Not a big deal, | ||||
| %  but I'm not sure how to fix it. | ||||
| % | ||||
| % | ||||
|  | ||||
| \NeedsTeXFormat{LaTeX2e} | ||||
| \ProvidesClass{reedthesis}[2004/01/27 The Reed College Thesis Class] | ||||
| \DeclareOption*{\PassOptionsToClass{\CurrentOption}{book}} | ||||
| \ProcessOptions\relax | ||||
| \LoadClass{book} | ||||
| \RequirePackage{fancyhdr} | ||||
|  | ||||
| % This gives us rules below the headers | ||||
| \AtBeginDocument{% | ||||
|   \fancyhf{} | ||||
|   \fancyhead[LE,RO]{\thepage} | ||||
| %  \fancyhead[RE]{\slshape \leftmark} | ||||
| %  \fancyhead[LO]{\slshape \rightmark} | ||||
| %	The above makes your headers in all caps. If you would like different headers, choose one of the following options (be sure to remove the % symbol from both the right and left headers): | ||||
| 	 \fancyhead[RE]{\slshape \nouppercase \leftmark} % This makes the headers on the RIGHT side pages be italic and use lowercase With Capitals When Specified. | ||||
| 	\fancyhead[LO]{\slshape \nouppercase \rightmark} % This does the same thing to the LEFT side pages | ||||
| %	or | ||||
| %	\fancyhead[RE]{\scshape \leftmark} % The RIGHT headers will be in small caps. | ||||
| %	\fancyhead[LO]{\scshape \rightmark} %  And so will the LEFT headers | ||||
|   \pagestyle{fancy} | ||||
|  | ||||
| % Psych majors: You do not need the following six lines, as it conflicts with apacite, so comment them out. | ||||
|   \let\oldthebibliography=\thebibliography | ||||
|   \let\endoldthebibliography=\endthebibliography | ||||
|   \renewenvironment{thebibliography}[1]{ | ||||
|     \oldthebibliography{#1} | ||||
|     \addcontentsline{toc}{chapter}{\bibname} | ||||
|   }{\endoldthebibliography} | ||||
|  %%%%%% end of things for psych majors to comment out | ||||
|    | ||||
|   \let\oldtheindex=\theindex | ||||
|   \let\endoldtheindex=\endtheindex | ||||
|   \renewenvironment{theindex}{ | ||||
|     \oldtheindex | ||||
|     \addcontentsline{toc}{chapter}{\indexname} | ||||
|   }{\endoldtheindex} | ||||
| } | ||||
|  | ||||
| % Stolen from book.cls and modified | ||||
| \let\RToldchapter\chapter | ||||
| \renewcommand{\chapter}{\if@openright\RTcleardoublepage | ||||
| 		    \else\clearpage\fi | ||||
| 		    \thispagestyle{empty}% | ||||
| 		    \global\@topnum\z@ | ||||
| 		    \@afterindentfalse | ||||
| 		    \secdef\@chapter\@schapter} | ||||
| 		     | ||||
| % Stolen from book.cls PBC 5/12/05 | ||||
| % Using this to actually show "Chapter 1" in TOC instead of "1" | ||||
| \def\@chapter[#1]#2{\ifnum \c@secnumdepth >\m@ne | ||||
|                        \if@mainmatter | ||||
|                          \refstepcounter{chapter}% | ||||
|                          \typeout{\@chapapp\space\thechapter.}% | ||||
|                          \addcontentsline{toc}{chapter}% | ||||
|                          {\@chapapp\space\thechapter:\space#1}% | ||||
|                        \else | ||||
|                          \addcontentsline{toc}{chapter}{#1}% | ||||
|                        \fi | ||||
|                     \else | ||||
|                       \addcontentsline{toc}{chapter}{#1}% | ||||
|                     \fi | ||||
|                     \chaptermark{#1}% | ||||
|                     \addtocontents{lof}{\protect\addvspace{10\p@}}% | ||||
|                     \addtocontents{lot}{\protect\addvspace{10\p@}}% | ||||
|                     \if@twocolumn | ||||
|                       \@topnewpage[\@makechapterhead{#2}]% | ||||
|                     \else | ||||
|                       \@makechapterhead{#2}% | ||||
|                       \@afterheading | ||||
|                     \fi} | ||||
|  | ||||
| \newcommand{\RTcleardoublepage}{ | ||||
| 	\clearpage\if@twoside \ifodd\c@page\else | ||||
| 	\thispagestyle{empty}\hbox{}\newpage | ||||
| 	\if@twocolumn\hbox{}\newpage\fi\fi\fi} | ||||
|  | ||||
| \let\RToldcleardoublepage\cleardoublepage | ||||
| \renewcommand{\cleardoublepage}{\RTcleardoublepage} | ||||
|  | ||||
| % adjust margins for binding  (changed 2007-04-24 tgp) | ||||
| \setlength{\oddsidemargin}{.5in} | ||||
| \setlength{\evensidemargin}{0in} | ||||
| \setlength{\textwidth}{6.0in} | ||||
| \setlength{\textheight}{9.0in} | ||||
| \setlength\topmargin{0in} | ||||
| \addtolength\topmargin{-\headheight} | ||||
| \addtolength\topmargin{-\headsep} | ||||
|  | ||||
| %\setlength{\oddsidemargin}{.6in} | ||||
| %\setlength{\evensidemargin}{0in} | ||||
| %\setlength{\textwidth}{5.9in} | ||||
| %\setlength\topmargin{0in} | ||||
| %\addtolength\headheight{2.5pt} | ||||
| %\addtolength\topmargin{-\headheight} | ||||
| %\addtolength\topmargin{-\headsep} | ||||
| %\addtolength\textheight{1in} | ||||
| %\addtolength\textheight{\headheight} | ||||
| %\addtolength\textheight{\headsep} | ||||
|  | ||||
| \def\division#1{\gdef \@division{#1}} | ||||
| \def\@division{\@latex@warning@no@line{No \noexpand\division given}} | ||||
| \def\department#1{\gdef \@department{#1}} | ||||
| \def\@department{\@latex@warning@no@line{No \noexpand\department given}} | ||||
| \def\thedivisionof#1{\gdef \@thedivisionof{#1}} | ||||
| \def\@thedivisionof{The Division of} | ||||
| \def\approvedforthe#1{\gdef \@approvedforthe{#1}} | ||||
| \def\@approvedforthe{Division} | ||||
| \def\advisor#1{\gdef \@advisor{#1}} | ||||
| \def\@advisor{\@latex@warning@no@line{No \noexpand\advisor given}} | ||||
| \def\altadvisor#1{\gdef \@altadvisor{#1} \@altadvisortrue} | ||||
| \global\let\@altadvisor\@empty | ||||
| \newif\if@altadvisor | ||||
| \@altadvisorfalse | ||||
|  | ||||
| \renewcommand{\contentsname}{Table of Contents} | ||||
| \renewcommand{\bibname}{References} | ||||
|  | ||||
| \renewcommand\l@chapter[2]{% | ||||
|   \ifnum \c@tocdepth >\m@ne | ||||
|     \addpenalty{-\@highpenalty}% | ||||
|     \vskip 1.0em \@plus\p@ | ||||
|     \setlength\@tempdima{1.5em}% | ||||
|     \begingroup | ||||
|       \parindent \z@ \rightskip \@pnumwidth | ||||
|       \parfillskip -\@pnumwidth | ||||
|       \leavevmode \bfseries | ||||
|       \advance\leftskip\@tempdima | ||||
|       \hskip -\leftskip | ||||
|       #1\nobreak\normalfont | ||||
|       \leaders\hbox{$\m@th \mkern \@dotsep mu\hbox{.}\mkern \@dotsep mu$}\hfill | ||||
|       \nobreak\hb@xt@\@pnumwidth{\bfseries \hss #2}\par | ||||
|       \penalty\@highpenalty | ||||
|     \endgroup | ||||
|   \fi} | ||||
|  | ||||
| \newenvironment{abstract}{% | ||||
|   \if@twocolumn | ||||
|     \@restonecoltrue\onecolumn | ||||
|   \else | ||||
|     \@restonecolfalse | ||||
|   \fi | ||||
|   \chapter[Abstract]{} | ||||
|   \begin{center} | ||||
|   {\fontsize{14}{16}\selectfont \bfseries Abstract} | ||||
|   \end{center} | ||||
|   \fontsize{12}{14}\selectfont | ||||
| }{\clearpage \if@restonecol\twocolumn\fi}% | ||||
|  | ||||
| \ifx\@pdfoutput\@undefined | ||||
|   \newcommand{\RTpercent}{\@percentchar\space} | ||||
|   \AtBeginDvi{\special{!\RTpercent Reed College LaTeX Thesis Class 2001/12/04 SN}}  | ||||
|   \AtBeginDvi{\special{rawpostscript \RTpercent Reed College LaTeX Thesis Class 2001/12/04 SN}}  | ||||
| \else | ||||
|   \AtEndDocument{\pdfinfo{/Creator	(Reed College LaTeX Thesis Class 2001/12/04 SN)}}  | ||||
| \fi | ||||
|  | ||||
| % I hacked the title page to all be the same font size  | ||||
| % as requested by the library, BTS 2005 | ||||
|  | ||||
| \renewcommand{\maketitle}{% | ||||
|   {\pagestyle{empty} | ||||
|   \fontsize{12}{14}\selectfont | ||||
|   \begin{titlepage} | ||||
|   \newpage | ||||
|   \let\footnotesize\small | ||||
|   \let\footnoterule\relax | ||||
|   \let \footnote \thanks | ||||
|  | ||||
|   \baselineskip = 1.4\baselineskip | ||||
|   \setbox0=\hbox{of the Requirements for the Degree} | ||||
|  | ||||
|   \begin{center} | ||||
|     \setcounter{page}{1} | ||||
|     \null\vfil | ||||
|     {\fontsize{12}{14}\selectfont \@title} | ||||
|     \vfil | ||||
|     \centerline{\hbox to \wd0 {\hbox{}\hrulefill\hbox{}}} | ||||
|     \vfil | ||||
|     A Thesis \\ | ||||
|     Presented to \\ | ||||
|     \@thedivisionof \ \@division \\ | ||||
|     Reed College | ||||
|     \vfil | ||||
|     \centerline{\hbox to \wd0 {\hbox{}\hrulefill\hbox{}}} | ||||
|     \vfil | ||||
|     In Partial Fulfillment \\ | ||||
|     of the Requirements for the Degree \\ | ||||
|     Bachelor of Arts | ||||
|     \vfil | ||||
|     \centerline{\hbox to \wd0 {\hbox{}\hrulefill\hbox{}}} | ||||
|     \bigskip | ||||
|     \centerline{} | ||||
|     \bigskip | ||||
|     {\fontsize{12}{14}\selectfont \lineskip .75em | ||||
|     \begin{tabular}[t]{c}% | ||||
|       \@author | ||||
|     \end{tabular}\par} | ||||
|     \vskip 1.5em | ||||
|     {\fontsize{12}{14}\selectfont \@date \par} | ||||
|   \end{center}\par | ||||
|   \end{titlepage} | ||||
|  | ||||
| %% Approved for the division page | ||||
|   \cleardoublepage | ||||
|   {\fontsize{12}{14} | ||||
|   \setbox0=\hbox{Approved for the \@approvedforthe} | ||||
|   \thispagestyle{empty} | ||||
|   \null\vfil		% just below center of page | ||||
|   \par\vskip 6cm	% below center, not center | ||||
|   \centerline{\copy0}	% approved | ||||
|   \centerline{(\@department)} %major | ||||
|   \vskip 1cm		%space to sign | ||||
|   \centerline{\makebox[\wd0][c]{\hrulefill} | ||||
| 	\if@altadvisor \makebox[.5in]{} \makebox[\wd0][c]{\hrulefill} \fi} | ||||
|   \centerline{\makebox[\wd0][c]{\@advisor} | ||||
| 	\if@altadvisor \makebox[.5in]{} \makebox[\wd0][c]{\@altadvisor} \fi} | ||||
|   \par\vfil\null} | ||||
|   \cleardoublepage | ||||
|   } | ||||
| } | ||||
|  | ||||
| @@ -33,6 +33,7 @@ class TestBlob < Test::Unit::TestCase | ||||
|  | ||||
|   def test_mime_type | ||||
|     assert_equal "application/octet-stream", blob("dog.o").mime_type | ||||
|     assert_equal "application/ogg", blob("foo.ogg").mime_type | ||||
|     assert_equal "application/postscript", blob("octocat.ai").mime_type | ||||
|     assert_equal "application/x-ruby", blob("grit.rb").mime_type | ||||
|     assert_equal "application/x-sh", blob("script.sh").mime_type | ||||
| @@ -42,6 +43,7 @@ class TestBlob < Test::Unit::TestCase | ||||
|  | ||||
|   def test_content_type | ||||
|     assert_equal "application/octet-stream", blob("dog.o").content_type | ||||
|     assert_equal "application/ogg", blob("foo.ogg").content_type | ||||
|     assert_equal "application/pdf", blob("foo.pdf").content_type | ||||
|     assert_equal "image/png", blob("foo.png").content_type | ||||
|     assert_equal "text/plain; charset=iso-8859-2", blob("README").content_type | ||||
| @@ -260,7 +262,7 @@ class TestBlob < Test::Unit::TestCase | ||||
|   def test_indexable | ||||
|     assert blob("file.txt").indexable? | ||||
|     assert blob("foo.rb").indexable? | ||||
|     assert !blob("defun.kt").indexable? | ||||
|     assert !blob("defu.nkt").indexable? | ||||
|     assert !blob("dump.sql").indexable? | ||||
|     assert !blob("github.po").indexable? | ||||
|     assert !blob("linguist.gem").indexable? | ||||
| @@ -285,11 +287,18 @@ class TestBlob < Test::Unit::TestCase | ||||
|     assert_equal Language['Ruby'],        blob("script.rb").language | ||||
|     assert_equal Language['Ruby'],        blob("wrong_shebang.rb").language | ||||
|     assert_equal Language['Arduino'],     blob("hello.ino").language | ||||
|     assert_equal Language['VHDL'],        blob("foo.vhd").language | ||||
|     assert_nil blob("octocat.png").language | ||||
|  | ||||
|     # .cls disambiguation | ||||
|     assert_equal Language['OpenEdge ABL'], blob("openedge.cls").language | ||||
|     assert_equal Language['TeX'], blob("latex.cls").language | ||||
|     # https://github.com/abevoelker/abl-email-client/blob/master/com/abevoelker/email/Email.cls | ||||
|     assert_equal Language['OpenEdge ABL'], blob("Email.cls").language | ||||
|     # https://github.com/emcmanis/Thesis/blob/master/TeX/Thesis%20Template/reedthesis.cls | ||||
|     assert_equal Language['TeX'], blob("reedthesis.cls").language | ||||
|     # https://github.com/DangerMouseB/VLMessaging/blob/master/VLMMachineRouter/cApplication.cls | ||||
|     assert_equal Language['Visual Basic'], blob("cApplication.cls").language | ||||
|     # https://github.com/apex-commons/base/blob/master/src/classes/ArrayUtils.cls | ||||
|     assert_equal Language['Apex'], blob("ArrayUtils.cls").language | ||||
|  | ||||
|     # .pl disambiguation | ||||
|     assert_equal Language['Prolog'],      blob("test-prolog.pl").language | ||||
| @@ -412,6 +421,12 @@ class TestBlob < Test::Unit::TestCase | ||||
|  | ||||
|     # OpenEdge ABL / Progress | ||||
|     assert_equal Language['OpenEdge ABL'], blob("openedge.p").language | ||||
|  | ||||
|     # Tea | ||||
|     assert_equal Language['Tea'], blob("foo.tea").language | ||||
|  | ||||
|     # Kotlin | ||||
|     assert_equal Language['Kotlin'], blob("Foo.kt").language | ||||
|   end | ||||
|  | ||||
|   def test_lexer | ||||
| @@ -421,6 +436,8 @@ class TestBlob < Test::Unit::TestCase | ||||
|     assert_equal Lexer['Ruby'], blob("grit.rb").lexer | ||||
|     assert_equal Lexer['Scheme'], blob("dude.el").lexer | ||||
|     assert_equal Lexer['Text only'], blob("README").lexer | ||||
|     assert_equal Lexer['Tea'], blob("foo.tea").lexer | ||||
|     assert_equal Lexer['vhdl'], blob("foo.vhd").lexer | ||||
|   end | ||||
|  | ||||
|   def test_shebang_script | ||||
|   | ||||
| @@ -10,7 +10,7 @@ class TestLanguage < Test::Unit::TestCase | ||||
|  | ||||
|   def test_ambiguous_extensions | ||||
|     assert Language.ambiguous?('.cls') | ||||
|     assert_equal Language['OpenEdge ABL'], Language.find_by_extension('cls') | ||||
|     assert_equal Language['TeX'], Language.find_by_extension('cls') | ||||
|  | ||||
|     assert Language.ambiguous?('.h') | ||||
|     assert_equal Language['C'], Language.find_by_extension('h') | ||||
| @@ -41,24 +41,24 @@ class TestLanguage < Test::Unit::TestCase | ||||
|     assert_equal Lexer['C++'], Language['C++'].lexer | ||||
|     assert_equal Lexer['Coldfusion HTML'], Language['ColdFusion'].lexer | ||||
|     assert_equal Lexer['Coq'], Language['Coq'].lexer | ||||
|     assert_equal Lexer['FSharp'], Language['F#'].lexer | ||||
|     assert_equal Lexer['FSharp'], Language['F#'].lexer | ||||
|     assert_equal Lexer['Fortran'], Language['FORTRAN'].lexer | ||||
|     assert_equal Lexer['Gherkin'], Language['Cucumber'].lexer | ||||
|     assert_equal Lexer['Groovy'], Language['Groovy'].lexer | ||||
|     assert_equal Lexer['HTML'], Language['HTML'].lexer | ||||
|     assert_equal Lexer['HTML+Django/Jinja'], Language['HTML+Django'].lexer | ||||
|     assert_equal Lexer['HTML+PHP'], Language['HTML+PHP'].lexer | ||||
|     assert_equal Lexer['JSON'], Language['JSON'].lexer | ||||
|     assert_equal Lexer['Java'], Language['ChucK'].lexer | ||||
|     assert_equal Lexer['Java'], Language['Groovy'].lexer | ||||
|     assert_equal Lexer['Java'], Language['Java'].lexer | ||||
|     assert_equal Lexer['JavaScript'], Language['JSON'].lexer | ||||
|     assert_equal Lexer['JavaScript'], Language['JavaScript'].lexer | ||||
|     assert_equal Lexer['MOOCode'], Language['Moocode'].lexer | ||||
|     assert_equal Lexer['MuPAD'], Language['mupad'].lexer | ||||
|     assert_equal Lexer['NASM'], Language['Assembly'].lexer | ||||
|     assert_equal Lexer['OCaml'], Language['F#'].lexer | ||||
|     assert_equal Lexer['OCaml'], Language['OCaml'].lexer | ||||
|     assert_equal Lexer['OpenEdge ABL'], Language['OpenEdge ABL'].lexer | ||||
|     assert_equal Lexer['Standard ML'], Language['Standard ML'].lexer | ||||
|     assert_equal Lexer['Ooc'], Language['ooc'].lexer | ||||
|     assert_equal Lexer['OpenEdge ABL'], Language['OpenEdge ABL'].lexer | ||||
|     assert_equal Lexer['REBOL'], Language['Rebol'].lexer | ||||
|     assert_equal Lexer['RHTML'], Language['HTML+ERB'].lexer | ||||
|     assert_equal Lexer['RHTML'], Language['RHTML'].lexer | ||||
| @@ -69,6 +69,7 @@ class TestLanguage < Test::Unit::TestCase | ||||
|     assert_equal Lexer['Scheme'], Language['Nu'].lexer | ||||
|     assert_equal Lexer['Scheme'], Language['Racket'].lexer | ||||
|     assert_equal Lexer['Scheme'], Language['Scheme'].lexer | ||||
|     assert_equal Lexer['Standard ML'], Language['Standard ML'].lexer | ||||
|     assert_equal Lexer['TeX'], Language['TeX'].lexer | ||||
|     assert_equal Lexer['Text only'], Language['Text'].lexer | ||||
|     assert_equal Lexer['Verilog'], Language['Verilog'].lexer | ||||
| @@ -112,7 +113,7 @@ class TestLanguage < Test::Unit::TestCase | ||||
|     assert_equal Language['OpenEdge ABL'], Language.find_by_alias('progress') | ||||
|     assert_equal Language['OpenEdge ABL'], Language.find_by_alias('abl') | ||||
|     assert_equal Language['Parrot Internal Representation'], Language.find_by_alias('pir') | ||||
|     assert_equal Language['Powershell'], Language.find_by_alias('posh') | ||||
|     assert_equal Language['PowerShell'], Language.find_by_alias('posh') | ||||
|     assert_equal Language['Puppet'], Language.find_by_alias('puppet') | ||||
|     assert_equal Language['Pure Data'], Language.find_by_alias('pure-data') | ||||
|     assert_equal Language['Raw token data'], Language.find_by_alias('raw') | ||||
| @@ -196,7 +197,7 @@ class TestLanguage < Test::Unit::TestCase | ||||
|   def test_programming | ||||
|     assert_equal :programming, Language['JavaScript'].type | ||||
|     assert_equal :programming, Language['Perl'].type | ||||
|     assert_equal :programming, Language['Powershell'].type | ||||
|     assert_equal :programming, Language['PowerShell'].type | ||||
|     assert_equal :programming, Language['Python'].type | ||||
|     assert_equal :programming, Language['Ruby'].type | ||||
|   end | ||||
| @@ -249,9 +250,9 @@ class TestLanguage < Test::Unit::TestCase | ||||
|     assert_equal Language['PHP'], Language.find_by_extension('php3') | ||||
|     assert_equal Language['PHP'], Language.find_by_extension('php4') | ||||
|     assert_equal Language['PHP'], Language.find_by_extension('php5') | ||||
|     assert_equal Language['Powershell'], Language.find_by_extension('psm1') | ||||
|     assert_equal Language['Powershell'], Language.find_by_extension('ps1') | ||||
|     assert_nil Language.find_by_extension('.kt') | ||||
|     assert_equal Language['PowerShell'], Language.find_by_extension('psm1') | ||||
|     assert_equal Language['PowerShell'], Language.find_by_extension('ps1') | ||||
|     assert_nil Language.find_by_extension('.nkt') | ||||
|   end | ||||
|  | ||||
|   def test_find_all_by_extension | ||||
| @@ -270,7 +271,7 @@ class TestLanguage < Test::Unit::TestCase | ||||
|     assert_equal Language['Ruby'], Language.find_by_filename('Rakefile') | ||||
|     assert_nil Language.find_by_filename('rb') | ||||
|     assert_nil Language.find_by_filename('.rb') | ||||
|     assert_nil Language.find_by_filename('.kt') | ||||
|     assert_nil Language.find_by_filename('.nkt') | ||||
|   end | ||||
|  | ||||
|   def test_find | ||||
| @@ -291,12 +292,36 @@ class TestLanguage < Test::Unit::TestCase | ||||
|     assert_equal 'Ruby',   Language['Ruby'].name | ||||
|   end | ||||
|  | ||||
|   def test_escaped_name | ||||
|     assert_equal 'C', Language['C'].escaped_name | ||||
|     assert_equal 'C%23', Language['C#'].escaped_name | ||||
|     assert_equal 'C%2B%2B', Language['C++'].escaped_name | ||||
|     assert_equal 'Objective-C', Language['Objective-C'].escaped_name | ||||
|     assert_equal 'Common%20Lisp', Language['Common Lisp'].escaped_name | ||||
|     assert_equal 'Max%2FMSP', Language['Max/MSP'].escaped_name | ||||
|   end | ||||
|  | ||||
|   def test_error_without_name | ||||
|     assert_raise ArgumentError do | ||||
|       Language.new :name => nil | ||||
|     end | ||||
|   end | ||||
|  | ||||
|   def test_ace_mode | ||||
|     assert_equal 'c_cpp', Language['C++'].ace_mode | ||||
|     assert_equal 'coffee', Language['CoffeeScript'].ace_mode | ||||
|     assert_equal 'csharp', Language['C#'].ace_mode | ||||
|     assert_equal 'css', Language['CSS'].ace_mode | ||||
|     assert_equal 'javascript', Language['JavaScript'].ace_mode | ||||
|     assert_equal 'text', Language['Text'].ace_mode | ||||
|   end | ||||
|  | ||||
|   def test_ace_modes | ||||
|     assert Language.ace_modes.include?(Language['Text']) | ||||
|     assert Language.ace_modes.include?(Language['Ruby']) | ||||
|     assert !Language.ace_modes.include?(Language['FORTRAN']) | ||||
|   end | ||||
|  | ||||
|   def test_extensions | ||||
|     assert Language['Perl'].extensions.include?('.pl') | ||||
|     assert Language['Python'].extensions.include?('.py') | ||||
|   | ||||
| @@ -14,6 +14,20 @@ class TestMime < Test::Unit::TestCase | ||||
|     # in mimes.yml. Its still useful to test even trivial cases since | ||||
|     # MIME::Type's extension lookup may return multiple matches and we | ||||
|     # only pick one of them. Please keep this list alphabetized. | ||||
|     assert_equal 'application/javascript', Mime.mime_for('.js') | ||||
|     assert_equal 'application/octet-stream', Mime.mime_for('.dll') | ||||
|     assert_equal 'application/octet-stream', Mime.mime_for('.dmg') | ||||
|     assert_equal 'application/octet-stream', Mime.mime_for('.exe') | ||||
|     assert_equal 'application/ogg', Mime.mime_for('.ogg') | ||||
|     assert_equal 'application/postscript', Mime.mime_for('.ai') | ||||
|     assert_equal 'application/postscript', Mime.mime_for('.eps') | ||||
|     assert_equal 'application/postscript', Mime.mime_for('.ps') | ||||
|     assert_equal 'application/vnd.adobe.air-application-installer-package+zip', Mime.mime_for('.air') | ||||
|     assert_equal 'application/vnd.oasis.opendocument.presentation', Mime.mime_for('.odp') | ||||
|     assert_equal 'application/vnd.oasis.opendocument.spreadsheet', Mime.mime_for('.ods') | ||||
|     assert_equal 'application/vnd.oasis.opendocument.text', Mime.mime_for('.odt') | ||||
|     assert_equal 'application/vnd.openofficeorg.extension', Mime.mime_for('.oxt') | ||||
|     assert_equal 'application/vnd.openxmlformats-officedocument.presentationml.presentation', Mime.mime_for('.pptx') | ||||
|     assert_equal 'application/x-chrome-extension', Mime.mime_for('.crx') | ||||
|     assert_equal 'application/x-debian-package', Mime.mime_for('.deb') | ||||
|     assert_equal 'application/x-iwork-keynote-sffkey', Mime.mime_for('.key') | ||||
| @@ -22,37 +36,19 @@ class TestMime < Test::Unit::TestCase | ||||
|     assert_equal 'application/x-java-archive', Mime.mime_for('.ear') | ||||
|     assert_equal 'application/x-java-archive', Mime.mime_for('.jar') | ||||
|     assert_equal 'application/x-java-archive', Mime.mime_for('.war') | ||||
|     assert_equal 'application/javascript', Mime.mime_for('.js') | ||||
|     assert_equal 'application/x-latex', Mime.mime_for('.latex') | ||||
|     assert_equal 'application/x-ms-xbap', Mime.mime_for('.xbap') | ||||
|     assert_equal 'application/octet-stream', Mime.mime_for('.dll') | ||||
|     assert_equal 'application/octet-stream', Mime.mime_for('.dmg') | ||||
|     assert_equal 'application/octet-stream', Mime.mime_for('.exe') | ||||
|     assert_equal 'application/x-perl', Mime.mime_for('.pl') | ||||
|     assert_equal 'application/x-perl', Mime.mime_for('.pm') | ||||
|     assert_equal 'application/postscript', Mime.mime_for('.ai') | ||||
|     assert_equal 'application/postscript', Mime.mime_for('.eps') | ||||
|     assert_equal 'application/postscript', Mime.mime_for('.ps') | ||||
|     assert_equal 'application/x-python', Mime.mime_for('.py') | ||||
|     assert_equal 'application/x-ruby', Mime.mime_for('.rb') | ||||
|     assert_equal 'application/x-sh', Mime.mime_for('.sh') | ||||
|     assert_equal 'application/x-shockwave-flash', Mime.mime_for('.swf') | ||||
|     assert_equal 'application/x-silverlight-app', Mime.mime_for('.xap') | ||||
|     assert_equal 'application/x-supercollider', Mime.mime_for('.sc') | ||||
|     assert_equal 'application/vnd.adobe.air-application-installer-package+zip', Mime.mime_for('.air') | ||||
|     assert_equal 'application/vnd.oasis.opendocument.presentation', Mime.mime_for('.odp') | ||||
|     assert_equal 'application/vnd.oasis.opendocument.spreadsheet', Mime.mime_for('.ods') | ||||
|     assert_equal 'application/vnd.oasis.opendocument.text', Mime.mime_for('.odt') | ||||
|     assert_equal 'application/vnd.openofficeorg.extension', Mime.mime_for('.oxt') | ||||
|     assert_equal 'application/vnd.openxmlformats-officedocument.presentationml.presentation', Mime.mime_for('.pptx') | ||||
|     assert_equal 'application/xaml+xml', Mime.mime_for('.xaml') | ||||
|     assert_equal 'text/cache-manifest', Mime.mime_for('.manifest') | ||||
|     assert_equal 'text/html', Mime.mime_for('.html') | ||||
|     assert_equal 'text/x-nemerle', Mime.mime_for('.n') | ||||
|     assert_equal 'text/x-nimrod', Mime.mime_for('.nim') | ||||
|     assert_equal 'text/x-ocaml', Mime.mime_for('.ml') | ||||
|     assert_equal 'text/x-ocaml', Mime.mime_for('.sig') | ||||
|     assert_equal 'text/x-ocaml', Mime.mime_for('.sml') | ||||
|     assert_equal 'text/plain', Mime.mime_for('.c') | ||||
|     assert_equal 'text/plain', Mime.mime_for('.cc') | ||||
|     assert_equal 'text/plain', Mime.mime_for('.cpp') | ||||
| @@ -63,8 +59,13 @@ class TestMime < Test::Unit::TestCase | ||||
|     assert_equal 'text/plain', Mime.mime_for('.hpp') | ||||
|     assert_equal 'text/plain', Mime.mime_for('.kt') | ||||
|     assert_equal 'text/x-logtalk', Mime.mime_for('.lgt') | ||||
|     assert_equal 'text/x-rust', Mime.mime_for('.rs') | ||||
|     assert_equal 'text/x-nemerle', Mime.mime_for('.n') | ||||
|     assert_equal 'text/x-nimrod', Mime.mime_for('.nim') | ||||
|     assert_equal 'text/x-ocaml', Mime.mime_for('.ml') | ||||
|     assert_equal 'text/x-ocaml', Mime.mime_for('.sig') | ||||
|     assert_equal 'text/x-ocaml', Mime.mime_for('.sml') | ||||
|     assert_equal 'text/x-rust', Mime.mime_for('.rc') | ||||
|     assert_equal 'text/x-rust', Mime.mime_for('.rs') | ||||
|     assert_equal 'video/quicktime', Mime.mime_for('.mov') | ||||
|   end | ||||
| end | ||||
|   | ||||
| @@ -41,7 +41,7 @@ class TestPathname < Test::Unit::TestCase | ||||
|     assert_equal Language['Python'], Pathname.new("itty.py").language | ||||
|     assert_equal Language['Nu'], Pathname.new("itty.nu").language | ||||
|  | ||||
|     assert_nil Pathname.new("defun.kt").language | ||||
|     assert_nil Pathname.new("defu.nkt").language | ||||
|   end | ||||
|  | ||||
|   def test_lexer | ||||
| @@ -50,13 +50,13 @@ class TestPathname < Test::Unit::TestCase | ||||
|     assert_equal Lexer['Bash'],      Pathname.new("file.ebuild").lexer | ||||
|     assert_equal Lexer['Python'],    Pathname.new("itty.py").lexer | ||||
|     assert_equal Lexer['Scheme'],    Pathname.new("itty.nu").lexer | ||||
|     assert_equal Lexer['Text only'], Pathname.new("defun.kt").lexer | ||||
|     assert_equal Lexer['Text only'], Pathname.new("defu.nkt").lexer | ||||
|   end | ||||
|  | ||||
|   def test_mime_type | ||||
|     assert_equal 'application/x-ruby', Pathname.new("file.rb").mime_type | ||||
|     assert_equal 'application/javascript', Pathname.new("file.js").mime_type | ||||
|     assert_equal 'application/x-python', Pathname.new("itty.py").mime_type | ||||
|     assert_equal 'text/plain', Pathname.new("defun.kt").mime_type | ||||
|     assert_equal 'text/plain', Pathname.new("defu.nkt").mime_type | ||||
|   end | ||||
| end | ||||
|   | ||||
		Reference in New Issue
	
	Block a user