From: Jean Privat Date: Thu, 26 May 2016 13:06:43 +0000 (-0400) Subject: Merge: toolcontext: introduce --share-dir X-Git-Url: http://nitlanguage.org?hp=52314ed8781861f18df0bdb60725eea575b049f0 Merge: toolcontext: introduce --share-dir So other tools than nitdoc can use it. Signed-off-by: Alexandre Terrasa Pull-Request: #2126 Reviewed-by: Jean Privat --- diff --git a/NOTICE b/NOTICE index 2e08fad..33a5cff 100644 --- a/NOTICE +++ b/NOTICE @@ -2,39 +2,48 @@ This product includes software developed as part of the Nit Language project ( http://nitlanguage.org ). Files: * -Copyright: 2004-2015 Jean Privat +Copyright: 2004-2016 Jean Privat 2006-2008 Floréal Morandat 2009 Julien Chevalier 2009-2011 Jean-Sebastien Gelinas - 2009-2015 Alexis Laferrière + 2009-2016 Alexis Laferrière 2011 Matthieu Auger - 2011-2015 Alexandre Terrasa + 2011-2016 Alexandre Terrasa 2012 Alexandre Pennetier - 2013-2015 Lucas Bajolet + 2013-2016 Lucas Bajolet 2013 Stefan Lage 2013 Nathan Heu 2013 Matthieu Lucas - 2014-2015 Romain Chanoir - 2014 Frédéric Vachon + 2014-2016 Romain Chanoir + 2014-2015 Frédéric Vachon 2014 Johan Kayser 2014-2015 Julien Pagès 2014 Geoffrey Hecht - 2014 Jean-Christophe Beaupré + 2014-2016 Jean-Christophe Beaupré 2015 Arthur Delamare + 2015-2016 Mehdi Ait Younes + 2015 Renata Carvalho + 2015 Simon Zeni + 2015 Anis Boubaker + 2015 Istvan SZALAI + 2015 Hervé Matysiak + 2015 Jean-Philippe Caissy + 2015 Alexandre Blondin Massé + 2015-2016 Guilherme Mansur License: Apache 2.0 (see LICENSE) Comment: The main license of the work, except for the following exceptions Files: lib/* clib/* share/nitdoc/* -Copyright: 2004-2015 Jean Privat +Copyright: 2004-2016 Jean Privat 2006-2008 Floréal Morandat 2009-2011 Jean-Sebastien Gelinas - 2009-2015 Alexis Laferrière + 2009-2016 Alexis Laferrière 2009 Julien Chevalier - 2011-2015 Alexandre Terrasa + 2011-2016 Alexandre Terrasa 2012 Alexandre Pennetier - 2013-2015 Lucas Bajolet + 2013-2016 Lucas Bajolet 2013 Nathan Heu 2013 Matthieu Lucas 2013 Stefan Lage @@ -48,7 +57,11 @@ Copyright: 2004-2015 Jean Privat 2014 Maxime Leroy 2014 Johann Dubois 2014-2015 Jean-Christophe Beaupré - 2014 Alexandre Blondin Massé + 2014-2015 Alexandre Blondin Massé + 2015 Mehdi Ait Younes + 2015 Budi Kurniawan + 2015-2016 Philippe Pepos Petitclerc + 2015-2016 Guilherme Mansur Licence: BSD 2 (see LICENSE-BSD) Comment: Use of libraries and resources is basically unrestricted. We hold the copyright on the compiler and the tools but not on the programs made by the users. diff --git a/lib/core/text/abstract_text.nit b/lib/core/text/abstract_text.nit index c9d1279..d7dfa48 100644 --- a/lib/core/text/abstract_text.nit +++ b/lib/core/text/abstract_text.nit @@ -2160,6 +2160,11 @@ redef class NativeString # SEE: `abstract_text::Text` for more info on the difference # between `Text::bytelen` and `Text::length`. fun to_s_full(bytelen, unilen: Int): String is abstract + + # Copies the content of `src` to `self` + # + # NOTE: `self` must be large enough to withold `self.bytelen` bytes + fun fill_from(src: Text) do src.copy_to_native(self, src.bytelen, 0, 0) end redef class NativeArray[E] diff --git a/lib/core/text/flat.nit b/lib/core/text/flat.nit index 2fa0bcb..9e70321 100644 --- a/lib/core/text/flat.nit +++ b/lib/core/text/flat.nit @@ -369,6 +369,10 @@ redef class FlatText end return res end + + redef fun copy_to_native(dst, n, src_off, dst_off) do + _items.copy_to(dst, n, first_byte + src_off, dst_off) + end end # Immutable strings of characters. diff --git a/lib/core/text/ropes.nit b/lib/core/text/ropes.nit index f370e49..0bf97b8 100644 --- a/lib/core/text/ropes.nit +++ b/lib/core/text/ropes.nit @@ -221,23 +221,16 @@ private class Concat end redef fun copy_to_native(dest, n, src_offset, dest_offset) do - var subs = new RopeSubstrings.from(self, src_offset) - var st = src_offset - subs.pos - var off = dest_offset - while n > 0 do - var it = subs.item - if n > it.length then - var cplen = it.length - st - it._items.copy_to(dest, cplen, st, off) - off += cplen - n -= cplen - else - it._items.copy_to(dest, n, st, off) - n = 0 - end - subs.next - st = 0 + var l = _left + if src_offset < l.bytelen then + var lcopy = l.bytelen - src_offset + lcopy = if lcopy > n then n else lcopy + l.copy_to_native(dest, lcopy, src_offset, dest_offset) + dest_offset += lcopy + n -= lcopy + src_offset = 0 end + _right.copy_to_native(dest, n, src_offset, dest_offset) end # Returns a balanced version of `self` diff --git a/lib/crapto/crapto.nit b/lib/crapto/crapto.nit index 6662877..5f3f017 100644 --- a/lib/crapto/crapto.nit +++ b/lib/crapto/crapto.nit @@ -16,3 +16,4 @@ module crapto import english_utils +import xor diff --git a/lib/crapto/examples/repeating_key_xor_cipher.txt b/lib/crapto/examples/repeating_key_xor_cipher.txt new file mode 100644 index 0000000..cecdb81 --- /dev/null +++ b/lib/crapto/examples/repeating_key_xor_cipher.txt @@ -0,0 +1,64 @@ +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 diff --git a/lib/crapto/examples/repeating_key_xor_solve.nit b/lib/crapto/examples/repeating_key_xor_solve.nit new file mode 100644 index 0000000..f88e2d9 --- /dev/null +++ b/lib/crapto/examples/repeating_key_xor_solve.nit @@ -0,0 +1,38 @@ +# This file is part of NIT ( http://www.nitlanguage.org ). +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import base64 +import crapto + +# Check usage +if args.length != 1 then + print "Usage: repeating_key_xor_solve " + exit 1 +end + +# Read the cipher from the file +var cipher_bytes = args[0].to_path.read_all_bytes.decode_base64 + +# Create a RepeatingKeyXorCipher object to manipulate your ciphertext +var xorcipher = new RepeatingKeyXorCipher +xorcipher.ciphertext = cipher_bytes + +# Try to find the best candidate key +xorcipher.find_key + +# Decrypt the cipher according to the found key +xorcipher.decrypt + +# Check the resulting plaintext out... +print xorcipher.plaintext diff --git a/lib/crapto/xor.nit b/lib/crapto/xor.nit new file mode 100644 index 0000000..8745c1a --- /dev/null +++ b/lib/crapto/xor.nit @@ -0,0 +1,150 @@ +# This file is part of NIT ( http://www.nitlanguage.org ). +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Cryptographic attacks and utilities for XOR-based algorithms. +module xor + +import combinations +import crypto +import english_utils + +redef class SingleByteXorCipher + # Tries to find key using frequency analysis on all possible plaintexts. + # Populates `self.key` + fun find_key do + + # Accumulate best result + var max = 0.0 + var best = 0.to_b + + # Iterate on possible values for a byte + var xor_b = new Bytes.with_capacity(1) + for b in [0 .. 255] do + # Need `Bytes` to pass to xor + xor_b[0] = b.to_b + + # Xor and evaluate result + var xored = ciphertext.xorcipher(xor_b) + var result = xored.to_s.english_scoring + if result > max then + max = result + best = b.to_b + end + end + + self.key = best + + end +end + +redef class RepeatingKeyXorCipher + # Attempts to find the key by using frequency analysis on the resulting plaintexts. + # Best key lengths are estimated using the hamming distance of blocks of keylength bytes. + # Ciphertext is then transposed in such a way that it can be solved by sequences of + # SingleByteXor (one for each offset in the key). + # + # `min_keylength` and `max_keylength` are limits as to what key lengths are tested. + # `considered_keylength_count` is the number of best key lengths that are kept to be + # analysed by the SingleByteXor frequency analysis. + fun find_key(min_keylength, max_keylength, considered_keylength_count: nullable Int) do + + # Set default values + if min_keylength == null then min_keylength = 2 + if max_keylength == null then max_keylength = 40 + if considered_keylength_count == null then considered_keylength_count = 3 + + # Find the best candidate key lengths based on the normalized hamming distances + var best_sizes = get_normalized_hamming_distances(min_keylength, max_keylength, considered_keylength_count) + + var best = 0.0 + var best_key: nullable Bytes = null + for ks in best_sizes do + + # Rearrange ciphertext to be in SingleByteXORable blocks + var transposed = transpose_ciphertext(ks) + + var key = new Bytes.empty + for slot in transposed do + var sbx = new SingleByteXorCipher + sbx.ciphertext = slot + sbx.find_key + key.add sbx.key + end + + # Evaluate the resulting plaintext based on english frequency analysis + var eng_score = ciphertext.xorcipher(key).to_s.english_scoring + if eng_score > best then + best_key = key + best = eng_score + end + + assert best_key != null + self.key = best_key + + end + end + + # Computes the normalized hamming distances between blocks of ciphertext of length between `min_length` and `max_length`. + # The `considered_keylength_count` smallest results are returned + private fun get_normalized_hamming_distances(min_keylength, max_keylength, considered_keylength_count: Int): Array[Int] do + + var normalized_distances = new HashMap[Float, Int] + + # Iterate over all given key lengths + for ks in [min_keylength .. max_keylength[ do + + # Initialize the blocks of size `ks` + var blocks = new Array[Bytes] + while (blocks.length + 1) * ks < ciphertext.length do + blocks.add(ciphertext.slice(blocks.length * ks, ks)) + end + + # Compute the normalized hamming distance with all block combinations + var pairs = new CombinationCollection[Bytes](blocks, 2) + var hamming_dists = new Array[Float] + for p in pairs do + hamming_dists.add(p[0].hamming_distance(p[1]).to_f / ks.to_f) + end + + # Normalize the results based on the number of blocks + var normalized = 0.0 + for dist in hamming_dists do normalized += dist + normalized /= hamming_dists.length.to_f + normalized_distances[normalized] = ks + + end + + # Collect the best candidates + var distances = normalized_distances.keys.to_a + default_comparator.sort(distances) + var best_distances = distances.subarray(0, considered_keylength_count) + var best_sizes = [for d in best_distances do normalized_distances[d]] + + return best_sizes + end + + # Returns a rearranged format of the ciphertext where every byte of a slot will be XORed with the same offset of a key of length `keylength`. + private fun transpose_ciphertext(keylength: Int): Array[Bytes] do + var transposed = new Array[Bytes] + for i in [0 .. keylength[ do + transposed.add(new Bytes.empty) + end + + for byte_idx in [0 .. ciphertext.length[ do + transposed[byte_idx % keylength].add(ciphertext[byte_idx]) + end + + return transposed + end +end diff --git a/lib/crypto.nit b/lib/crypto/basic_ciphers.nit similarity index 91% rename from lib/crypto.nit rename to lib/crypto/basic_ciphers.nit index 2abe5d7..e4a133c 100644 --- a/lib/crypto.nit +++ b/lib/crypto/basic_ciphers.nit @@ -12,8 +12,8 @@ # See the License for the specific language governing permissions and # limitations under the License. -# Mix of all things cryptography-related -module crypto +# Basic cryptographic ciphers and utilities. +module basic_ciphers redef class Char # Rotates self of `x` @@ -157,20 +157,21 @@ redef class Text end redef class Bytes - - # Returns `self` xored with `key` - # - # The key is cycled through until the `self` has been completely xored. - # - # assert "goodmorning".to_bytes.xorcipher(" ".to_bytes) == "GOODMORNING".bytes - fun xorcipher(key: Bytes): Bytes do - var xored = new Bytes.with_capacity(self.length) - - for i in self.length.times do - xored.add(self[i] ^ key[i % key.length]) + # Computes the edit/hamming distance of two sequences of bytes. + # + # assert "this is a test".to_bytes.hamming_distance("wokka wokka!!!".bytes) == 37 + # assert "this is a test".to_bytes.hamming_distance("this is a test".bytes) == 0 + # + fun hamming_distance(other: SequenceRead[Byte]): Int do + var diff = 0 + for idx in self.length.times do + var res_byte = self[idx] ^ other[idx] + for bit in [0..8[ do + if res_byte & 1u8 == 1u8 then diff += 1 + res_byte = res_byte >> 1 + end end - - return xored + return diff end end diff --git a/lib/crypto/crypto.nit b/lib/crypto/crypto.nit new file mode 100644 index 0000000..4709403 --- /dev/null +++ b/lib/crypto/crypto.nit @@ -0,0 +1,19 @@ +# This file is part of NIT ( http://www.nitlanguage.org ). +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Mix of all things cryptography-related +module crypto + +import basic_ciphers +import xor_ciphers diff --git a/lib/crypto.ini b/lib/crypto/package.ini similarity index 89% rename from lib/crypto.ini rename to lib/crypto/package.ini index e8b4cf1..24f6b14 100644 --- a/lib/crypto.ini +++ b/lib/crypto/package.ini @@ -6,6 +6,6 @@ license=Apache-2.0 [upstream] browse=https://github.com/nitlang/nit/tree/master/lib/crypto.nit git=https://github.com/nitlang/nit.git -git.directory=lib/crypto.nit +git.directory=lib/crypto/crypto.nit homepage=http://nitlanguage.org issues=https://github.com/nitlang/nit/issues diff --git a/lib/crypto/xor_ciphers.nit b/lib/crypto/xor_ciphers.nit new file mode 100644 index 0000000..1c4807c --- /dev/null +++ b/lib/crypto/xor_ciphers.nit @@ -0,0 +1,88 @@ +# This file is part of NIT ( http://www.nitlanguage.org ). +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# XOR oriented cryptographic ciphers and utilities. +module xor_ciphers + +redef class Bytes + # Returns `self` xored with `key` + # + # The key is cycled through until the `self` has been completely xored. + # + # assert "goodmorning".to_bytes.xorcipher(" ".to_bytes) == "GOODMORNING".bytes + fun xorcipher(key: Bytes): Bytes do + var xored = new Bytes.with_capacity(self.length) + + for i in self.length.times do + xored.add(self[i] ^ key[i % key.length]) + end + + return xored + end +end + +# Base class to modelize cryptographic ciphers +abstract class Cipher + + # Encrypted data + var ciphertext = new Bytes.empty is writable + + # Unencrypted data + var plaintext = new Bytes.empty is writable + + # Encrypt plaintext and populate `self.ciphertext` + fun encrypt is abstract + + # Decrypt ciphertext and populate `self.plaintext` + fun decrypt is abstract + +end + +# Simple XOR cipher where the whole plaintext is XORed with a single byte. +class SingleByteXorCipher + super Cipher + + # Cryptographic key used in encryption and decryption. + var key: Byte = 0.to_b + + redef fun encrypt do + var key_bytes = new Bytes.with_capacity(1) + key_bytes.add(key) + ciphertext = plaintext.xorcipher(key_bytes) + end + + redef fun decrypt do + var key_bytes = new Bytes.with_capacity(1) + key_bytes.add(key) + plaintext = ciphertext.xorcipher(key_bytes) + end +end + +# XOR cipher where the key is repeated to match the length of the message. +class RepeatingKeyXorCipher + super Cipher + + # Cryptographic key used in encryption and decryption. + var key = new Bytes.empty + + redef fun encrypt do + assert key.length > 0 + ciphertext = plaintext.xorcipher(key) + end + + redef fun decrypt do + assert key.length > 0 + plaintext = ciphertext.xorcipher(key) + end +end diff --git a/src/model/model.nit b/src/model/model.nit index 9aefe19..d4ca515 100644 --- a/src/model/model.nit +++ b/src/model/model.nit @@ -30,6 +30,15 @@ import mdoc import ordered_tree private import more_collections +redef class MEntity + # The visibility of the MEntity. + # + # MPackages, MGroups and MModules are always public. + # The visibility of `MClass` and `MProperty` is defined by the keyword used. + # `MClassDef` and `MPropDef` return the visibility of `MClass` and `MProperty`. + fun visibility: MVisibility do return public_visibility +end + redef class Model # All known classes var mclasses = new Array[MClass] @@ -465,7 +474,7 @@ class MClass # The visibility of the class # In Nit, the visibility of a class cannot evolve in refinements - var visibility: MVisibility + redef var visibility init do @@ -593,6 +602,8 @@ class MClassDef redef var location: Location + redef fun visibility do return mclass.visibility + # Internal name combining the module and the class # Example: "mymodule$MyClass" redef var to_s is noinit @@ -1988,7 +1999,7 @@ abstract class MProperty end # The visibility of the property - var visibility: MVisibility + redef var visibility # Is the property usable as an initializer? var is_autoinit = false is writable @@ -2255,6 +2266,8 @@ abstract class MPropDef redef var location: Location + redef fun visibility do return mproperty.visibility + init do mclassdef.mpropdefs.add(self) diff --git a/src/model/model_json.nit b/src/model/model_json.nit index fc4b101..658e73d 100644 --- a/src/model/model_json.nit +++ b/src/model/model_json.nit @@ -59,6 +59,8 @@ redef class MEntity obj["class_name"] = class_name obj["full_name"] = full_name obj["mdoc"] = mdoc_or_fallback + obj["visibility"] = visibility + obj["location"] = location var modifiers = new JsonArray for modifier in collect_modifiers do modifiers.add modifier @@ -114,7 +116,6 @@ redef class MPackage redef fun json do var obj = super - obj["visibility"] = public_visibility if ini != null then obj["ini"] = new JsonObject.from(ini.as(not null).to_map) end @@ -127,7 +128,6 @@ end redef class MGroup redef fun json do var obj = super - obj["visibility"] = public_visibility obj["is_root"] = is_root obj["mpackage"] = to_mentity_ref(mpackage) obj["default_mmodule"] = to_mentity_ref(default_mmodule) @@ -141,8 +141,6 @@ end redef class MModule redef fun json do var obj = super - obj["location"] = location - obj["visibility"] = public_visibility obj["mpackage"] = to_mentity_ref(mpackage) obj["mgroup"] = to_mentity_ref(mgroup) obj["intro_mclasses"] = to_mentity_refs(intro_mclasses) @@ -154,7 +152,6 @@ end redef class MClass redef fun json do var obj = super - obj["visibility"] = visibility var arr = new JsonArray for mparameter in mparameters do arr.add mparameter obj["mparameters"] = arr @@ -169,8 +166,6 @@ end redef class MClassDef redef fun json do var obj = super - obj["visibility"] = mclass.visibility - obj["location"] = location obj["is_intro"] = is_intro var arr = new JsonArray for mparameter in mclass.mparameters do arr.add mparameter @@ -186,7 +181,6 @@ end redef class MProperty redef fun json do var obj = super - obj["visibility"] = visibility obj["intro"] = to_mentity_ref(intro) obj["intro_mclassdef"] = to_mentity_ref(intro_mclassdef) obj["mpropdefs"] = to_mentity_refs(mpropdefs) @@ -223,8 +217,6 @@ end redef class MPropDef redef fun json do var obj = super - obj["visibility"] = mproperty.visibility - obj["location"] = location obj["is_intro"] = is_intro obj["mclassdef"] = to_mentity_ref(mclassdef) obj["mproperty"] = to_mentity_ref(mproperty) diff --git a/src/model/model_visitor.nit b/src/model/model_visitor.nit index da881a0..59d3e61 100644 --- a/src/model/model_visitor.nit +++ b/src/model/model_visitor.nit @@ -144,7 +144,10 @@ redef class MEntity # See the specific implementation in the subclasses. fun visit_all(v: ModelVisitor) do end - private fun accept_visibility(min_visibility: nullable MVisibility): Bool do return true + private fun accept_visibility(min_visibility: nullable MVisibility): Bool do + if min_visibility == null then return true + return visibility >= min_visibility + end end redef class Model @@ -183,13 +186,6 @@ redef class MModule end end -redef class MClass - redef fun accept_visibility(min_visibility) do - if min_visibility == null then return true - return visibility >= min_visibility - end -end - redef class MClassDef # Visit all the classes and class definitions of the module. # @@ -202,23 +198,4 @@ redef class MClassDef v.enter_visit(x) end end - - redef fun accept_visibility(min_visibility) do - if min_visibility == null then return true - return mclass.visibility >= min_visibility - end -end - -redef class MProperty - redef fun accept_visibility(min_visibility) do - if min_visibility == null then return true - return visibility >= min_visibility - end -end - -redef class MPropDef - redef fun accept_visibility(min_visibility) do - if min_visibility == null then return true - return mproperty.visibility >= min_visibility - end end diff --git a/src/testing/testing_base.nit b/src/testing/testing_base.nit index 4249df5..88651ef 100644 --- a/src/testing/testing_base.nit +++ b/src/testing/testing_base.nit @@ -18,6 +18,7 @@ module testing_base import modelize private import parser_util import html +import console redef class ToolContext # opt --full @@ -93,22 +94,101 @@ ulimit -t {{{ulimit_usertime}}} 2> /dev/null # # Default: 10 CPU minute var ulimit_usertime = 600 is writable + + # Show a single-line status to use as a progression. + # + # Note that the line starts with `'\r'` and is not ended by a `'\n'`. + # So it is expected that: + # * no other output is printed between two calls + # * the last `show_unit_status` is followed by a new-line + fun show_unit_status(name: String, tests: SequenceRead[UnitTest], more_message: nullable String) + do + var esc = 27.code_point.to_s + var line = "\r{esc}[K* {name} [" + var done = tests.length + for t in tests do + if not t.is_done then + line += " " + done -= 1 + else if t.error == null then + line += ".".green.bold + else + line += "X".red.bold + end + end + line += "] {done}/{tests.length}" + if more_message != null then + line += " " + more_message + end + printn "{line}" + end + end -# A unit test is an elementary test discovered, run and reported bu nitunit. +# A unit test is an elementary test discovered, run and reported by nitunit. # # This class factorizes `DocUnit` and `TestCase`. abstract class UnitTest + # The name of the unit to show in messages + fun full_name: String is abstract + + # The location of the unit test to show in messages. + fun location: Location is abstract - # Error occurred during test-case execution. + # Flag that indicates if the unit test was compiled/run. + var is_done: Bool = false is writable + + # Error message occurred during test-case execution (or compilation). + # + # e.g.: `Runtime Error` var error: nullable String = null is writable # Was the test case executed at least once? + # + # This will indicate the status of the test (failture or error) var was_exec = false is writable - # Return the `TestCase` in XML format compatible with Jenkins. + # The raw output of the execution (or compilation) # - # See to_xml + # It merges the standard output and error output + var raw_output: nullable String = null is writable + + # The location where the error occurred, if it makes sense. + var error_location: nullable Location = null is writable + + # A colorful `[OK]` or `[KO]`. + fun status_tag: String do + if not is_done then + return "[ ]" + else if error != null then + return "[KO]".red.bold + else + return "[OK]".green.bold + end + end + + # The full (color) description of the test-case. + # + # `more message`, if any, is added after the error message. + fun to_screen(more_message: nullable String): String do + var res + var error = self.error + if error != null then + if more_message != null then error += " " + more_message + var loc = error_location or else location + res = "{status_tag} {full_name}\n {loc.to_s.yellow}: {error}\n{loc.colored_line("1;31")}" + var output = self.raw_output + if output != null then + res += "\n Output\n\t{output.chomp.replace("\n", "\n\t")}\n" + end + else + res = "{status_tag} {full_name}" + if more_message != null then res += more_message + end + return res + end + + # Return a `` XML node in format compatible with Jenkins unit tests. fun to_xml: HTMLTag do var tc = new HTMLTag("testcase") tc.attr("classname", xml_classname) @@ -116,11 +196,14 @@ abstract class UnitTest var error = self.error if error != null then if was_exec then - tc.open("error").append("Runtime Error") + tc.open("error").append(error) else - tc.open("failure").append("Compilation Error") + tc.open("failure").append(error) end - tc.open("system-err").append(error.trunc(8192).filter_nonprintable) + end + var output = self.raw_output + if output != null then + tc.open("system-err").append(output.trunc(8192).filter_nonprintable) end return tc end @@ -128,6 +211,8 @@ abstract class UnitTest # The `classname` attribute of the XML format. # # NOTE: jenkins expects a '.' in the classname attr + # + # See to_xml fun xml_classname: String is abstract # The `name` attribute of the XML format. diff --git a/src/testing/testing_doc.nit b/src/testing/testing_doc.nit index 1ea2cf7..2465d37 100644 --- a/src/testing/testing_doc.nit +++ b/src/testing/testing_doc.nit @@ -36,6 +36,9 @@ class NitUnitExecutor # The XML node associated to the module var testsuite: HTMLTag + # The name of the suite + var name: String + # Markdown processor used to parse markdown comments and extract code. var mdproc = new MarkdownProcessor @@ -70,20 +73,37 @@ class NitUnitExecutor # Populate `blocks` from the markdown decorator mdproc.process(mdoc.content.join("\n")) - - toolcontext.check_errors end # All extracted docunits var docunits = new Array[DocUnit] + fun show_status(more_message: nullable String) + do + toolcontext.show_unit_status(name, docunits, more_message) + end + + fun mark_done(du: DocUnit) + do + du.is_done = true + show_status(du.full_name + " " + du.status_tag) + end + # Execute all the docunits fun run_tests do + if docunits.is_empty then + return + end + var simple_du = new Array[DocUnit] + show_status for du in docunits do # Skip existing errors - if du.error != null then continue + if du.error != null then + mark_done(du) + continue + end var ast = toolcontext.parse_something(du.block) if ast isa AExpr then @@ -95,6 +115,13 @@ class NitUnitExecutor test_simple_docunits(simple_du) + show_status + print "" + + for du in docunits do + print du.to_screen + end + for du in docunits do testsuite.add du.to_xml end @@ -149,16 +176,16 @@ class NitUnitExecutor i += 1 toolcontext.info("Execute doc-unit {du.full_name} in {file} {i}", 1) var res2 = toolcontext.safe_exec("{file.to_program_name}.bin {i} >'{file}.out1' 2>&1 '{file}.out1' 2>&1 '{res_name}.out1' 2>&1 '{res_name}.diff' 2>&1 assert true -assert false -Compilation Error.nitunit/test_nitunit-3.nit:5,8--27: Error: method or variable `undefined_identifier` unknown in `Sys`. +assert true +Runtime error in .nitunit/test_nitunit-2.nitRuntime error: Assert failed (.nitunit/test_nitunit-2.nit:5) +assert false +Compilation error in .nitunit/test_nitunit-3.nit.nitunit/test_nitunit-3.nit:5,8--27: Error: method or variable `undefined_identifier` unknown in `Sys`. assert undefined_identifier -Runtime ErrorRuntime error: Assert failed (test_test_nitunit.nit:39) - \ No newline at end of file +Syntax Error: unexpected operator '!'.assert !@#$%^&*() +Runtime Error in file .nitunit/gen_test_test_nitunit.nitRuntime error: Assert failed (test_test_nitunit.nit:39) + \ No newline at end of file diff --git a/tests/sav/nitunit_args4.res b/tests/sav/nitunit_args4.res index 4cb3aaa..95b3751 100644 --- a/tests/sav/nitunit_args4.res +++ b/tests/sav/nitunit_args4.res @@ -1,3 +1,7 @@ + * Docunits of module test_nitunit2::test_nitunit2 [ ] 0/3 * Docunits of module test_nitunit2::test_nitunit2 [. ] 1/3 test_nitunit2::test_nitunit2$core::Sys$foo1 [OK] * Docunits of module test_nitunit2::test_nitunit2 [.. ] 2/3 test_nitunit2::test_nitunit2$core::Sys$bar2 [OK] * Docunits of module test_nitunit2::test_nitunit2 [...] 3/3 test_nitunit2::test_nitunit2$core::Sys$foo3 [OK] * Docunits of module test_nitunit2::test_nitunit2 [...] 3/3 +[OK] test_nitunit2::test_nitunit2$core::Sys$foo1 +[OK] test_nitunit2::test_nitunit2$core::Sys$bar2 +[OK] test_nitunit2::test_nitunit2$core::Sys$foo3 DocUnits: DocUnits Success Entities: 4; Documented ones: 3; With nitunits: 3; Failures: 0 @@ -5,17 +9,17 @@ Entities: 4; Documented ones: 3; With nitunits: 3; Failures: 0 TestSuites: No test cases found Class suites: 0; Test Cases: 0; Failures: 0 -if true then +if true then assert true end -if true then +if true then assert true end -var a = 1 +var a = 1 assert a == 1 assert a == 1 \ No newline at end of file diff --git a/tests/sav/nitunit_args5.res b/tests/sav/nitunit_args5.res index 8fa1c3c..f161044 100644 --- a/tests/sav/nitunit_args5.res +++ b/tests/sav/nitunit_args5.res @@ -1,3 +1,7 @@ + * Docunits of module test_doc2::test_doc2 [ ] 0/3 * Docunits of module test_doc2::test_doc2 [. ] 1/3 test_doc2::test_doc2$core::Sys$foo1 [OK] * Docunits of module test_doc2::test_doc2 [.. ] 2/3 test_doc2::test_doc2$core::Sys$foo2 [OK] * Docunits of module test_doc2::test_doc2 [...] 3/3 test_doc2::test_doc2$core::Sys$foo3 [OK] * Docunits of module test_doc2::test_doc2 [...] 3/3 +[OK] test_doc2::test_doc2$core::Sys$foo1 +[OK] test_doc2::test_doc2$core::Sys$foo2 +[OK] test_doc2::test_doc2$core::Sys$foo3 DocUnits: DocUnits Success Entities: 6; Documented ones: 5; With nitunits: 3; Failures: 0 @@ -5,7 +9,7 @@ Entities: 6; Documented ones: 5; With nitunits: 3; Failures: 0 TestSuites: No test cases found Class suites: 0; Test Cases: 0; Failures: 0 -assert true # tested -assert true # tested -assert true # tested +assert true # tested +assert true # tested +assert true # tested \ No newline at end of file diff --git a/tests/sav/nitunit_args6.res b/tests/sav/nitunit_args6.res index ca7ee6a..13ff875 100644 --- a/tests/sav/nitunit_args6.res +++ b/tests/sav/nitunit_args6.res @@ -1,16 +1,27 @@ -test_nitunit3/README.md:7,3--5: Syntax Error: unexpected malformed character '\]. To suppress this message, enclose the block with a fence tagged `nitish` or `raw` (see `man nitdoc`). -test_nitunit3/README.md:4,2--15,0: ERROR: test_nitunit3> (in .nitunit/test_nitunit3-0.nit): Runtime error -Runtime error: Assert failed (.nitunit/test_nitunit3-0.nit:7) + * Docunits of group test_nitunit3> [ ] 0/2 * Docunits of group test_nitunit3> [ X] 1/2 test_nitunit3> [KO] * Docunits of group test_nitunit3> [XX] 2/2 test_nitunit3> [KO] * Docunits of group test_nitunit3> [XX] 2/2 +[KO] test_nitunit3> + test_nitunit3/README.md:4,2--15,0: Runtime error in .nitunit/test_nitunit3-0.nit with argument 1 + ~~ + ^ + Output + Runtime error: Assert failed (.nitunit/test_nitunit3-0.nit:7) +[KO] test_nitunit3> + test_nitunit3/README.md:7,3--5: Syntax Error: unexpected malformed character '\]. + ~~~ +; + ^ + * Docunits of module test_nitunit3::test_nitunit3 [ ] 0/1 * Docunits of module test_nitunit3::test_nitunit3 [.] 1/1 test_nitunit3::test_nitunit3 [OK] * Docunits of module test_nitunit3::test_nitunit3 [.] 1/1 +[OK] test_nitunit3::test_nitunit3 DocUnits: Entities: 2; Documented ones: 2; With nitunits: 3; Failures: 2 TestSuites: No test cases found Class suites: 0; Test Cases: 0; Failures: 0 -Compilation ErrorRuntime error: Assert failed (.nitunit/test_nitunit3-0.nit:7) +Runtime error in .nitunit/test_nitunit3-0.nit with argument 1Runtime error: Assert failed (.nitunit/test_nitunit3-0.nit:7) assert false assert true -Compilation Errortest_nitunit3/README.md:7,3--5: Syntax Error: unexpected malformed character '\].;'\][] -assert true +Syntax Error: unexpected malformed character '\].;'\][] +assert true \ No newline at end of file diff --git a/tests/sav/nitunit_args7.res b/tests/sav/nitunit_args7.res index 0888b04..bf0c504 100644 --- a/tests/sav/nitunit_args7.res +++ b/tests/sav/nitunit_args7.res @@ -1,5 +1,10 @@ -test_nitunit_md.md:4,2--16,0: ERROR: nitunit..test_nitunit_md.md:1,0--15,0 (in .nitunit/file-0.nit): Runtime error -Runtime error: Assert failed (.nitunit/file-0.nit:8) + * Docunits of file test_nitunit_md.md:1,0--15,0 [ ] 0/1 * Docunits of file test_nitunit_md.md:1,0--15,0 [X] 1/1 nitunit..test_nitunit_md.md:1,0--15,0 [KO] * Docunits of file test_nitunit_md.md:1,0--15,0 [X] 1/1 +[KO] nitunit..test_nitunit_md.md:1,0--15,0 + test_nitunit_md.md:4,2--16,0: Runtime error in .nitunit/file-0.nit with argument 1 + ~~ + ^ + Output + Runtime error: Assert failed (.nitunit/file-0.nit:8) DocUnits: Entities: 1; Documented ones: 1; With nitunits: 1; Failures: 1 @@ -7,7 +12,7 @@ Entities: 1; Documented ones: 1; With nitunits: 1; Failures: 1 TestSuites: No test cases found Class suites: 0; Test Cases: 0; Failures: 0 -Compilation ErrorRuntime error: Assert failed (.nitunit/file-0.nit:8) +Runtime error in .nitunit/file-0.nit with argument 1Runtime error: Assert failed (.nitunit/file-0.nit:8) var a = 1 assert 1 == 1 assert false diff --git a/tests/sav/nitunit_args8.res b/tests/sav/nitunit_args8.res index afa1ac3..c3e9bf7 100644 --- a/tests/sav/nitunit_args8.res +++ b/tests/sav/nitunit_args8.res @@ -1,13 +1,23 @@ -test_doc3.nit:17,9--15: Syntax Error: unexpected identifier 'garbage'. To suppress this message, enclose the block with a fence tagged `nitish` or `raw` (see `man nitdoc`). -test_doc3.nit:23,4--10: Syntax Error: unexpected identifier 'garbage'. To suppress this message, enclose the block with a fence tagged `nitish` or `raw` (see `man nitdoc`). -test_doc3.nit:30,4--10: Syntax Error: unexpected identifier 'garbage'. To suppress this message, enclose the block with a fence tagged `nitish` or `raw` (see `man nitdoc`). + * Docunits of module test_doc3::test_doc3 [ ] 0/3 * Docunits of module test_doc3::test_doc3 [X ] 1/3 test_doc3::test_doc3$core::Sys$foo1 [KO] * Docunits of module test_doc3::test_doc3 [XX ] 2/3 test_doc3::test_doc3$core::Sys$foo2 [KO] * Docunits of module test_doc3::test_doc3 [XXX] 3/3 test_doc3::test_doc3$core::Sys$foo3 [KO] * Docunits of module test_doc3::test_doc3 [XXX] 3/3 +[KO] test_doc3::test_doc3$core::Sys$foo1 + test_doc3.nit:17,9--15: Syntax Error: unexpected identifier 'garbage'. + # *garbage* + ^ +[KO] test_doc3::test_doc3$core::Sys$foo2 + test_doc3.nit:23,4--10: Syntax Error: unexpected identifier 'garbage'. + # *garbage* + ^ +[KO] test_doc3::test_doc3$core::Sys$foo3 + test_doc3.nit:30,4--10: Syntax Error: unexpected identifier 'garbage'. + # *garbage* + ^ DocUnits: Entities: 6; Documented ones: 5; With nitunits: 3; Failures: 3 TestSuites: No test cases found Class suites: 0; Test Cases: 0; Failures: 0 -Compilation Errortest_doc3.nit:17,9--15: Syntax Error: unexpected identifier 'garbage'. *garbage* -Compilation Errortest_doc3.nit:23,4--10: Syntax Error: unexpected identifier 'garbage'.*garbage* -Compilation Errortest_doc3.nit:30,4--10: Syntax Error: unexpected identifier 'garbage'.*garbage* +Syntax Error: unexpected identifier 'garbage'. *garbage* +Syntax Error: unexpected identifier 'garbage'.*garbage* +Syntax Error: unexpected identifier 'garbage'.*garbage* \ No newline at end of file diff --git a/tests/sav/nitunit_args9.res b/tests/sav/nitunit_args9.res index 27d74a9..5806e40 100644 --- a/tests/sav/nitunit_args9.res +++ b/tests/sav/nitunit_args9.res @@ -1,16 +1,28 @@ -test_nitunit4/test_nitunit4.nit:22,2--26,4: ERROR: test_foo (in file .nitunit/gen_test_nitunit4.nit): Before Test -Tested method -After Test -Runtime error: Assert failed (test_nitunit4/test_nitunit4_base.nit:31) + * Test-suite of module test_nitunit4::test_nitunit4 [ ] 0/3 * Test-suite of module test_nitunit4::test_nitunit4 [X ] 1/3 test_nitunit4$TestTestSuite$test_foo [KO] * Test-suite of module test_nitunit4::test_nitunit4 [X. ] 2/3 test_nitunit4$TestTestSuite$test_bar [OK] * Test-suite of module test_nitunit4::test_nitunit4 [X.X] 3/3 test_nitunit4$TestTestSuite$test_baz [KO] * Test-suite of module test_nitunit4::test_nitunit4 [X.X] 3/3 +[KO] test_nitunit4$TestTestSuite$test_foo + test_nitunit4/test_nitunit4.nit:22,2--26,4: Runtime Error in file .nitunit/gen_test_nitunit4.nit + fun test_foo do + ^ + Output + Before Test + Tested method + After Test + Runtime error: Assert failed (test_nitunit4/test_nitunit4_base.nit:31) -test_nitunit4/test_nitunit4.nit:32,2--34,4: ERROR: test_baz (in file .nitunit/gen_test_nitunit4.nit): Diff ---- expected:test_nitunit4/test_nitunit4.sav/test_baz.res -+++ got:.nitunit/gen_test_nitunit4_test_baz.out1 -@@ -1 +1,3 @@ --Bad result file -+Before Test -+Tested method -+After Test +[OK] test_nitunit4$TestTestSuite$test_bar +[KO] test_nitunit4$TestTestSuite$test_baz + test_nitunit4/test_nitunit4.nit:32,2--34,4: Difference with expected output: diff -u test_nitunit4/test_nitunit4.sav/test_baz.res .nitunit/gen_test_nitunit4_test_baz.out1 + fun test_baz do + ^ + Output + Diff + --- expected:test_nitunit4/test_nitunit4.sav/test_baz.res + +++ got:.nitunit/gen_test_nitunit4_test_baz.out1 + @@ -1 +1,3 @@ + -Bad result file + +Before Test + +Tested method + +After Test DocUnits: No doc units found @@ -18,11 +30,14 @@ Entities: 12; Documented ones: 0; With nitunits: 0; Failures: 0 TestSuites: Class suites: 1; Test Cases: 3; Failures: 2 -Runtime ErrorBefore Test +Runtime Error in file .nitunit/gen_test_nitunit4.nitBefore Test Tested method After Test Runtime error: Assert failed (test_nitunit4/test_nitunit4_base.nit:31) -Runtime ErrorDiff +Before Test +Tested method +After Test +Difference with expected output: diff -u test_nitunit4/test_nitunit4.sav/test_baz.res .nitunit/gen_test_nitunit4_test_baz.out1Diff --- expected:test_nitunit4/test_nitunit4.sav/test_baz.res +++ got:.nitunit/gen_test_nitunit4_test_baz.out1 @@ -1 +1,3 @@ diff --git a/tests/sav/repeating_key_xor_solve.res b/tests/sav/repeating_key_xor_solve.res new file mode 100644 index 0000000..8a61309 --- /dev/null +++ b/tests/sav/repeating_key_xor_solve.res @@ -0,0 +1 @@ +Usage: repeating_key_xor_solve diff --git a/tests/sav/repeating_key_xor_solve_args1.res b/tests/sav/repeating_key_xor_solve_args1.res new file mode 100644 index 0000000..f81264e --- /dev/null +++ b/tests/sav/repeating_key_xor_solve_args1.res @@ -0,0 +1,80 @@ +I'm back and I'm ringin' the bell +A rockin' on the mike while the fly girls yell +In ecstasy in the back of me +Well that's my DJ Deshay cuttin' all them Z's +Hittin' hard and the girlies goin' crazy +Vanilla's on the mike, man I'm not lazy. + +I'm lettin' my drug kick in +It controls my mouth and I begin +To just let it flow, let my concepts go +My posse's to the side yellin', Go Vanilla Go! + +Smooth 'cause that's the way I will be +And if you don't give a damn, then +Why you starin' at me +So get off 'cause I control the stage +There's no dissin' allowed +I'm in my own phase +The girlies sa y they love me and that is ok +And I can dance better than any kid n' play + +Stage 2 -- Yea the one ya' wanna listen to +It's off my head so let the beat play through +So I can funk it up and make it sound good +1-2-3 Yo -- Knock on some wood +For good luck, I like my rhymes atrocious +Supercalafragilisticexpialidocious +I'm an effect and that you can bet +I can take a fly girl and make her wet. + +I'm like Samson -- Samson to Delilah +There's no denyin', You can try to hang +But you'll keep tryin' to get my style +Over and over, practice makes perfect +But not if you're a loafer. + +You'll get nowhere, no place, no time, no girls +Soon -- Oh my God, homebody, you probably eat +Spaghetti with a spoon! Come on and say it! + +VIP. Vanilla Ice yep, yep, I'm comin' hard like a rhino +Intoxicating so you stagger like a wino +So punks stop trying and girl stop cryin' +Vanilla Ice is sellin' and you people are buyin' +'Cause why the freaks are jockin' like Crazy Glue +Movin' and groovin' trying to sing along +All through the ghetto groovin' this here song +Now you're amazed by the VIP posse. + +Steppin' so hard like a German Nazi +Startled by the bases hittin' ground +There's no trippin' on mine, I'm just gettin' down +Sparkamatic, I'm hangin' tight like a fanatic +You trapped me once and I thought that +You might have it +So step down and lend me your ear +'89 in my time! You, '90 is my year. + +You're weakenin' fast, YO! and I can tell it +Your body's gettin' hot, so, so I can smell it +So don't be mad and don't be sad +'Cause the lyrics belong to ICE, You can call me Dad +You're pitchin' a fit, so step back and endure +Let the witch doctor, Ice, do the dance to cure +So come up close and don't be square +You wanna battle me -- Anytime, anywhere + +You thought that I was weak, Boy, you're dead wrong +So come on, everybody and sing this song + +Say -- Play that funky music Say, go white boy, go white boy go +play that funky music Go white boy, go white boy, go +Lay down and boogie and play that funky music till you die. + +Play that funky music Come on, Come on, let me hear +Play that funky music white boy you say it, say it +Play that funky music A little louder now +Play that funky music, white boy Come on, Come on, Come on +Play that funky music + diff --git a/tests/sav/test_copy_to_native.res b/tests/sav/test_copy_to_native.res new file mode 100644 index 0000000..764d170 --- /dev/null +++ b/tests/sav/test_copy_to_native.res @@ -0,0 +1 @@ +gâštr diff --git a/tests/sav/test_copy_to_native_alt1.res b/tests/sav/test_copy_to_native_alt1.res new file mode 100644 index 0000000..785cb5d --- /dev/null +++ b/tests/sav/test_copy_to_native_alt1.res @@ -0,0 +1 @@ +gâštr%D diff --git a/tests/sav/test_copy_to_native_alt2.res b/tests/sav/test_copy_to_native_alt2.res new file mode 100644 index 0000000..ec88d9a --- /dev/null +++ b/tests/sav/test_copy_to_native_alt2.res @@ -0,0 +1 @@ +gâštré diff --git a/tests/sav/test_nativestring_fill_from.res b/tests/sav/test_nativestring_fill_from.res new file mode 100644 index 0000000..2c26c70 --- /dev/null +++ b/tests/sav/test_nativestring_fill_from.res @@ -0,0 +1 @@ +S&éstr diff --git a/tests/sav/test_nativestring_fill_from_alt1.res b/tests/sav/test_nativestring_fill_from_alt1.res new file mode 100644 index 0000000..0667158 --- /dev/null +++ b/tests/sav/test_nativestring_fill_from_alt1.res @@ -0,0 +1 @@ +S&éstrS&éstr diff --git a/tests/sav/test_nativestring_fill_from_alt2.res b/tests/sav/test_nativestring_fill_from_alt2.res new file mode 100644 index 0000000..2c26c70 --- /dev/null +++ b/tests/sav/test_nativestring_fill_from_alt2.res @@ -0,0 +1 @@ +S&éstr diff --git a/tests/sav/test_nativestring_fill_from_alt3.res b/tests/sav/test_nativestring_fill_from_alt3.res new file mode 100644 index 0000000..f28809f --- /dev/null +++ b/tests/sav/test_nativestring_fill_from_alt3.res @@ -0,0 +1 @@ +&éstr diff --git a/tests/test_copy_to_native.nit b/tests/test_copy_to_native.nit new file mode 100644 index 0000000..380c02a --- /dev/null +++ b/tests/test_copy_to_native.nit @@ -0,0 +1,28 @@ +# This file is part of NIT ( http://www.nitlanguage.org ). +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import core +#alt1 intrude import core::text::ropes +#alt2 intrude import core::text::ropes + +var ons = new NativeString(9) +var base_str = "%Dégâštr" + +var str: String = base_str +#alt1 str = new Concat(base_str, base_str) +#alt2 str = new Concat(base_str, base_str.substring_from(2)) + +var copy_len = (str.bytelen - 4).min(9) +str.copy_to_native(ons, copy_len, 4, 0) +print ons.to_s_with_length(copy_len) diff --git a/tests/test_nativestring_fill_from.nit b/tests/test_nativestring_fill_from.nit new file mode 100644 index 0000000..1b9e491 --- /dev/null +++ b/tests/test_nativestring_fill_from.nit @@ -0,0 +1,27 @@ +# This file is part of NIT ( http://www.nitlanguage.org ). +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +#alt1 intrude import core::text::ropes +import core + +var src_s = "S&éstr" +var cpstr: Text = src_s +#alt1 cpstr = new Concat(src_s, src_s) +#alt2 cpstr = new FlatBuffer.from(src_s) +#alt3 cpstr = cpstr.substring(1, 5) + +var ns = new NativeString(cpstr.bytelen) +ns.fill_from(cpstr) + +print ns.to_s_with_length(cpstr.bytelen) diff --git a/tests/test_nitunit.nit b/tests/test_nitunit.nit index b583197..d260cd1 100644 --- a/tests/test_nitunit.nit +++ b/tests/test_nitunit.nit @@ -24,6 +24,8 @@ class X # assert undefined_identifier fun foo do end + # a 'failure' unit test (does not parse) + # assert !@#$%^&*() fun foo1(a, b: Int) do end private fun foo2: Bool do return true