toxon
/
tox.rb
Archived
1
0
Fork 0

Fuck undocumented GStreamer

This commit is contained in:
Braiden Vasco 2018-04-28 14:36:49 +00:00
parent 4330c8f52e
commit 203164f422
No known key found for this signature in database
GPG Key ID: F1D3CA63437BDC6F
14 changed files with 1 additions and 806 deletions

1
.gitignore vendored
View File

@ -43,7 +43,6 @@
# Rake-compiled extension files:
/lib/tox/tox.so
/lib/gst-plugins-tox.so
# Vendored dependencies:
/vendor/*

View File

@ -8,7 +8,7 @@ rvm:
before_install:
- sudo apt-get update
- sudo apt-get install -y yasm libconfig-dev libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev
- sudo apt-get install -y yasm libconfig-dev
install: bundle install --jobs 3 --retry 3 --without examples

View File

@ -7,10 +7,6 @@ gemspec
gem 'coveralls', group: :test, require: false
group :development, :test do
gem 'gstreamer', '~> 3.2'
end
group :examples do
gem 'gtk3', '~> 3.2'
end

View File

@ -54,11 +54,6 @@ begin
ext.lib_dir = File.expand_path('lib/tox', __dir__).freeze
ext.config_options << "--with-opt-dir=#{VENDOR_PREFIX.shellescape}"
end
Rake::ExtensionTask.new 'gst-plugins-tox' do |ext|
ext.lib_dir = File.expand_path('lib', __dir__).freeze
ext.config_options << "--with-opt-dir=#{VENDOR_PREFIX.shellescape}"
end
rescue LoadError
nil
end

View File

@ -4,7 +4,6 @@
require 'bundler/setup'
require 'tox'
require 'gst/plugins/tox'
# You can add fixtures and/or initialization code here to make experimenting
# with your gem easier. You can also use a different console, if you like.

View File

@ -1,160 +0,0 @@
#!/usr/bin/env ruby
# frozen_string_literal: true
require 'bundler/setup'
require 'tox'
require 'gst/plugins/tox'
class StreamingThread
FILENAME = File.expand_path('test.mp3', __dir__).freeze
attr_reader :tox_audio_video, :friend_number
def initialize(tox_audio_video, friend_number)
@tox_audio_video = tox_audio_video
@friend_number = friend_number
raise unless elements.all?
Thread.start(&method(:call))
end
private
def call
bus # add loop event handler
pipeline.play
main_loop.run
ensure
pipeline.stop
end
def main_loop
@main_loop ||= GLib::MainLoop.new
end
def pipeline
@pipeline ||= Gst::Pipeline.new.tap do |pipeline|
elements.inject(pipeline, &:<<)
elements.inject(&:>>)
end
end
def bus
@bus ||= pipeline.bus.tap do |bus|
bus.add_watch do |_bus, message|
case message.type
when Gst::MessageType::EOS, Gst::MessageType::ERROR
main_loop.quit
end
true
end
end
end
def elements
@elements ||= [
filesrc,
mpegaudioparse,
mpg123audiodec,
audioresample,
toxaudiosink,
].freeze
end
def filesrc
@filesrc ||= Gst::ElementFactory.make('filesrc')&.tap do |elem|
elem.location = FILENAME
end
end
def mpegaudioparse
@mpegaudioparse ||= Gst::ElementFactory.make 'mpegaudioparse'
end
def mpg123audiodec
@mpg123audiodec ||= Gst::ElementFactory.make 'mpg123audiodec'
end
def audioresample
@audioresample ||= Gst::ElementFactory.make 'audioresample'
end
def toxaudiosink
@toxaudiosink ||= Gst::ElementFactory.make('toxaudiosink')&.tap do |elem|
elem.tox_av = tox_audio_video.pointer
elem.friend_number = friend_number
end
end
end
NAME = 'GStreamerAudioSendBot'
STATUS_MESSAGE = 'Call me'
AUDIO_BIT_RATE = 48
tox_client = Tox::Client.new
tox_client.name = NAME
tox_client.status = Tox::UserStatus::NONE
tox_client.status_message = STATUS_MESSAGE
puts "Address: #{tox_client.address}"
puts 'Connecting to the nodes from official list...'
tox_client.bootstrap_official
tox_client.on_friend_request do |public_key, text|
puts 'Friend request. Adding to contacts...'
puts "Public key: #{public_key}"
puts "Text: #{text.inspect}"
puts
tox_client.friend_add_norequest public_key
end
tox_client.audio_video.on_call do |friend_call_request|
puts 'Friend call.'
puts "Friend number: #{friend_call_request.friend_number}"
puts "Audio enabled: #{friend_call_request.audio_enabled?}"
puts "Video enabled: #{friend_call_request.video_enabled?}"
puts
unless friend_call_request.audio_enabled?
puts 'Audio disabled. Rejecting...'
puts
friend_call_request.reject
next
end
friend_call_request.answer AUDIO_BIT_RATE, nil
StreamingThread.new(
friend_call_request.audio_video,
friend_call_request.friend_number,
)
end
puts 'Running. Send me friend request, I\'ll accept it immediately. ' \
'Then call me.'
puts
Thread.start do
loop do
sleep tox_client.audio_video.iteration_interval
tox_client.audio_video.iterate
end
end
begin
loop do
sleep tox_client.iteration_interval
tox_client.iterate
end
rescue Interrupt
nil
end

View File

@ -1,179 +0,0 @@
#!/usr/bin/env ruby
# frozen_string_literal: true
require 'mkmf'
ENV['PKG_CONFIG_PATH'] =
File.expand_path(
File.join('..', '..', 'vendor', 'lib', 'pkgconfig'),
__dir__,
).freeze
def cflags(*args)
args.each do |str|
$CFLAGS += " #{str.shellescape} "
end
end
def pkg_config!(*args)
exit 1 unless pkg_config(*args)
end
def have_library!(*args)
exit 1 unless have_library(*args)
end
def have_header!(*args)
exit 1 unless have_header(*args)
end
def have_struct_member!(header, *args)
exit 1 unless have_struct_member(*args, header)
end
def have_func!(header, *args)
exit 1 unless have_func(*args, header)
end
def have_macro!(header, *args)
exit 1 unless have_macro(*args, header)
end
def have_type!(header, *args)
exit 1 unless have_type(*args, header)
end
def have_const!(header, *args)
exit 1 unless have_const(*args, header)
end
##########
# Common #
##########
cflags '-std=c11'
cflags '-Wall'
cflags '-Wextra'
cflags '-Wno-declaration-after-statement'
pkg_config! 'libtoxav'
pkg_config! 'gstreamer-1.0'
pkg_config! 'gstreamer-audio-1.0'
have_library! 'toxav'
have_library! 'gstreamer-1.0'
have_library! 'gstaudio-1.0'
have_header! 'tox/tox.h'
have_header! 'gst/gst.h'
have_header! 'gst/base/gstbasesink.h'
have_header! 'gst/audio/gstaudiosink.h'
#########
# ToxAV #
#########
have_type! 'tox/toxav.h', 'TOXAV_ERR_SEND_FRAME'
have_func! 'tox/toxav.h', 'toxav_audio_send_frame'
########
# GLib #
########
have_type! 'gst/gst.h', 'gpointer'
have_type! 'gst/gst.h', 'gboolean'
have_type! 'gst/gst.h', 'guint'
have_type! 'gst/gst.h', 'guint64'
have_type! 'gst/gst.h', 'GValue'
have_type! 'gst/gst.h', 'GObject'
have_type! 'gst/gst.h', 'GType'
have_type! 'gst/gst.h', 'GParamSpec'
have_type! 'gst/gst.h', 'GObjectClass'
have_macro! 'gst/gst.h', 'G_TYPE_CHECK_INSTANCE_CAST'
have_macro! 'gst/gst.h', 'G_TYPE_CHECK_CLASS_CAST'
have_macro! 'gst/gst.h', 'G_TYPE_CHECK_INSTANCE_TYPE'
have_macro! 'gst/gst.h', 'G_TYPE_CHECK_CLASS_TYPE'
have_macro! 'gst/gst.h', 'G_DEFINE_TYPE'
have_macro! 'gst/gst.h', 'G_OBJECT_WARN_INVALID_PROPERTY_ID'
have_macro! 'gst/gst.h', 'G_OBJECT_CLASS'
have_const! 'gst/gst.h', 'G_PARAM_READWRITE'
have_struct_member! 'gst/gst.h', 'GObjectClass', 'finalize'
have_struct_member! 'gst/gst.h', 'GObjectClass', 'get_property'
have_struct_member! 'gst/gst.h', 'GObjectClass', 'set_property'
have_func! 'gst/gst.h', 'g_type_class_peek_parent'
# have_func!' gst/gst.h', 'g_object_class_install_property'
have_func! 'gst/gst.h', 'g_param_spec_uint'
have_func! 'gst/gst.h', 'g_param_spec_uint64'
have_func! 'gst/gst.h', 'g_value_get_uint'
have_func! 'gst/gst.h', 'g_value_set_uint'
have_func! 'gst/gst.h', 'g_value_get_uint64'
have_func! 'gst/gst.h', 'g_value_set_uint64'
#############
# GStreamer #
#############
# have_type! 'gst/gst.h', 'GstPlugin'
have_type! 'gst/gst.h', 'GstElementClass'
have_type! 'gst/gst.h', 'GstStaticPadTemplate'
have_type! 'gst/gst.h', 'GstPad'
have_type! 'gst/gst.h', 'GstCaps'
have_type! 'gst/gst.h', 'GstQuery'
have_type! 'gst/base/gstbasesink.h', 'GstBaseSink'
have_type! 'gst/base/gstbasesink.h', 'GstBaseSinkClass'
have_struct_member! 'gst/base/gstbasesink.h', 'GstBaseSinkClass', 'get_caps'
have_struct_member! 'gst/base/gstbasesink.h', 'GstBaseSinkClass', 'query'
have_macro! 'gst/gst.h', 'GST_VERSION_MAJOR'
have_macro! 'gst/gst.h', 'GST_VERSION_MINOR'
have_macro! 'gst/gst.h', 'GST_PLUGIN_DEFINE'
have_macro! 'gst/gst.h', 'GST_DEBUG_CATEGORY_STATIC'
have_macro! 'gst/gst.h', 'GST_DEBUG_CATEGORY_INIT'
have_macro! 'gst/gst.h', 'GST_STATIC_CAPS'
have_macro! 'gst/gst.h', 'GST_DEBUG_FUNCPTR'
have_macro! 'gst/gst.h', 'GST_STATIC_PAD_TEMPLATE'
have_macro! 'gst/gst.h', 'GST_QUERY_TYPE'
have_macro! 'gst/base/gstbasesink.h', 'GST_BASE_SINK_CLASS'
have_macro! 'gst/base/gstbasesink.h', 'GST_BASE_SINK_PAD'
have_const! 'gst/gst.h', 'GST_PAD_SINK'
have_const! 'gst/gst.h', 'GST_PAD_ALWAYS'
have_const! 'gst/gst.h', 'GST_RANK_NONE'
have_const! 'gst/gst.h', 'GST_QUERY_ACCEPT_CAPS'
have_func! 'gst/gst.h', 'gst_element_class_set_details_simple'
have_func! 'gst/gst.h', 'gst_element_register'
have_func! 'gst/gst.h', 'gst_element_class_add_pad_template'
have_func! 'gst/gst.h', 'gst_static_pad_template_get'
have_func! 'gst/gst.h', 'gst_pad_get_pad_template_caps'
###################
# GStreamer Audio #
###################
have_macro! 'gst/audio/gstaudiosink.h', 'GST_TYPE_AUDIO_SINK'
have_type! 'gst/audio/gstaudiosink.h', 'GstAudioSink'
have_type! 'gst/audio/gstaudiosink.h', 'GstAudioSinkClass'
have_struct_member! 'gst/audio/gstaudiosink.h', 'GstAudioSinkClass', 'open'
have_struct_member! 'gst/audio/gstaudiosink.h', 'GstAudioSinkClass', 'prepare'
have_struct_member! 'gst/audio/gstaudiosink.h', 'GstAudioSinkClass', 'unprepare'
have_struct_member! 'gst/audio/gstaudiosink.h', 'GstAudioSinkClass', 'close'
have_struct_member! 'gst/audio/gstaudiosink.h', 'GstAudioSinkClass', 'write'
have_struct_member! 'gst/audio/gstaudiosink.h', 'GstAudioSinkClass', 'reset'
have_struct_member! 'gst/audio/gstaudiosink.h', 'GstAudioSinkClass', 'delay'
##########
# Common #
##########
create_makefile 'gst-plugins-tox' or exit 1

View File

@ -1,325 +0,0 @@
#include "gsttoxaudiosink.h"
GST_DEBUG_CATEGORY_STATIC(gst_tox_audio_sink_debug);
#define GST_CAT_DEFAULT gst_tox_audio_sink_debug
#define gst_tox_audio_sink_parent_class parent_class
G_DEFINE_TYPE(GstToxAudioSink, gst_tox_audio_sink, GST_TYPE_AUDIO_SINK);
/******************************************************************************
* Types and constants
******************************************************************************/
enum {
PROP_0,
PROP_TOX_AV,
PROP_FRIEND_NUMBER
};
/******************************************************************************
* Function declarations
******************************************************************************/
static void gst_tox_audio_sink_class_init(GstToxAudioSinkClass *klass);
static void gst_tox_audio_sink_init(GstToxAudioSink *self);
static void gst_tox_audio_sink_finalize(GObject *object);
static void gst_tox_audio_sink_get_property(
GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec
);
static void gst_tox_audio_sink_set_property(
GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec
);
static GstCaps *gst_tox_audio_sink_get_caps(
GstBaseSink *gst_base_sink,
GstCaps *filter
);
static gboolean gst_tox_audio_sink_query(
GstBaseSink *gst_base_sink,
GstQuery *gst_query
);
static gboolean gst_tox_audio_sink_query_accept_caps(
GstBaseSink *gst_base_sink,
GstQuery *gst_query
);
static gboolean gst_tox_audio_sink_open(GstAudioSink *gst_audio_sink);
static gboolean gst_tox_audio_sink_close(GstAudioSink *gst_audio_sink);
static gboolean gst_tox_audio_sink_prepare(
GstAudioSink *gst_audio_sink,
GstAudioRingBufferSpec *gst_audio_ring_buffer_spec
);
static gboolean gst_tox_audio_sink_unprepare(GstAudioSink *gst_audio_sink);
static void gst_tox_audio_sink_reset(GstAudioSink *gst_audio_sink);
static guint gst_tox_audio_sink_delay(GstAudioSink *gst_audio_sink);
static gint gst_tox_audio_sink_write(
GstAudioSink *gst_audio_sink,
gpointer data,
guint length
);
/******************************************************************************
* Variables
******************************************************************************/
static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE(
"sink",
GST_PAD_SINK,
GST_PAD_ALWAYS,
GST_STATIC_CAPS(
"audio/x-raw, "
"format = (string) S16LE, "
"rate = (int) 48000, "
"channels = (int) 1, "
"channel-mapping-family = (int) 0, "
"stream-count = (int) 1, "
"coupled-count = (int) 0"
)
);
/******************************************************************************
* Function implementations
******************************************************************************/
void gst_tox_audio_sink_class_init(GstToxAudioSinkClass *const klass)
{
GST_DEBUG_CATEGORY_INIT(
gst_tox_audio_sink_debug,
"toxaudiosink",
0,
"toxaudiosink element"
);
parent_class = g_type_class_peek_parent(klass);
// Class inheritance hierarchy
GObjectClass *const gobject_class = (GObjectClass*)klass;
GstElementClass *const gst_element_class = (GstElementClass*)klass;
GstBaseSinkClass *const gst_base_sink_class = (GstBaseSinkClass*)klass;
GstAudioSinkClass *const gst_audio_sink_class = (GstAudioSinkClass*)klass;
// GObjectClass
gobject_class->finalize = gst_tox_audio_sink_finalize;
gobject_class->get_property = gst_tox_audio_sink_get_property;
gobject_class->set_property = gst_tox_audio_sink_set_property;
g_object_class_install_property(
gobject_class,
PROP_TOX_AV,
g_param_spec_uint64(
"tox-av",
"ToxAV",
"ToxAV instance",
0,
UINT64_MAX,
0,
G_PARAM_READWRITE
)
);
g_object_class_install_property(
gobject_class,
PROP_FRIEND_NUMBER,
g_param_spec_uint(
"friend-number",
"Friend number",
"Friend number",
0,
UINT32_MAX,
0,
G_PARAM_READWRITE
)
);
// GstElementClass
gst_element_class_set_details_simple(
gst_element_class,
"ToxAudioSink",
"Sink/Audio",
"Sends audio to Tox",
"Braiden Vasco <braiden-vasco@users.noreply.github.com>"
);
gst_element_class_add_pad_template(
gst_element_class,
gst_static_pad_template_get(&sink_template)
);
// GstBaseSinkClass
gst_base_sink_class->get_caps = GST_DEBUG_FUNCPTR(gst_tox_audio_sink_get_caps);
gst_base_sink_class->query = GST_DEBUG_FUNCPTR(gst_tox_audio_sink_query);
// GstAudioSinkClass
gst_audio_sink_class->open = GST_DEBUG_FUNCPTR(gst_tox_audio_sink_open);
gst_audio_sink_class->close = GST_DEBUG_FUNCPTR(gst_tox_audio_sink_close);
gst_audio_sink_class->prepare = GST_DEBUG_FUNCPTR(gst_tox_audio_sink_prepare);
gst_audio_sink_class->unprepare = GST_DEBUG_FUNCPTR(gst_tox_audio_sink_unprepare);
gst_audio_sink_class->reset = GST_DEBUG_FUNCPTR(gst_tox_audio_sink_reset);
gst_audio_sink_class->delay = GST_DEBUG_FUNCPTR(gst_tox_audio_sink_delay);
gst_audio_sink_class->write = GST_DEBUG_FUNCPTR(gst_tox_audio_sink_write);
}
void gst_tox_audio_sink_init(GstToxAudioSink *const self)
{
self->tox_av = NULL;
self->friend_number = 0;
}
void gst_tox_audio_sink_finalize(GObject *const object)
{
G_OBJECT_CLASS(parent_class)->finalize(object);
}
void gst_tox_audio_sink_get_property(
GObject *const object,
const guint prop_id,
GValue *const value,
GParamSpec *const pspec
)
{
switch (prop_id) {
case PROP_TOX_AV:
g_value_set_uint64(value, (guint64)GST_TOX_AUDIO_SINK(object)->tox_av);
break;
case PROP_FRIEND_NUMBER:
g_value_set_uint(value, GST_TOX_AUDIO_SINK(object)->friend_number);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
}
}
void gst_tox_audio_sink_set_property(
GObject *const object,
const guint prop_id,
const GValue *const value,
GParamSpec *const pspec
)
{
switch (prop_id) {
case PROP_TOX_AV:
GST_TOX_AUDIO_SINK(object)->tox_av = (gpointer)g_value_get_uint64(value);
break;
case PROP_FRIEND_NUMBER:
GST_TOX_AUDIO_SINK(object)->friend_number = g_value_get_uint(value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
}
}
GstCaps *gst_tox_audio_sink_get_caps(
GstBaseSink *gst_base_sink,
GstCaps *filter
)
{
GstPad *pad = GST_BASE_SINK_PAD(gst_base_sink);
return gst_pad_get_pad_template_caps(pad);
}
gboolean gst_tox_audio_sink_query(
GstBaseSink *gst_base_sink,
GstQuery *gst_query
)
{
switch (GST_QUERY_TYPE(gst_query)) {
case GST_QUERY_ACCEPT_CAPS:
return gst_tox_audio_sink_query_accept_caps(gst_base_sink, gst_query);
default:
return GST_BASE_SINK_CLASS(parent_class)->
query(gst_base_sink, gst_query);
}
}
gboolean gst_tox_audio_sink_query_accept_caps(
GstBaseSink *gst_base_sink,
GstQuery *gst_query
)
{
return GST_BASE_SINK_CLASS(parent_class)->query(gst_base_sink, gst_query);
}
gboolean gst_tox_audio_sink_open(GstAudioSink *gst_audio_sink)
{
return TRUE;
}
gboolean gst_tox_audio_sink_close(GstAudioSink *gst_audio_sink)
{
return TRUE;
}
gboolean gst_tox_audio_sink_prepare(
GstAudioSink *gst_audio_sink,
GstAudioRingBufferSpec *gst_audio_ring_buffer_spec
)
{
return TRUE;
}
gboolean gst_tox_audio_sink_unprepare(GstAudioSink *gst_audio_sink)
{
return TRUE;
}
void gst_tox_audio_sink_reset(GstAudioSink *gst_audio_sink)
{
}
guint gst_tox_audio_sink_delay(GstAudioSink *gst_audio_sink)
{
return 0;
}
gint gst_tox_audio_sink_write(
GstAudioSink *const gst_audio_sink,
const gpointer data,
const guint length
)
{
const GstToxAudioSink *const gst_tox_audio_sink =
GST_TOX_AUDIO_SINK(gst_audio_sink);
if (!gst_tox_audio_sink->tox_av) {
return length;
}
const size_t sample_count = length / sizeof(int16_t);
TOXAV_ERR_SEND_FRAME toxav_audio_send_frame_error;
toxav_audio_send_frame(
gst_tox_audio_sink->tox_av,
gst_tox_audio_sink->friend_number,
data,
sample_count,
1, // channels
48000, // sampling_rate
&toxav_audio_send_frame_error
);
return length;
}

View File

@ -1,39 +0,0 @@
#ifndef __GSTTOXAUDIOSINK_H__
#define __GSTTOXAUDIOSINK_H__
#include <gst/gst.h>
#include <gst/audio/gstaudiosink.h>
#include <tox/toxav.h>
#define GST_TYPE_TOX_AUDIO_SINK \
(gst_tox_audio_sink_get_type())
#define GST_TOX_AUDIO_SINK(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_TOX_AUDIO_SINK,GstToxAudioSink))
#define GST_TOX_AUDIO_SINK_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_TOX_AUDIO_SINK,GetToxAudioSinkClass))
#define GST_IS_TOX_AUDIO_SINK(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_TOX_AUDIO_SINK))
#define GST_IS_TOX_AUDIO_SINK_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_TOX_AUDIO_SINK))
typedef struct _GstToxAudioSink GstToxAudioSink;
typedef struct _GstToxAudioSinkClass GstToxAudioSinkClass;
struct _GstToxAudioSink {
GstAudioSink parent;
ToxAV *tox_av;
uint32_t friend_number;
};
struct _GstToxAudioSinkClass {
GstAudioSinkClass parent_class;
};
GType gst_tox_audio_sink_get_type();
#endif // __GSTTOXAUDIOSINK_H__

View File

@ -1,31 +0,0 @@
#include "gsttoxaudiosink.h"
#ifndef PACKAGE
#define PACKAGE "tox"
#endif
static gboolean tox_init(GstPlugin *plugin);
GST_PLUGIN_DEFINE(
GST_VERSION_MAJOR,
GST_VERSION_MINOR,
tox,
"Tox audio/video sink/src",
tox_init,
"0.0.0",
"GPL",
"gst-plugins-tox",
"https://github.com/toxon/tox.rb"
)
gboolean tox_init(GstPlugin *const plugin)
{
gst_element_register(
plugin,
"toxaudiosink",
GST_RANK_NONE,
GST_TYPE_TOX_AUDIO_SINK
);
return TRUE;
}

View File

@ -1,5 +0,0 @@
# frozen_string_literal: true
require 'gst'
Gst::Registry.get.scan_path File.expand_path '../..', __dir__

View File

@ -1,53 +0,0 @@
# frozen_string_literal: true
RSpec.describe 'lib/gst-plugins-tox.so' do
subject { Gst::Registry.get.find_plugin 'tox' }
describe '#description' do
specify do
expect(subject.description).to eq 'Tox audio/video sink/src'
end
end
describe '#license' do
specify do
expect(subject.license).to eq 'GPL'
end
end
describe '#name' do
specify do
expect(subject.name).to eq 'tox'
end
end
describe '#origin' do
specify do
expect(subject.origin).to eq 'https://github.com/toxon/tox.rb'
end
end
describe '#package' do
specify do
expect(subject.package).to eq 'gst-plugins-tox'
end
end
describe '#source' do
specify do
expect(subject.source).to eq 'tox'
end
end
describe '#version' do
specify do
expect(subject.version).to eq '0.0.0'
end
end
describe '#load' do
specify do
expect { subject.load }.not_to raise_error
end
end
end

View File

@ -26,7 +26,6 @@ require 'openssl'
require 'faker'
require 'tox'
require 'gst/plugins/tox'
require 'support/random_port'

View File

@ -38,7 +38,6 @@ Gem::Specification.new do |spec|
spec.executables = spec.files.grep %r{^exe/}, &File.method(:basename)
spec.extensions << 'ext/tox/extconf.rb'
spec.extensions << 'ext/gst-plugins-tox/extconf.rb'
spec.add_development_dependency 'bundler', '~> 1.13'
spec.add_development_dependency 'celluloid', '~> 0.17'