don't use as many strings when panicking on unwrapping typed values

link to fixtures directory rather than copying fixtures files

Remove logs, boilerplate comments and unused code.
This commit is contained in:
Emily Toop 2018-04-24 14:05:20 +01:00
parent f924da4517
commit 0c758ab6d3
21 changed files with 65 additions and 2167 deletions

View file

@ -307,229 +307,180 @@ pub unsafe extern "C" fn query_builder_execute(query_builder: *mut QueryBuilder)
Box::into_raw(Box::new(results.into()))
}
fn unwrap_conversion<T>(value: Option<T>, expected_type: ValueType) -> T {
match value {
Some(v) => v,
None => panic!("Typed value cannot be coerced into a {}", expected_type)
}
}
// as_long
#[no_mangle]
pub unsafe extern "C" fn typed_value_as_long(typed_value: *mut Binding) -> c_longlong {
pub unsafe extern "C" fn typed_value_as_long(typed_value: *mut Binding) -> c_longlong {
let typed_value = Box::from_raw(typed_value);
typed_value.into_long().expect("Typed value cannot be coerced into a Long")
unwrap_conversion(typed_value.into_long(), ValueType::Long)
}
// as_entid
#[no_mangle]
pub unsafe extern "C" fn typed_value_as_entid(typed_value: *mut Binding) -> Entid {
pub unsafe extern "C" fn typed_value_as_entid(typed_value: *mut Binding) -> Entid {
let typed_value = Box::from_raw(typed_value);
typed_value.into_entid().expect("Typed value cannot be coerced into an Entid")
unwrap_conversion(typed_value.into_entid(), ValueType::Ref)
}
// kw
#[no_mangle]
pub unsafe extern "C" fn typed_value_as_kw(typed_value: *mut Binding) -> *const c_char {
pub unsafe extern "C" fn typed_value_as_kw(typed_value: *mut Binding) -> *const c_char {
let typed_value = Box::from_raw(typed_value);
typed_value.into_kw_c_string().expect("Typed value cannot be coerced into a Namespaced Keyword")
unwrap_conversion(typed_value.into_kw_c_string(), ValueType::Keyword) as *const c_char
}
//as_boolean
#[no_mangle]
pub unsafe extern "C" fn typed_value_as_boolean(typed_value: *mut Binding) -> i32 {
let typed_value = Box::from_raw(typed_value);
if typed_value.into_boolean().expect("Typed value cannot be coerced into a Boolean") { 1 } else { 0 }
if unwrap_conversion(typed_value.into_boolean(), ValueType::Boolean) { 1 } else { 0 }
}
//as_double
#[no_mangle]
pub unsafe extern "C" fn typed_value_as_double(typed_value: *mut Binding) -> f64 {
pub unsafe extern "C" fn typed_value_as_double(typed_value: *mut Binding) -> f64 {
let typed_value = Box::from_raw(typed_value);
typed_value.into_double().expect("Typed value cannot be coerced into a Double")
unwrap_conversion(typed_value.into_double(), ValueType::Double)
}
//as_timestamp
#[no_mangle]
pub unsafe extern "C" fn typed_value_as_timestamp(typed_value: *mut Binding) -> c_longlong {
pub unsafe extern "C" fn typed_value_as_timestamp(typed_value: *mut Binding) -> c_longlong {
let typed_value = Box::from_raw(typed_value);
let t = typed_value.value_type();
typed_value.into_timestamp().expect(&format!("Typed value of type {:?} cannot be coerced into a Timestamp", t))
unwrap_conversion(typed_value.into_timestamp(), ValueType::Instant)
}
//as_string
#[no_mangle]
pub unsafe extern "C" fn typed_value_as_string(typed_value: *mut Binding) -> *const c_char {
pub unsafe extern "C" fn typed_value_as_string(typed_value: *mut Binding) -> *const c_char {
let typed_value = Box::from_raw(typed_value);
typed_value.into_c_string().expect("Typed value cannot be coerced into a String")
unwrap_conversion(typed_value.into_c_string(), ValueType::String) as *const c_char
}
//as_uuid
#[no_mangle]
pub unsafe extern "C" fn typed_value_as_uuid(typed_value: *mut Binding) -> *mut [u8; 16] {
pub unsafe extern "C" fn typed_value_as_uuid(typed_value: *mut Binding) -> *mut [u8; 16] {
let typed_value = Box::from_raw(typed_value);
let value = typed_value.into_uuid().expect("Typed value cannot be coerced into a Uuid");
let value = unwrap_conversion(typed_value.into_uuid(), ValueType::Uuid);
Box::into_raw(Box::new(*value.as_bytes()))
}
//value_type
#[no_mangle]
pub unsafe extern "C" fn typed_value_value_type(typed_value: *mut Binding) -> ValueType {
pub unsafe extern "C" fn typed_value_value_type(typed_value: *mut Binding) -> ValueType {
let typed_value = &*typed_value;
typed_value.value_type().unwrap_or_else(|| panic!("Binding is not Scalar and has no ValueType"))
}
#[no_mangle]
pub unsafe extern "C" fn row_at_index(rows: *mut Vec<Vec<Binding>>, index: c_int) -> *mut Vec<Binding> {
pub unsafe extern "C" fn row_at_index(rows: *mut RelResult<Binding>, index: c_int) -> *mut Vec<Binding> {
let result = &*rows;
result.get(index as usize).map_or_else(std::ptr::null_mut, |v| Box::into_raw(Box::new(v.clone())))
result.row(index as usize).map_or_else(std::ptr::null_mut, |v| Box::into_raw(Box::new(v.to_vec())))
}
#[no_mangle]
pub unsafe extern "C" fn rows_iter(rows: *mut RelResult<Binding>) -> *mut BindingListIterator {
pub unsafe extern "C" fn rows_iter(rows: *mut RelResult<Binding>) -> *mut BindingListIterator {
let result = &*rows;
let rows = result.rows();
Box::into_raw(Box::new(rows))
}
#[no_mangle]
pub unsafe extern "C" fn rows_iter_next(iter: *mut BindingListIterator) -> *mut Vec<Binding> {
pub unsafe extern "C" fn rows_iter_next(iter: *mut BindingListIterator) -> *mut Vec<Binding> {
let iter = &mut *iter;
iter.next().map_or(std::ptr::null_mut(), |v| Box::into_raw(Box::new(v.to_vec())))
}
#[no_mangle]
pub unsafe extern "C" fn values_iter(values: *mut Vec<Binding>) -> *mut BindingIterator {
pub unsafe extern "C" fn values_iter(values: *mut Vec<Binding>) -> *mut BindingIterator {
let result = Box::from_raw(values);
Box::into_raw(Box::new(result.into_iter()))
}
#[no_mangle]
pub unsafe extern "C" fn values_iter_next(iter: *mut BindingIterator) -> *mut Binding {
pub unsafe extern "C" fn values_iter_next(iter: *mut BindingIterator) -> *mut Binding {
let iter = &mut *iter;
iter.next().map_or(std::ptr::null_mut(), |v| Box::into_raw(Box::new(v)))
}
//as_long
#[no_mangle]
pub unsafe extern "C" fn values_iter_next_as_long(iter: *mut BindingIterator) -> *const c_longlong {
let iter = &mut *iter;
iter.next().map_or(std::ptr::null_mut(), |v| &v.into_long().expect("Typed value cannot be coerced into a Long") as *const c_longlong)
}
// as ref
#[no_mangle]
pub unsafe extern "C" fn values_iter_next_as_entid(iter: *mut BindingIterator) -> *const Entid {
let iter = &mut *iter;
iter.next().map_or_else(std::ptr::null, |v| &v.into_entid().expect("Typed value cannot be coerced into am Entid") as *const Entid)
}
// as kw
#[no_mangle]
pub unsafe extern "C" fn values_iter_next_as_kw(iter: *mut BindingIterator) -> *const c_char {
let iter = &mut *iter;
iter.next().map_or_else(std::ptr::null, |v| v.into_kw_c_string().expect("Typed value cannot be coerced into a Namespaced Keyword"))
}
//as_boolean
#[no_mangle]
pub unsafe extern "C" fn values_iter_next_as_boolean(iter: *mut BindingIterator) -> *const i32 {
let iter = &mut *iter;
iter.next().map_or(std::ptr::null_mut(), |v| if v.into_boolean().expect("Typed value cannot be coerced into a Boolean") { 1 } else { 0 } as *const i32)
}
//as_double
#[no_mangle]
pub unsafe extern "C" fn values_iter_next_as_double(iter: *mut BindingIterator) -> *const f64 {
let iter = &mut *iter;
iter.next().map_or_else(std::ptr::null, |v| &v.into_double().expect("Typed value cannot be coerced into a Double") as *const f64)
}
//as_timestamp
#[no_mangle]
pub unsafe extern "C" fn values_iter_next_as_timestamp(iter: *mut BindingIterator) -> *const i64 {
let iter = &mut *iter;
iter.next().map_or_else(std::ptr::null, |v| v.into_timestamp().expect("Typed value cannot be coerced into a Timestamp") as *const i64)
}
//as_string
#[no_mangle]
pub unsafe extern "C" fn values_iter_next_as_string(iter: *mut BindingIterator) -> *const c_char {
let iter = &mut *iter;
iter.next().map_or_else(std::ptr::null, |v| v.into_c_string().expect("Typed value cannot be coerced into a String"))
}
//as_uuid
#[no_mangle]
pub unsafe extern "C" fn values_iter_next_as_uuid(iter: *mut BindingIterator) -> *const c_char {
let iter = &mut *iter;
iter.next().map_or_else(std::ptr::null, |v| v.into_uuid_c_string().expect("Typed value cannot be coerced into a Uuid"))
}
#[no_mangle]
pub unsafe extern "C" fn value_at_index(values: *mut Vec<Binding>, index: c_int) -> *const Binding {
pub unsafe extern "C" fn value_at_index(values: *mut Vec<Binding>, index: c_int) -> *const Binding {
let result = &*values;
result.get(index as usize).expect("No value at index") as *const Binding
}
//as_long
#[no_mangle]
pub unsafe extern "C" fn value_at_index_as_long(values: *mut Vec<Binding>, index: c_int) -> c_longlong {
pub unsafe extern "C" fn value_at_index_as_long(values: *mut Vec<Binding>, index: c_int) -> c_longlong {
let result = &*values;
let value = result.get(index as usize).expect("No value at index");
value.clone().into_long().expect("Typed value cannot be coerced into a Long")
unwrap_conversion(value.clone().into_long(), ValueType::Long)
}
// as ref
#[no_mangle]
pub unsafe extern "C" fn value_at_index_as_entid(values: *mut Vec<Binding>, index: c_int) -> Entid {
pub unsafe extern "C" fn value_at_index_as_entid(values: *mut Vec<Binding>, index: c_int) -> Entid {
let result = &*values;
let value = result.get(index as usize).expect("No value at index");
value.clone().into_entid().expect("Typed value cannot be coerced into an Entid")
unwrap_conversion(value.clone().into_entid(), ValueType::Ref)
}
// as kw
#[no_mangle]
pub unsafe extern "C" fn value_at_index_as_kw(values: *mut Vec<Binding>, index: c_int) -> *const c_char {
pub unsafe extern "C" fn value_at_index_as_kw(values: *mut Vec<Binding>, index: c_int) -> *const c_char {
let result = &*values;
let value = result.get(index as usize).expect("No value at index");
value.clone().into_kw_c_string().expect("Typed value cannot be coerced into a Namespaced Keyword")
unwrap_conversion(value.clone().into_kw_c_string(), ValueType::Keyword) as *const c_char
}
//as_boolean
#[no_mangle]
pub unsafe extern "C" fn value_at_index_as_boolean(values: *mut Vec<Binding>, index: c_int) -> i32 {
pub unsafe extern "C" fn value_at_index_as_boolean(values: *mut Vec<Binding>, index: c_int) -> i32 {
let result = &*values;
let value = result.get(index as usize).expect("No value at index");
if value.clone().into_boolean().expect("Typed value cannot be coerced into a Boolean") { 1 } else { 0 }
if unwrap_conversion(value.clone().into_boolean(), ValueType::Boolean) { 1 } else { 0 }
}
//as_double
#[no_mangle]
pub unsafe extern "C" fn value_at_index_as_double(values: *mut Vec<Binding>, index: c_int) -> f64 {
pub unsafe extern "C" fn value_at_index_as_double(values: *mut Vec<Binding>, index: c_int) -> f64 {
let result = &*values;
let value = result.get(index as usize).expect("No value at index");
value.clone().into_double().expect("Typed value cannot be coerced into a Double")
unwrap_conversion(value.clone().into_double(), ValueType::Double)
}
//as_timestamp
#[no_mangle]
pub unsafe extern "C" fn value_at_index_as_timestamp(values: *mut Vec<Binding>, index: c_int) -> c_longlong {
pub unsafe extern "C" fn value_at_index_as_timestamp(values: *mut Vec<Binding>, index: c_int) -> c_longlong {
let result = &*values;
let value = result.get(index as usize).expect("No value at index");
value.clone().into_timestamp().expect("Typed value cannot be coerced into a timestamp")
unwrap_conversion(value.clone().into_timestamp(), ValueType::Instant)
}
//as_string
#[no_mangle]
pub unsafe extern "C" fn value_at_index_as_string(values: *mut Vec<Binding>, index: c_int) -> *mut c_char {
pub unsafe extern "C" fn value_at_index_as_string(values: *mut Vec<Binding>, index: c_int) -> *const c_char {
let result = &*values;
let value = result.get(index as usize).expect("No value at index");
value.clone().into_c_string().expect("Typed value cannot be coerced into a String")
unwrap_conversion(value.clone().into_c_string(), ValueType::String) as *const c_char
}
//as_uuid
#[no_mangle]
pub unsafe extern "C" fn value_at_index_as_uuid(values: *mut Vec<Binding>, index: c_int) -> *mut [u8; 16] {
pub unsafe extern "C" fn value_at_index_as_uuid(values: *mut Vec<Binding>, index: c_int) -> *mut [u8; 16] {
let result = &*values;
let value = result.get(index as usize).expect("No value at index");
let uuid = value.clone().into_uuid().expect("Typed value cannot be coerced into a Uuid");
let uuid = unwrap_conversion(value.clone().into_uuid(), ValueType::Uuid);
Box::into_raw(Box::new(*uuid.as_bytes()))
}
#[no_mangle]
pub unsafe extern "C" fn store_value_for_attribute(store: *mut Store, entid: c_longlong, attribute: *const c_char) -> *mut ExternResult {
pub unsafe extern "C" fn store_value_for_attribute(store: *mut Store, entid: c_longlong, attribute: *const c_char) -> *mut ExternResult {
let store = &*store;
let kw = kw_from_string(c_char_to_string(attribute));
let value = match store.lookup_value_for_attribute(entid, &kw) {

View file

@ -16,6 +16,10 @@ android {
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
sourceSets {
androidTest.assets.srcDirs += '../../../../fixtures'
}
}
dependencies {

View file

@ -1,6 +1,6 @@
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in /Users/emilytoop/.android-sdk/tools/proguard/proguard-android.txt
# in ~/.android-sdk/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
#

View file

@ -1 +0,0 @@
[ {:db/ident :community/name :db/valueType :db.type/string :db/cardinality :db.cardinality/one :db/index true :db/fulltext true :db/doc "A community's name"} {:db/ident :community/url :db/valueType :db.type/string :db/cardinality :db.cardinality/one :db/doc "A community's url"} {:db/ident :community/neighborhood :db/valueType :db.type/ref :db/cardinality :db.cardinality/one :db/doc "A community's neighborhood"} {:db/ident :community/category :db/valueType :db.type/string :db/cardinality :db.cardinality/many :db/index true :db/fulltext true :db/doc "All community categories"} {:db/ident :community/orgtype :db/valueType :db.type/ref :db/cardinality :db.cardinality/one :db/doc "A community orgtype enum value"} {:db/ident :community/type :db/valueType :db.type/ref :db/cardinality :db.cardinality/many :db/doc "Community type enum values"} {:db/ident :community.orgtype/community} {:db/ident :community.orgtype/commercial} {:db/ident :community.orgtype/nonprofit} {:db/ident :community.orgtype/personal} {:db/ident :community.type/email-list} {:db/ident :community.type/twitter} {:db/ident :community.type/facebook-page} {:db/ident :community.type/blog} {:db/ident :community.type/website} {:db/ident :community.type/wiki} {:db/ident :community.type/myspace} {:db/ident :community.type/ning} ;; district/region enum values {:db/ident :region/n} {:db/ident :region/ne} {:db/ident :region/e} {:db/ident :region/se} {:db/ident :region/s} {:db/ident :region/sw} {:db/ident :region/w} {:db/ident :region/nw} {:db/ident :neighborhood/name :db/valueType :db.type/string :db/cardinality :db.cardinality/one :db/index true :db/unique :db.unique/identity :db/doc "A unique neighborhood name (upsertable)"} {:db/ident :neighborhood/district :db/valueType :db.type/ref :db/cardinality :db.cardinality/one :db/doc "A neighborhood's district"} ;; district {:db/ident :district/name :db/valueType :db.type/string :db/cardinality :db.cardinality/one :db/index true :db/unique :db.unique/identity :db/doc "A unique district name (upsertable)"} {:db/ident :district/region :db/valueType :db.type/ref :db/cardinality :db.cardinality/one :db/doc "A district region enum value"} ]

View file

@ -36,8 +36,6 @@ import static org.junit.Assert.*;
/**
* Instrumentation test, which will execute on an Android device.
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
@RunWith(AndroidJUnit4.class)
public class FFIIntegrationTest {

View file

@ -7,9 +7,8 @@
* under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
* CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License. */
package com.mozilla.mentat;
import android.util.Log;
package com.mozilla.mentat;
import com.sun.jna.Structure;
import com.sun.jna.ptr.IntByReference;
@ -42,8 +41,6 @@ public class AttributeList extends Structure implements Closeable {
@Override
public void close() {
Log.i("AttributeList", "close");
if (this.getPointer() != null) {
JNA.INSTANCE.destroy(this.getPointer());
}

View file

@ -10,11 +10,8 @@
package com.mozilla.mentat;
import android.util.Log;
import com.sun.jna.Pointer;
import java.io.IOException;
import java.util.Iterator;
/**
@ -50,7 +47,6 @@ public class ColResultIterator extends RustObject implements Iterator {
@Override
public void close() {
Log.i("TupleResult", "close");
if (this.rawPointer != null) {
JNA.INSTANCE.typed_value_list_iter_destroy(this.rawPointer);
}

View file

@ -7,9 +7,8 @@
* under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
* CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License. */
package com.mozilla.mentat;
import android.util.Log;
package com.mozilla.mentat;
import com.sun.jna.Pointer;
@ -44,8 +43,6 @@ public class CollResult extends TupleResult implements Iterable<TypedValue> {
@Override
public void close() {
Log.i("CollResult", "close");
if (this.rawPointer != null) {
JNA.INSTANCE.destroy(this.rawPointer);
}

View file

@ -57,7 +57,7 @@ public class Mentat extends RustObject {
public TxReport transact(String transaction) {
RustResult result = JNA.INSTANCE.store_transact(this.rawPointer, transaction);
if (result.isFailure()) {
Log.i("Mentat", result.err);
Log.e("Mentat", result.err);
return null;
}
@ -101,7 +101,7 @@ public class Mentat extends RustObject {
}
if (result.isFailure()) {
Log.i("Mentat", result.err);
Log.e("Mentat", result.err);
}
return null;
@ -122,10 +122,6 @@ public class Mentat extends RustObject {
for(int i = 0; i < attributes.length; i++) {
attrEntids[i] = JNA.INSTANCE.store_entid_for_attribute(this.rawPointer, attributes[i]);
}
Log.i("Mentat", "Registering observer {" + key + "} for attributes:");
for (int i = 0; i < attrEntids.length; i++) {
Log.i("Mentat", "entid: " + attrEntids[i]);
}
final Pointer entidsNativeArray = new Memory(8 * attrEntids.length);
entidsNativeArray.write(0, attrEntids, 0, attrEntids.length);
JNA.INSTANCE.store_register_observer(rawPointer, key, entidsNativeArray, attrEntids.length, callback);
@ -144,7 +140,6 @@ public class Mentat extends RustObject {
@Override
public void close() {
Log.i("Mentat", "close");
if (this.rawPointer != null) {
JNA.INSTANCE.store_destroy(this.rawPointer);
}

View file

@ -322,8 +322,6 @@ public class Query extends RustObject {
@Override
public void close() {
Log.i("Query", "close");
if (this.rawPointer == null) {
return;
}

View file

@ -10,8 +10,6 @@
package com.mozilla.mentat;
import android.util.Log;
import com.sun.jna.Pointer;
/**
@ -81,8 +79,6 @@ public class RelResult extends RustObject implements Iterable<TupleResult> {
@Override
public void close() {
Log.i("RelResult", "close");
if (this.rawPointer != null) {
JNA.INSTANCE.typed_value_result_set_destroy(this.rawPointer);
}

View file

@ -10,8 +10,6 @@
package com.mozilla.mentat;
import android.util.Log;
import com.sun.jna.Pointer;
import java.util.Iterator;
@ -49,7 +47,6 @@ public class RelResultIterator extends RustObject implements Iterator {
@Override
public void close() {
Log.i("TupleResult", "close");
if (this.rawPointer != null) {
JNA.INSTANCE.typed_value_result_set_iter_destroy(this.rawPointer);
}

View file

@ -10,7 +10,6 @@
package com.mozilla.mentat;
import android.util.Log;
import com.sun.jna.Pointer;
import java.nio.ByteBuffer;
@ -162,7 +161,6 @@ public class TupleResult extends RustObject {
@Override
public void close() {
Log.i("TupleResult", "close");
if (this.rawPointer != null) {
JNA.INSTANCE.typed_value_list_destroy(this.rawPointer);
}

View file

@ -10,8 +10,6 @@
package com.mozilla.mentat;
import android.util.Log;
import com.sun.jna.Pointer;
import com.sun.jna.Structure;
@ -46,7 +44,7 @@ public class TxChange extends Structure implements Closeable {
final long[] array = (long[]) changes.getLongArray(0, numberOfItems);
Long[] longArray = new Long[numberOfItems];
int idx = 0;
for(long change: array) {
for (long change: array) {
longArray[idx++] = change;
}
return Arrays.asList(longArray);
@ -59,7 +57,6 @@ public class TxChange extends Structure implements Closeable {
@Override
public void close() {
Log.i("TxChange", "close");
if (this.getPointer() != null) {
JNA.INSTANCE.destroy(this.getPointer());
}

View file

@ -10,8 +10,6 @@
package com.mozilla.mentat;
import android.util.Log;
import com.sun.jna.Structure;
import java.io.Closeable;
@ -50,7 +48,6 @@ public class TxChangeList extends Structure implements Closeable {
@Override
public void close() {
Log.i("TxChangeList", "close");
final TxChange[] nativeReports = (TxChange[]) reports.toArray(numberOfItems);
for (TxChange nativeReport : nativeReports) {
nativeReport.close();

View file

@ -10,8 +10,6 @@
package com.mozilla.mentat;
import android.util.Log;
import com.sun.jna.Pointer;
import java.util.Date;
@ -84,7 +82,6 @@ public class TxReport extends RustObject {
@Override
public void close() {
Log.i("TxReport", "close");
if (this.rawPointer != null) {
JNA.INSTANCE.tx_report_destroy(this.rawPointer);
}

View file

@ -10,10 +10,8 @@
package com.mozilla.mentat;
import android.util.Log;
import com.sun.jna.Pointer;
import java.io.BufferedReader;
import java.nio.ByteBuffer;
import java.util.Date;
import java.util.UUID;
@ -152,8 +150,6 @@ public class TypedValue extends RustObject {
@Override
public void close() {
Log.i("TypedValue", "close");
if (this.rawPointer != null) {
JNA.INSTANCE.typed_value_destroy(this.rawPointer);
}

View file

@ -37,6 +37,14 @@
BlueprintName = "MentatTests"
ReferencedContainer = "container:Mentat.xcodeproj">
</BuildableReference>
<SkippedTests>
<Test
Identifier = "MentatTests/testBindBoolean()">
</Test>
<Test
Identifier = "MentatTests/testBindDate()">
</Test>
</SkippedTests>
</TestableReference>
</Testables>
<MacroExpansion>

View file

@ -16,5 +16,3 @@ FOUNDATION_EXPORT double MentatVersionNumber;
//! Project version string for Mentat.
FOUNDATION_EXPORT const unsigned char MentatVersionString[];
// In this header, you should import all the public headers of your framework using statements like #import <Mentat/PublicHeader.h>