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,8 +78,11 @@ module Linguist
|
||||
guesses = ::MIME::Types.type_for(ext_or_mime_type)
|
||||
end
|
||||
|
||||
# Prefer text mime types over binary
|
||||
guesses.detect { |type| type.ascii? } ||
|
||||
# Use custom override first
|
||||
guesses.detect { |type| type.override } ||
|
||||
|
||||
# Prefer text mime types over binary
|
||||
guesses.detect { |type| type.ascii? } ||
|
||||
|
||||
# Otherwise use the first guess
|
||||
guesses.first
|
||||
|
||||
@@ -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